SpringBoot使用Redis实现类似消息队列的简单方法

Java使用Redis实现类似消息队列的方法

前提条件:
SpringBoot项目集成了Redis,并且可以直接使用。本文使用SpringDataRedis的RedisTemplate实现。
实现效果:生产者能够向redis队列中不断发送数据。消费者可以不断的从该队列获取到该数据,进行处理。
核心代码:

redisTemplate.opsForList().leftPush(QUEUE, jsonObject);
JSONObject jsonObject = (JSONObject) redisTemplate.opsForList().rightPop(QUEUE, 10, TimeUnit.SECONDS);

AI解析:
使用Spring Data Redis的RedisTemplate类来操作Redis数据库中的列表数据结构。opsForList()方法提供了一系列操作列表的方法,例如leftPush和rightPop。

leftPush(String key, Object value)方法将给定的对象(这里是jsonObject)推入到列表的左侧(头部)。
rightPop(String key)方法从列表的右侧弹出元素并返回。这里还有一个可选的三个参数版本的方法rightPop(String key, long timeout, TimeUnit unit),这个方法会尝试从列表的右侧弹出一个元素,如果列表为空,则会等待直到有元素可用或者超时。
在你的代码中,你首先将jsonObject推入到名为READING_VISIT的列表的头部,然后尝试从该列表的尾部弹出元素,并且最多等待10秒来获取这个元素。如果在这10秒内没有元素可用,那么这个方法将返回null。
全部代码:

生产者:

try{
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data",data);
            //发送队列
            redisTemplate.opsForList().leftPush(QUEUE, jsonObject);
}catch (Exception e){
            e.getMessage();
}

消费者:
1、新建一个配置类,实例化一个bean,在这个bean中单独启动线程:

@Configuration
public class QueueConfig {

    @Autowired
    private ConsumerServiceImpl consumerService;
    
    @Bean
    public String initConsume(){
      	//启动线程
        consumerService.start();
        return "success";
    }
}

2、消费者从redis中不间断取值

@Slf4j
@Service
public class ConsumerServiceImpl extends Thread implements *** {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private bizService service;


    private static final String QUEUE= "queue";


    @Override
    public void run() {
        while (true) {
            try {
//                log.info("开始执行任务");
                //阻塞式取值
                JSONObject jsonObject = (JSONObject) redisTemplate.opsForList().rightPop(QUEUE, 10, TimeUnit.SECONDS);
                //消息队列取到消息
                if (jsonObject != null) {
                    System.out.println(jsonObject);
                    service.add(jsonObject);
                    log.info("Listening to a message, starting the task!");
                }
            } catch (Exception e) {
                // 异常捕获,防止循环因异常停止
                e.printStackTrace();
            }
        }
    }

}

第二种方法:可以使用定时任务,持续从redis中取值处理,以下为AI实现:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class RedisListProcessor {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Scheduled(fixedRate = 1000) // 每隔1秒执行一次
    public void processRedisList() {
        // 从Redis中取出列表的值进行处理
        String value = redisTemplate.opsForList().rightPop("yourListKey");
        if (value != null) {
            // 进行处理逻辑
            System.out.println("Processing value from Redis list: " + value);
        }
    }
}

定时任务的好处:

简单易用:Spring提供的定时任务功能可以方便地实现定时执行任务,不需要手动管理线程的创建和销毁。
可控性:定时任务可以通过注解的方式灵活控制执行频率、执行时间等,更加容易管理。
避免资源浪费:定时任务可以在处理完数据后自动释放资源,避免线程一直占用资源。
定时任务的缺点:

实时性不高:定时任务是按照预定的时间执行的,可能无法满足对数据实时性要求较高的场景。
灵活性较差:定时任务的执行时间是预先设定的,可能无法灵活应对数据变化。
使用新建线程的好处:

实时性高:通过新建线程不间断地读取Redis,可以更加实时地处理Redis中的数据。
灵活性高:可以根据需要动态调整线程的数量、执行逻辑等。
使用新建线程的缺点:

管理复杂:需要手动管理线程的创建、销毁、异常处理等,容易出现资源泄漏和线程安全问题。
可维护性差:使用新建线程会增加系统的复杂性,降低代码的可读性和可维护性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值