分类
分布式队列Queue还可以分为双端队列Deque、阻塞队列Blocking Queue、有界阻塞队列(Bounded Blocking Queue)、阻塞双端队列(Blocking Deque)、阻塞公平队列(Blocking Fair Queue)、阻塞公平双端队列(Blocking Fair Deque)。
不管是哪种队列,底层都是借助”基于发布—订阅式的主题“来实现的。
组成
生产者 消费者 消息
代(上)码(菜)
生产者:QueuePublisher.java
/**
* 队列的生产者
*/
@Component
public class QueuePublisher {
//定义日志
private static final Logger log= LoggerFactory.getLogger
(QueuePublisher.class);
//定义Redisson的操作客户端实例
@Autowired
private RedissonClient redissonClient;
/**
* 队列的生产者
* @param msg 待发送的消息
*/
public void sendBasicMsg(String msg){
try {
//定义基本队列的名称
final String queueName="redissonBasicQueue";
//获取队列的实例
RQueue<String> rQueue=redissonClient.getQueue(queueName);
//向队列中发送消息
rQueue.add(msg);
log.info("队列的生产者-发送基本的消息-消息发送成功:{} ", msg);
}catch (Exception e){
log.error("队列的生产者-发送基本的消息-发生异常:{} ", msg, e.fillInStackTrace());
}
}
}
消费者QueueConsumer.java
@Component
public class QueueConsumer implements ApplicationRunner, Ordered{
//定义日志
private static final Logger log= LoggerFactory.getLogger(QueueConsumer.class);
//定义Redisson的操作客户端实例
@Autowired
private RedissonClient redissonClient;
/**
* 在项目启动运行成功之后执行该run方法
* @param args
* @throws Exception
*/
@Override
public void run(ApplicationArguments args) throws Exception {
//定义基本队列的名称
final String queueName="redissonBasicQueue";
//获取队列的实例
RQueue<String> rQueue=redissonClient.getQueue(queueName);
while (true){
//从队列中弹出消息
String msg=rQueue.poll();
if (!StringUtils.isEmpty(msg)){
log.info("队列的消费者-监听消费消息:{} ", msg);
//TODO:在这里执行相应的业务逻辑
}
}
}
/**
* 表示QueueConsumer将会在项目启动之后启动
* @return
*/
@Override
public int getOrder() {
return -1;
}
}
在这里需要注意的是,Redisson分布式队列中的“消息监听”机制是不同于RabbitMQ的,对于消息中间件RabbitMQ而言,当队列中有消息到来时,RabbitMQ会将该消息“主动推送”给队列的监听者,从而实现消息可以成功被监听、消费的功能。而在Redisson的分布式队列RQueue这里,却并没有“主动推送”的机制,因而需要在“某个地方”,消费者需要不断地监听队列中是否有消息到来,从而决定是否需要执行相应的业务逻辑。
用于触发队列生产者生产、发送消息的QueueController类
@RestController
public class QueueController {
//定义日志
private static final Logger log = LoggerFactory.getLogger
(QueueController.class);
//定义发送请求的前缀URL
private static final String prefix = "queue";
//定义发送日志的队列生产者实例
@Autowired
private QueuePublisher queuePublisher;
/**
* 发送消息
*
* @param msg
* @return
*/
@RequestMapping(value = prefix + "/basic/msg/send", method = RequestMethod.GET)
public String sendBasicMsg(@RequestParam String msg) {
//定义响应结果实例
String response ="SUCCESS" ;
try {
//调用队列生产者发送消息的方法
queuePublisher.sendBasicMsg(msg);
} catch (Exception e) {
response = "程序异常";
}
//返回响应结果实例
return response;
}
}
输出
2023-04-12 14:27:08.249 INFO 158832 --- [nio-9999-exec-3] c.e.f.m.redisson.mq.QueuePublisher : 队列的生产者-发送基本的消息-消息发送成功:fadffasd
2023-04-12 14:27:08.276 INFO 158832 --- [ main] c.e.f.m.redisson.mq.QueueConsumer : 队列的消费者-监听消费消息:fadffasd
总结
没啥难度只是记录下使用情况