From 430af700439faf7d6e93e49c871e90287f5f5c85 Mon Sep 17 00:00:00 2001 From: yxt_djz Date: Mon, 10 Oct 2022 10:44:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=9A=84?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- anrui-timertask/pom.xml | 85 +++++ .../timertask/AnruiTimerTaskApplication.java | 54 ++++ .../timertask/config/KeyExpiredListener.java | 60 ++++ .../timertask/config/RedisConfiguration.java | 17 + .../timertask/feign/FinKingDeeFeign.java | 18 ++ .../yxt/anrui/timertask/util/RedisUtil.java | 295 ++++++++++++++++++ .../src/main/resources/application-devv.yml | 15 + .../src/main/resources/application.yml | 7 + pom.xml | 1 + 9 files changed, 552 insertions(+) create mode 100644 anrui-timertask/pom.xml create mode 100644 anrui-timertask/src/main/java/com/yxt/anrui/timertask/AnruiTimerTaskApplication.java create mode 100644 anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/KeyExpiredListener.java create mode 100644 anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/RedisConfiguration.java create mode 100644 anrui-timertask/src/main/java/com/yxt/anrui/timertask/feign/FinKingDeeFeign.java create mode 100644 anrui-timertask/src/main/java/com/yxt/anrui/timertask/util/RedisUtil.java create mode 100644 anrui-timertask/src/main/resources/application-devv.yml create mode 100644 anrui-timertask/src/main/resources/application.yml diff --git a/anrui-timertask/pom.xml b/anrui-timertask/pom.xml new file mode 100644 index 0000000000..bc420a86fb --- /dev/null +++ b/anrui-timertask/pom.xml @@ -0,0 +1,85 @@ + + + + anrui + com.yxt.anrui + 0.0.1 + + 4.0.0 + + anrui-timertask + + + 8 + 8 + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-cache + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.github.xiaoymin + knife4j-spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-data-redis + + + io.lettuce + lettuce-core + + + + + redis.clients + jedis + + + com.alibaba + fastjson + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + src/main/resources + + **/*.* + + false + + + + \ No newline at end of file diff --git a/anrui-timertask/src/main/java/com/yxt/anrui/timertask/AnruiTimerTaskApplication.java b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/AnruiTimerTaskApplication.java new file mode 100644 index 0000000000..f2d1c49191 --- /dev/null +++ b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/AnruiTimerTaskApplication.java @@ -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(进销存)
+ * File: AnruiScmApplication.java
+ * Class: com.yxt.anrui.scm.AnruiScmApp
+ * Description: .
+ * Copyright: Copyright (c) 2011
+ * Company: https://gitee.com/liuzp315
+ * Makedate: 2021-11-17 13:48:15
+ * + * @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); + } +} diff --git a/anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/KeyExpiredListener.java b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/KeyExpiredListener.java new file mode 100644 index 0000000000..ced8ff3727 --- /dev/null +++ b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/KeyExpiredListener.java @@ -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); + } +} diff --git a/anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/RedisConfiguration.java b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/RedisConfiguration.java new file mode 100644 index 0000000000..c3db1b741f --- /dev/null +++ b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/config/RedisConfiguration.java @@ -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; + } +} diff --git a/anrui-timertask/src/main/java/com/yxt/anrui/timertask/feign/FinKingDeeFeign.java b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/feign/FinKingDeeFeign.java new file mode 100644 index 0000000000..9807c123dd --- /dev/null +++ b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/feign/FinKingDeeFeign.java @@ -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 { + +} diff --git a/anrui-timertask/src/main/java/com/yxt/anrui/timertask/util/RedisUtil.java b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/util/RedisUtil.java new file mode 100644 index 0000000000..70b73e4f2f --- /dev/null +++ b/anrui-timertask/src/main/java/com/yxt/anrui/timertask/util/RedisUtil.java @@ -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() { + @Override + public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException { + RedisSerializer 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() { + @Override + public Boolean doInRedis(RedisConnection connection) throws DataAccessException { + RedisSerializer 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 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() { + @Override + public String doInRedis(RedisConnection connection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + byte[] value = connection.get(serializer.serialize(key)); + return serializer.deserialize(value); + } + }); + return result; + } + + /** + * 正则获取key集合 + * + * @param pattern + * @return + */ + public Set keys(String pattern) { + Set 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 keys = redisTemplate.keys(pattern); + if (keys.size() > 0) { + redisTemplate.delete(keys); + } + + } + + + public Long remove(final String key) { + return (Long) redisTemplate.execute(new RedisCallback() { + @Override + public Long doInRedis(RedisConnection redisConnection) throws DataAccessException { + RedisSerializer 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 hash = redisTemplate.opsForHash(); + hash.put(key, hashKey, value); + } + + /** + * 哈希获取数据 + * + * @param key + * @param hashKey + * @return + */ + public String hmGet(String key, Object hashKey) { + HashOperations hash = redisTemplate.opsForHash(); + return hash.get(key, hashKey); + } + + /** + * 获取哈希 keys + * + * @param key + * @return + */ + public Set hmGetKeys(String key) { + HashOperations hash = redisTemplate.opsForHash(); + return hash.keys(key); + } + + /** + * 删除集合中的key + * + * @param key + * @param hashKey + */ + public void hmDelete(String key, Object hashKey) { + HashOperations hash = redisTemplate.opsForHash(); + hash.delete(key, hashKey); + } + + /** + * 列表添加 + * + * @param k + * @param v + */ + public void lPush(String k, Object v) { + ListOperations list = redisTemplate.opsForList(); + list.rightPush(k, v); + } + + /** + * 列表获取 + * + * @param k + * @param l + * @param l1 + * @return + */ + public List lRange(String k, long l, long l1) { + ListOperations list = redisTemplate.opsForList(); + return list.range(k, l, l1); + } + + /** + * 集合添加 + * + * @param key + * @param value + */ + public void add(String key, Object value) { + SetOperations set = redisTemplate.opsForSet(); + set.add(key, value); + } + + /** + * 集合获取 + * + * @param key + * @return + */ + public Set setMembers(String key) { + SetOperations set = redisTemplate.opsForSet(); + return set.members(key); + } + + /** + * 有序集合添加 + * + * @param key + * @param value + * @param scoure + */ + public void zAdd(String key, Object value, double scoure) { + ZSetOperations zset = redisTemplate.opsForZSet(); + zset.add(key, value, scoure); + } + + /** + * 有序集合获取 + * + * @param key + * @param scoure + * @param scoure1 + * @return + */ + public Set rangeByScore(String key, double scoure, double scoure1) { + ZSetOperations zset = redisTemplate.opsForZSet(); + return zset.rangeByScore(key, scoure, scoure1); + } + + /** + * 实现命令:TTL key 以秒为单位,返回给定key的剩余生存时间 + * @param key + * @return + */ + public long ttl(String key) { + return redisTemplate.getExpire(key); + } +} diff --git a/anrui-timertask/src/main/resources/application-devv.yml b/anrui-timertask/src/main/resources/application-devv.yml new file mode 100644 index 0000000000..346062f32e --- /dev/null +++ b/anrui-timertask/src/main/resources/application-devv.yml @@ -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 # 连接超时时间(毫秒) \ No newline at end of file diff --git a/anrui-timertask/src/main/resources/application.yml b/anrui-timertask/src/main/resources/application.yml new file mode 100644 index 0000000000..bb5986b4e0 --- /dev/null +++ b/anrui-timertask/src/main/resources/application.yml @@ -0,0 +1,7 @@ +server: + port: 8119 +spring: + application: + name: timer-task + profiles: + active: devv diff --git a/pom.xml b/pom.xml index f5b6f1e67f..dfcfd3d773 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ anrui-scm anrui-fin anrui-terminal + anrui-timertask pom