# 結構
2臺java服務器一主一備,redis服務器,Nginx負載均衡給java后臺。
# 場景
雙機熱備:當主服務器更新或者宕機,nginx會轉發給備用服務器,平時都是主服務器。
# 問題點
主備服務器的代碼是一樣的,都監聽了redis的過期事件。兩者都會處理一遍過期,重復了,這怎么解決呢?
# 嘗試解決
修改備用服務器的代碼讓其不監聽,主服務宕機的時候備服務器再監聽。但是實作困難,而且感覺不優雅。
uj5u.com熱心網友回復:
分布式系統中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教程網
uj5u.com熱心網友回復:
單機本地鎖,集群分布式鎖,要不想重復,加鎖即可uj5u.com熱心網友回復:
這樣確實可以保證不重復。但是有一點還不夠完美,備用主機同樣能拿到鎖進行處理。
目標是主服務器沒有出問題的時候,一直是由主服務器提供服務。沒出問題默認不請求備用服務器。
uj5u.com熱心網友回復:
分享福利一個java很好的底層學習站www.java52.com,tcc分布式事物調度器,分布式調度引擎框架源底層原始碼實作,github上知名分布式框架的底層實作和原始碼決議,JDK多執行緒,容器,NIO底層實作決議。大廠面試必備知識體系
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/253251.html
標籤:Java EE
上一篇:請問執行ssh-keygen -t rsa -C "[email protected]" 時,生成公鑰期間,是僅在本機上生成的,還是提交到相關網站,由網站生成的
下一篇:java模板引擎問題
