基于redis实现消息队列

基于redis实现消息队列

众所周知,redis是基于内存的数据库,速度非常快,不但可以用来存储缓存
还可以用作消息队列。

消息队列需要先进先出,redis中最符合的数据结构就是list了,所以我们采用
lpush命令往队列里生产消息,为了防止没有消息的时候循环空转,采用
brpop命令阻塞拉取消息

这里使用的是RedisTemplate

首先创建一个生产者类,收到请求就往队列里发送消息

@RestController
public class Producer {
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/sendMessage")
    public void sendMessage() {
        System.out.println("生产者生产");
        String mg = String.valueOf(LocalDateTime.now());
        redisTemplate.opsForList().leftPush("message", mg);
    }

}

之后创建消费者类,消费者需要在容器启动时就开始监听队列里有无消息
所以需要继承CommandLineRunner接口

@Component
public class Consumer implements CommandLineRunner {
	@Override
    public void run(String... args) {
		System.out.println("消费者正在监听");
	}
}

开启一个线程循环监听队列里的消息,再使用自定义线程池执行任务

private final static ThreadPoolExecutor executorService = new ThreadPoolExecutor(20, 30, 5,
            TimeUnit.MINUTES, new ArrayBlockingQueue<>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

就当是复习线程使用了,再用一个继承了Runnable接口的内部类打印出接收到的消息

static class ConsumerRunner implements Runnable  {

        private String key;
        private String mg;

        public ConsumerRunner(String key, String mg) {
            this.key = key;
            this.mg = mg;
        }

        @Override
        public void run() {
            System.out.println("消费者消费" + key + ":" + mg);
        }
    }

消费者完整代码如下

@Component
public class Consumer implements CommandLineRunner {
    @Autowired
    RedisTemplate redisTemplate;

    private final static ThreadPoolExecutor executorService = new ThreadPoolExecutor(20, 30, 5,
            TimeUnit.MINUTES, new ArrayBlockingQueue<>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

    @Override
    public void run(String... args) {
        System.out.println("消费者正在监听");
        Thread residingThread = new Thread(() -> {
            while (true) {
                String mg;
                do {
                	// 设置阻塞时间,防止循环空转
                    mg = (String) redisTemplate.opsForList().rightPop("message", 10000, TimeUnit.MILLISECONDS);
                    executorService.execute(new ConsumerRunner("message", mg));
                } while (mg != null);

            }
        });
        residingThread.start();
    }

    static class ConsumerRunner implements Runnable  {

        private String key;
        private String mg;

        public ConsumerRunner(String key, String mg) {
            this.key = key;
            this.mg = mg;
        }

        @Override
        public void run() {
            System.out.println("消费者消费" + key + ":" + mg);
        }
    }
}

启动之后执行监听方法
在这里插入图片描述
发送请求向队列添加消息,然后消费者打印出消息
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值