typescript监听redis断开

如题所述



打开APP



AaronWang94
关注
redis监听断开后,重新监听的方案 原创
2020-03-12 13:36:56

AaronWang94 

码龄9年

关注
之前搭建的springcloud gateway框架,出现了问题,一旦redis重启后监听就会失效。我的思路是,捕捉到redis断开的异常,并尝试重新监听。写了一个心跳机制,一旦redis断开连接,便等待redis重连,一旦重连后就重新开启监听,调用KeyspaceEventMessageListener的init方法,下面是代码。

@Slf4j
@Component
public class RedisMessageListener extends KeyspaceEventMessageListener {
@Resource
private RedisTemplate<String,Object> redisTemplate;
@Resource
private ApplicationEventPublisher publisher;

@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.password}")
private String redisPassword;

public RedisMessageListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}

@Override
public void onMessage(Message message, byte[] pattern) {
//监听redis的改变,若改变的值为GATEWAY_ROUTES,则更新路由map
String changeKey = message.toString();
try {
if (changeKey.contains(RouteConfig.REDIS_ROUTE_SOURCE)) {
//先清空路由
log.info("清空路由");
RouteConfig.clearRoute();
//从redis中获取路由
Map<Object, Object> redisRouteMap=redisTemplate.opsForHash().entries(RouteConfig.REDIS_ROUTE_SOURCE);
//将路由存入map中
redisRouteMap.forEach((key, routeDefinition) -> {
RouteConfig.addRoute(key.toString(), JSON.parseObject(routeDefinition.toString(), RouteDefinition.class));
});
this.publisher.publishEvent(new RefreshRoutesEvent(this));
log.info("路由重置成功");
}
}
catch (Exception ex)
{
log.error("异常信息:",ex);
}
}
/*每隔10s定时心跳获取长连接*/
@Scheduled(cron = "0/10 * * * * *")
public void timer() throws InterruptedException {
boolean isOK=true;
//获取连接状态
isOK=checkRedisIsOk(redisHost,redisPort,redisPassword);
//若连接异常,则一直循环等待连接,直到连接成功后,重新开启监听
if(isOK==false)
{
//连接异常,则隔1s尝试连接
while (!checkRedisIsOk(redisHost,redisPort,redisPassword))
{
Thread.sleep(1000);
}
//若重新连接成功后,重新开启redis监听
super.init();
}
}

/**
* 检查redis是否存活
* @param url
* @param port
* @param password
* @return
*/
public boolean checkRedisIsOk(String url, int port, String password) {
boolean result=false;
try {
//连接本地Redis服务
Jedis jedis = new Jedis(url, port);
if (!password.isEmpty()) {
jedis.auth(password);
}
String ping = jedis.ping();
if (ping.equalsIgnoreCase("PONG")) {
log.info(new Date()+"redis连接正常!" + ping);
result=true;
}
} catch (Exception e) {
log.info(new Date()+"redis连接异常!");
result=false;
}
return result;
}

@Override
protected void doHandleMessage(Message message) {

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
采用定时器保持心跳,用jedis的ping方法判断连接是否异常。@schedule在上一个任务未结束前不会执行新的任务,不用担心任务会积压。
温馨提示:答案为网友推荐,仅供参考
相似回答