java服务器集群如何处理redis过期消息监听?

ʟ 2021-01-27 11:05:34
# 结构
2台java服务器一主一备,redis服务器,Nginx负载均衡给java后台。

# 场景
双机热备:当主服务器更新或者宕机,nginx会转发给备用服务器,平时都是主服务器。

# 问题点
主备服务器的代码是一样的,都监听了redis的过期事件。两者都会处理一遍过期,重复了,这怎么解决呢?

# 尝试解决
修改备用服务器的代码让其不监听,主服务宕机的时候备服务器再监听。但是实现困难,而且感觉不优雅。
...全文
47 点赞 收藏 5
写回复
5 条回复
ʟ 04月20日
很久了,来结个贴。 最后是在Redis中做一个分布式锁。不再采用”一台机器平时不接受请求“的策略。两个服务器同时接受redis 过期消息。伪代码:


handleKeyExpireMessage(){
     tryLock(){ //此为获取redis分布式锁
         //处理过期消息
     }
 } 
回复 点赞
ʟ 01月27日
这样确实可以保证不重复。 但是有一点还不够完美,备用主机同样能拿到锁进行处理。 目标是主服务器没有出问题的时候,一直是由主服务器提供服务。没出问题默认不请求备用服务器。
回复 点赞
Forevermark993 01月27日
单机本地锁,集群分布式锁,要不想重复,加锁即可
回复 点赞
weixin_48567397 01月27日
分布式系统中Redis的Key过期监听事件如何防止重复处理 我在Java的分布式系统中,使用了Redis的Key过期时间 Redis中设置如下: notify-keyspace-events Ex 在Java中代码使用了JedisPubSub进行订阅: /* * 添加Redisd的key过期事件监听(因为会阻塞线程,所以放到最后执行) */ try { logger.info("正在添加Redisd的key过期事件监听..."); Jedis jedis = Redis.use("data").getJedis(); JedisPubSub jedisPubSub = new RedisKeyExpiredListener(); String channel = "__keyevent@0__:expired";// key过期事件 if (jedis != null) { new Thread(() -> { jedis.subscribe(jedisPubSub, channel);// 这里启动了订阅监听,线程将在这里被阻塞 }).start(); logger.info("添加Redisd的key过期事件监听完成!"); } else { logger.warn("添加Redisd的key过期事件监听失败,未获取到 jedis 对象!"); } } catch (Exception ex) { logger.error("添加Redisd的key过期事件监听异常!", ex); } 监听事件如下: /** * 监听到订阅频道接受到消息时的回调 */ @Override public void onMessage(String channel, String message) { logger.info("【onMessage】"); logger.info("channel = " + channel); logger.info("message = " + message); } 现在出现的问题是每当Redis中有Key过期时,都会调用各个程序中的onMessage事件,而且是同时调用,请问如果防止处理重复?处理完成后存缓存或者库来保证同步吗? 以上答案来自 IPAA教程网
回复 点赞
weixin_54951126 01月27日
分享福利一个java很好的底层学习站www.java52.com
,tcc分布式事物调度器,分布式调度引擎框架源底层源码实现,github上知名分布式框架的底层实现和源码解析,JDK多线程,容器,NIO底层实现解析。大厂面试必备知识体系
回复 点赞
发动态
发帖子
Java EE
创建于2007-09-28

3.7w+

社区成员

22.5w+

社区内容

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区公告
暂无公告