博客主页:https://blog.csdn.net/GBS20200720
博主昵称:怎么又有bug单
主要领域:Java、Linux、K8S
期待大家的关注💖点赞👍收藏⭐留言💬
文章目录
原因
redis宕机后,设置的redis连接超时时间还有效吗?
最近在实际的开发中遇到了这个问题。大家要模拟redis故障的场景,观察业务系统会受多大的影响,会不会阻塞主流程。
而在模拟redis宕机之后,发现之前设置的超时时间并未生效。现象是超时时间设置了1000ms,但是实际调用redis服务返回快速失败只用了20ms,这说明超时时间并未生效。
于是我自己写了一个demo,来验证下redis宕机后,设置的redis连接超时时间是否还有效。
代码
ConsumeConfiguration:
public class ConsumeConfiguration {
@Autowired
private RedisUtil redisUtil;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 模仿消费者 每秒执行一次
@Scheduled(cron = "*/1 * * * * * ")
public void consume(){
System.out.println("------------等待消费--------------");
// 取出QUEUE_NAME集合中的score在0-当前时间戳这个范围的所有值
Set<Object> set = redisUtil.opsForZSetrangeByScore(QueueNameEnum.REDIS_DELAY_QUEUE01.getMsg(), 0, System.currentTimeMillis());
Iterator<Object> iterator = set.iterator();
while (iterator.hasNext()) {
Integer value = (Integer) iterator.next();
// 遍历取出每一个score
Double score = redisUtil.opsForZSetScore(QueueNameEnum.REDIS_DELAY_QUEUE01.getMsg(), value);
// 达到了时间就进行消费
if (System.currentTimeMillis() > score) {
System.out.println("消费了:" + value + "消费时间为:" + simpleDateFormat.format(System.currentTimeMillis()));
redisUtil.opsForZSetRemove(QueueNameEnum.REDIS_DELAY_QUEUE01.getMsg(), value);
}
}
}
}
MyRunnable01:
@Component
public class MyRunnable01 implements Runnable {
@Autowired
private RedisUtil redisUtil;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void run() {
// 模仿消费者 每秒执行一次
// 取出QUEUE_NAME集合中的score在0-当前时间戳这个范围的所有值
Set<Object> set = redisUtil.opsForZSetrangeByScore(QueueNameEnum.REDIS_DELAY_QUEUE01.getMsg(), 0, System.currentTimeMillis());
Iterator<Object> iterator = set.iterator();
while (iterator.hasNext()) {
Integer value = (Integer) iterator.next();
// 遍历取出每一个score
Double score = redisUtil.opsForZSetScore(QueueNameEnum.REDIS_DELAY_QUEUE01.getMsg(), value);
// 达到了时间就进行消费
if (System.currentTimeMillis() > score) {
System.out.println("消费了:" + value + "消费时间为:" + simpleDateFormat.format(System.currentTimeMillis()));
redisUtil.opsForZSetRemove(QueueNameEnum.REDIS_DELAY_QUEUE01.getMsg(), value);
}
}
}
}
ProduceRequest:
@Data
public class ProduceRequest {
// 发送消息的code
// 1为1号消息 2为2号消息 3为3号消息
private Integer messageCode;
// 多少秒之后消费
private Integer afterSeconds;
// 消息内容
private String message;
// 发送条数
private Integer number;
}
QueueNameEnum:
public enum QueueNameEnum {
REDIS_DELAY_QUEUE01(1, "redis_delay_queue01"),
REDIS_DELAY_QUEUE02(2, "redis_delay_queue02"),
REDIS_DELAY_QUEUE03(3, "redis_delay_queue03");
private int code;
private String msg;
QueueNameEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public static String getMsgByCode(int code) {
switch (code) {
case 1: {
return REDIS_DELAY_QUEUE01.getMsg();
}
case 2: {
return REDIS_DELAY_QUEUE02.getMsg();
}
case 3: {
return REDIS_DELAY_QUEUE03.getMsg();
}
}
return REDIS_DELAY_QUEUE03.getMsg();
}
}
RedisController:
@RestController
@RequestMapping("/redis")