
9 changed files with 552 additions and 0 deletions
@ -0,0 +1,85 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<parent> |
||||
|
<artifactId>anrui</artifactId> |
||||
|
<groupId>com.yxt.anrui</groupId> |
||||
|
<version>0.0.1</version> |
||||
|
</parent> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>anrui-timertask</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
</properties> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.cloud</groupId> |
||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.projectlombok</groupId> |
||||
|
<artifactId>lombok</artifactId> |
||||
|
<optional>true</optional> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-cache</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba.cloud</groupId> |
||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.github.xiaoymin</groupId> |
||||
|
<artifactId>knife4j-spring-boot-starter</artifactId> |
||||
|
</dependency> |
||||
|
<!--引入redis--> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-data-redis</artifactId> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<groupId>io.lettuce</groupId> |
||||
|
<artifactId>lettuce-core</artifactId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>redis.clients</groupId> |
||||
|
<artifactId>jedis</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba</groupId> |
||||
|
<artifactId>fastjson</artifactId> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
<build> |
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||
|
<executions> |
||||
|
<execution> |
||||
|
<goals> |
||||
|
<goal>repackage</goal> |
||||
|
</goals> |
||||
|
</execution> |
||||
|
</executions> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
<resources> |
||||
|
<resource> |
||||
|
<directory>src/main/resources</directory> |
||||
|
<includes> |
||||
|
<include>**/*.*</include> |
||||
|
</includes> |
||||
|
<filtering>false</filtering> |
||||
|
</resource> |
||||
|
</resources> |
||||
|
</build> |
||||
|
</project> |
@ -0,0 +1,54 @@ |
|||||
|
/********************************************************* |
||||
|
********************************************************* |
||||
|
******************** ******************* |
||||
|
************* ************ |
||||
|
******* _oo0oo_ ******* |
||||
|
*** o8888888o *** |
||||
|
* 88" . "88 * |
||||
|
* (| -_- |) * |
||||
|
* 0\ = /0 * |
||||
|
* ___/`---'\___ * |
||||
|
* .' \\| |// '. *
|
||||
|
* / \\||| : |||// \ *
|
||||
|
* / _||||| -:- |||||- \ * |
||||
|
* | | \\\ - /// | | *
|
||||
|
* | \_| ''\---/'' |_/ | * |
||||
|
* \ .-\__ '-' ___/-. / * |
||||
|
* ___'. .' /--.--\ `. .'___ * |
||||
|
* ."" '< `.___\_<|>_/___.' >' "". * |
||||
|
* | | : `- \`.;`\ _ /`;.`/ - ` : | | * |
||||
|
* \ \ `_. \_ __\ /__ _/ .-` / / * |
||||
|
* =====`-.____`.___ \_____/___.-`___.-'===== * |
||||
|
* `=---=' * |
||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * |
||||
|
*********__佛祖保佑__永无BUG__验收通过__钞票多多__********* |
||||
|
*********************************************************/ |
||||
|
package com.yxt.anrui.timertask; |
||||
|
|
||||
|
|
||||
|
import org.springframework.boot.SpringApplication; |
||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; |
||||
|
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||
|
|
||||
|
/** |
||||
|
* Project: anrui-scm(进销存) <br/> |
||||
|
* File: AnruiScmApplication.java <br/> |
||||
|
* Class: com.yxt.anrui.scm.AnruiScmApp <br/> |
||||
|
* Description: . <br/> |
||||
|
* Copyright: Copyright (c) 2011 <br/> |
||||
|
* Company: https://gitee.com/liuzp315 <br/>
|
||||
|
* Makedate: 2021-11-17 13:48:15 <br/> |
||||
|
* |
||||
|
* @author liupopo |
||||
|
* @version 1.0 |
||||
|
* @since 1.0 |
||||
|
*/ |
||||
|
@EnableDiscoveryClient |
||||
|
@SpringBootApplication() |
||||
|
@EnableFeignClients(basePackages = {"com.yxt.anrui.timertask"}) |
||||
|
public class AnruiTimerTaskApplication { |
||||
|
public static void main(String[] args) { |
||||
|
SpringApplication.run(AnruiTimerTaskApplication.class, args); |
||||
|
} |
||||
|
} |
@ -0,0 +1,60 @@ |
|||||
|
package com.yxt.anrui.timertask.config; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.data.redis.connection.Message; |
||||
|
import org.springframework.data.redis.connection.RedisConnection; |
||||
|
import org.springframework.data.redis.core.BoundValueOperations; |
||||
|
import org.springframework.data.redis.core.RedisCallback; |
||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||
|
import org.springframework.data.redis.core.StringRedisTemplate; |
||||
|
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; |
||||
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer; |
||||
|
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; |
||||
|
import org.springframework.data.redis.serializer.RedisSerializer; |
||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class KeyExpiredListener extends KeyExpirationEventMessageListener { |
||||
|
@Autowired |
||||
|
private StringRedisTemplate stringRedisTemplate; |
||||
|
public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) { |
||||
|
super(listenerContainer); |
||||
|
} |
||||
|
@Override |
||||
|
@Transactional |
||||
|
public void onMessage(Message message, byte[] pattern) { |
||||
|
//从消息队列中接收消息
|
||||
|
// 获取过期的key,可以做自己的业务
|
||||
|
//反序列化Key,否则出现乱码
|
||||
|
String key = message.toString(); |
||||
|
// 利用redis setIfAbsent命令,如果为空set返回true,如果不为空返回false,
|
||||
|
// 类似setnx加锁操作
|
||||
|
Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent( key, String.valueOf(System.currentTimeMillis()), 10, TimeUnit.SECONDS); |
||||
|
if (aBoolean) { |
||||
|
// 避免多个服务监听情况下重复消费
|
||||
|
// 注意:只能获取失效的key值,不能获取key对应的value值
|
||||
|
System.out.println(key); |
||||
|
try { |
||||
|
if(key.startsWith("stock-")){ |
||||
|
// 过期监听后的具体逻辑
|
||||
|
log.info("redisKey:{}",key); |
||||
|
String s = stringRedisTemplate.opsForValue().get("stock-in1"); |
||||
|
log.info("redisValue:{}", s); |
||||
|
} |
||||
|
}catch (Exception e){ |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
super.onMessage(message, pattern); |
||||
|
} |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package com.yxt.anrui.timertask.config; |
||||
|
|
||||
|
import org.springframework.cache.annotation.CachingConfigurerSupport; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer; |
||||
|
|
||||
|
@Configuration |
||||
|
public class RedisConfiguration extends CachingConfigurerSupport { |
||||
|
@Bean |
||||
|
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory ) { |
||||
|
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); |
||||
|
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); |
||||
|
return redisMessageListenerContainer; |
||||
|
} |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
package com.yxt.anrui.timertask.feign; |
||||
|
|
||||
|
import io.swagger.annotations.Api; |
||||
|
import org.springframework.cloud.openfeign.FeignClient; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 财务模块调用金蝶保存业务单据的接口 |
||||
|
*/ |
||||
|
@Api(tags = "财务模块调用金蝶保存业务单据的接口") |
||||
|
@FeignClient( |
||||
|
contextId = "anrui-fin-FinKingDeeFeign", |
||||
|
name = "anrui-fin", |
||||
|
path = "/finKingDee" |
||||
|
) |
||||
|
public interface FinKingDeeFeign { |
||||
|
|
||||
|
} |
@ -0,0 +1,295 @@ |
|||||
|
package com.yxt.anrui.timertask.util; |
||||
|
|
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.data.redis.connection.RedisConnection; |
||||
|
import org.springframework.data.redis.connection.RedisStringCommands; |
||||
|
import org.springframework.data.redis.core.*; |
||||
|
import org.springframework.data.redis.core.types.Expiration; |
||||
|
import org.springframework.data.redis.serializer.RedisSerializer; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
import java.util.List; |
||||
|
import java.util.Set; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
@Service |
||||
|
public class RedisUtil { |
||||
|
|
||||
|
@Autowired |
||||
|
private RedisTemplate redisTemplate; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 字符串类型:根据key设置value值,如果key中的value存在,那么返回false |
||||
|
* |
||||
|
* @param key |
||||
|
* @param value |
||||
|
* @return |
||||
|
*/ |
||||
|
public Boolean setnx(final String key, final String value, final long expration, final TimeUnit timeUnit) { |
||||
|
return (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() { |
||||
|
@Override |
||||
|
public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException { |
||||
|
RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer(); |
||||
|
byte keys[] = redisSerializer.serialize(key); |
||||
|
byte values[] = redisSerializer.serialize(value); |
||||
|
return redisConnection.set(keys, values, Expiration.from(expration, timeUnit), RedisStringCommands.SetOption.SET_IF_ABSENT); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 写入缓存 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param value |
||||
|
* @return |
||||
|
*/ |
||||
|
public boolean set(final String key, final String value) { |
||||
|
|
||||
|
boolean result = (boolean) redisTemplate.execute(new RedisCallback<Boolean>() { |
||||
|
@Override |
||||
|
public Boolean doInRedis(RedisConnection connection) throws DataAccessException { |
||||
|
RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); |
||||
|
connection.set(serializer.serialize(key), serializer.serialize(value)); |
||||
|
return true; |
||||
|
} |
||||
|
}); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 写入缓存设置时效时间 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param value |
||||
|
* @return |
||||
|
*/ |
||||
|
public boolean set(final String key, Object value, Long expireTime) { |
||||
|
boolean result = false; |
||||
|
try { |
||||
|
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); |
||||
|
operations.set(key, value); |
||||
|
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); |
||||
|
result = true; |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
/** |
||||
|
* 刷新缓存到期时间 |
||||
|
* @param key |
||||
|
* @param expire |
||||
|
* @return |
||||
|
*/ |
||||
|
public boolean expire(String key, long expire) { |
||||
|
return redisTemplate.expire(key, expire, TimeUnit.SECONDS); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 读取缓存 |
||||
|
* |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public String get(final String key) { |
||||
|
String result = (String) redisTemplate.execute(new RedisCallback<String>() { |
||||
|
@Override |
||||
|
public String doInRedis(RedisConnection connection) throws DataAccessException { |
||||
|
RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); |
||||
|
byte[] value = connection.get(serializer.serialize(key)); |
||||
|
return serializer.deserialize(value); |
||||
|
} |
||||
|
}); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 正则获取key集合 |
||||
|
* |
||||
|
* @param pattern |
||||
|
* @return |
||||
|
*/ |
||||
|
public Set<String> keys(String pattern) { |
||||
|
Set<String> keys = redisTemplate.keys(pattern); |
||||
|
return keys; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 批量删除对应的value |
||||
|
* |
||||
|
* @param keys |
||||
|
*/ |
||||
|
public void remove(final String... keys) { |
||||
|
for (String key : keys) { |
||||
|
remove(key); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 批量删除key |
||||
|
* |
||||
|
* @param pattern |
||||
|
*/ |
||||
|
public void removePattern(final String pattern) { |
||||
|
Set<Serializable> keys = redisTemplate.keys(pattern); |
||||
|
if (keys.size() > 0) { |
||||
|
redisTemplate.delete(keys); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Long remove(final String key) { |
||||
|
return (Long) redisTemplate.execute(new RedisCallback<Long>() { |
||||
|
@Override |
||||
|
public Long doInRedis(RedisConnection redisConnection) throws DataAccessException { |
||||
|
RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); |
||||
|
byte keys[] = serializer.serialize(key); |
||||
|
return redisConnection.del(keys); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 判断缓存中是否有对应的value |
||||
|
* |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public boolean exists(final String key) { |
||||
|
return redisTemplate.hasKey(key); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 哈希 添加 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param hashKey |
||||
|
* @param value |
||||
|
*/ |
||||
|
public void hmSet(String key, Object hashKey, Object value) { |
||||
|
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); |
||||
|
hash.put(key, hashKey, value); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 哈希获取数据 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param hashKey |
||||
|
* @return |
||||
|
*/ |
||||
|
public String hmGet(String key, Object hashKey) { |
||||
|
HashOperations<String, String, String> hash = redisTemplate.opsForHash(); |
||||
|
return hash.get(key, hashKey); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取哈希 keys |
||||
|
* |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public Set<String> hmGetKeys(String key) { |
||||
|
HashOperations<String, String, String> hash = redisTemplate.opsForHash(); |
||||
|
return hash.keys(key); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除集合中的key |
||||
|
* |
||||
|
* @param key |
||||
|
* @param hashKey |
||||
|
*/ |
||||
|
public void hmDelete(String key, Object hashKey) { |
||||
|
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); |
||||
|
hash.delete(key, hashKey); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 列表添加 |
||||
|
* |
||||
|
* @param k |
||||
|
* @param v |
||||
|
*/ |
||||
|
public void lPush(String k, Object v) { |
||||
|
ListOperations<String, Object> list = redisTemplate.opsForList(); |
||||
|
list.rightPush(k, v); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 列表获取 |
||||
|
* |
||||
|
* @param k |
||||
|
* @param l |
||||
|
* @param l1 |
||||
|
* @return |
||||
|
*/ |
||||
|
public List<Object> lRange(String k, long l, long l1) { |
||||
|
ListOperations<String, Object> list = redisTemplate.opsForList(); |
||||
|
return list.range(k, l, l1); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 集合添加 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param value |
||||
|
*/ |
||||
|
public void add(String key, Object value) { |
||||
|
SetOperations<String, Object> set = redisTemplate.opsForSet(); |
||||
|
set.add(key, value); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 集合获取 |
||||
|
* |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public Set<Object> setMembers(String key) { |
||||
|
SetOperations<String, Object> set = redisTemplate.opsForSet(); |
||||
|
return set.members(key); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 有序集合添加 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param value |
||||
|
* @param scoure |
||||
|
*/ |
||||
|
public void zAdd(String key, Object value, double scoure) { |
||||
|
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet(); |
||||
|
zset.add(key, value, scoure); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 有序集合获取 |
||||
|
* |
||||
|
* @param key |
||||
|
* @param scoure |
||||
|
* @param scoure1 |
||||
|
* @return |
||||
|
*/ |
||||
|
public Set<Object> rangeByScore(String key, double scoure, double scoure1) { |
||||
|
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet(); |
||||
|
return zset.rangeByScore(key, scoure, scoure1); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 实现命令:TTL key 以秒为单位,返回给定key的剩余生存时间 |
||||
|
* @param key |
||||
|
* @return |
||||
|
*/ |
||||
|
public long ttl(String key) { |
||||
|
return redisTemplate.getExpire(key); |
||||
|
} |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
spring: |
||||
|
resources: |
||||
|
static-locations: file:D://anrui |
||||
|
redis: |
||||
|
database: 6 # Redis数据库索引(默认为0) |
||||
|
host: 127.0.0.1 |
||||
|
jedis: |
||||
|
pool: |
||||
|
max-active: -1 #连接池最大连接数(使用负值表示没有限制) |
||||
|
max-idle: 8 #连接池中的最大空闲连接 |
||||
|
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) |
||||
|
min-idle: 0 # 连接池中的最小空闲连接 |
||||
|
password: 123456 |
||||
|
port: 6379 |
||||
|
timeout: 0 # 连接超时时间(毫秒) |
@ -0,0 +1,7 @@ |
|||||
|
server: |
||||
|
port: 8119 |
||||
|
spring: |
||||
|
application: |
||||
|
name: timer-task |
||||
|
profiles: |
||||
|
active: devv |
Loading…
Reference in new issue