目录
引言
函数式接口
- Lambda 表达式的本质是匿名函数
- Java 函数无法脱离类而存在,所以 Java 通过引入函数式接口以支持 Lambda 表达式
特性:
- 函数式接口为一个 interface 类
- 该类中有且仅有一个方法
- 该类需加上 @FunctionalInterface 注解
注意:
- 上述三点其实就是 Lambda 的本质,即底层实现
消费者订阅消息 实现思路
1、让 broker server 把有哪些消费者管理好
- 消费者调用 basicConsume 方法就是订阅某个指定队列的消息
注意:
- 消费者是以队列为纬度订阅的
- 一个队列可以有多个消费者
- 约定 消费者之间按照 轮询 的方式进行消费
代码编写:
- 定义一个 ConsumerEnv 类,用来描述一个消费者
- 该类中也会包含一些消费者消费过程中用到的数据
import lombok.Data; /* * 表示一个消费者(完整的执行环境) * */ @Data public class ConsumerEnv { private String consumerTag; private String queueName; private boolean autoAck; // 通过这个回调来处理收到的消息 private Consumer consumer; public ConsumerEnv(String consumerTag, String queueName, boolean autoAck, Consumer consumer) { this.consumerTag = consumerTag; this.queueName = queueName; this.autoAck = autoAck; this.consumer = consumer; } }
- 给每个队列对象(MSGQueue 对象)添加属性 List,用于存储该队列的 消费者对象
// 当前队列都有哪些消费者订阅了 private List<ConsumerEnv> consumerEnvList = new ArrayList<>(); // 记录当前取到了第几个消费者,方便实现轮询策略 private AtomicInteger consumerSeq = new AtomicInteger(0); // 添加一个新的订阅者 public void addConsumerEnv(ConsumerEnv consumerEnv) { consumerEnvList.add(consumerEnv); } // 订阅者的删除暂时不考虑 // 挑选一个订阅者,用来处理当前的消息 (按照轮询的方式) public ConsumerEnv chooseConsumer() { if(consumerEnvList.size() == 0) { // 该队列没有人订阅 return null; } // 计算一下当前要取的元素的下标 int index = consumerSeq.get() % consumerEnvList.size(); consumerSeq.getAndDecrement(); return consumerEnvList.get(index); }
2、消费者 订阅队列消息,并使用该消息完成明确好的业务逻辑
- 所谓 消费者 消费消息,其实就