rocketmq消费负载均衡--push消费为例
在DefaultMQPushConsumerImpl.start()时,会将消费者的topic订阅关系设置到rebalanceImpl的SubscriptionInner的map中用于负载:
- private void copySubscription() throws MQClientException {
- try {
- //注:一个consumer对象可以订阅多个topic
- Map<String, String> sub = this.defaultMQPushConsumer.getSubscription();
- if (sub != null) {
- for (final Map.Entry<String, String> entry : sub.entrySet()) {
- final String topic = entry.getKey();
- final String subString = entry.getValue();
- SubscriptionData subscriptionData =
- FilterAPI.buildSubscriptionData(this.defaultMQPushConsumer.getConsumerGroup(),//
- topic, subString);
- this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
- }
- }
- if (null == this.messageListenerInner) {
- this.messageListenerInner = this.defaultMQPushConsumer.getMessageListener();
- }
- switch (this.defaultMQPushConsumer.getMessageModel()) {
- case BROADCASTING:
- break;
- case CLUSTERING:
- final String retryTopic = MixAll.getRetryTopic(this.defaultMQPushConsumer.getConsumerGroup());
- SubscriptionData subscriptionData =
- FilterAPI.buildSubscriptionData(this.defaultMQPushConsumer.getConsumerGroup(),//
- retryTopic, SubscriptionData.SUB_ALL);
- this.rebalanceImpl.getSubscriptionInner().put(retryTopic, subscriptionData);
- break;
- default:
- break;
- }
- }
- catch (Exception e) {
- throw new MQClientException("subscription exception", e);
- }
- }
- this.rebalanceImpl.setConsumerGroup(this.defaultMQPushConsumer.getConsumerGroup());
- this.rebalanceImpl.setMessageModel(this.defaultMQPushConsumer.getMessageModel());
- this.rebalanceImpl.setAllocateMessageQueueStrategy(this.defaultMQPushConsumer
- .getAllocateMessageQueueStrategy());
- this.rebalanceImpl.setmQClientFactory(this.mQClientFactory);
- @Override
- public void run() {
- log.info(this.getServiceName() + " service started");
- while (!this.isStoped()) {
- this.waitForRunning(WaitInterval);
- this.mqClientFactory.doRebalance();
- }
- log.info(this.getServiceName() + " service end");
- }
- public void doRebalance() {
- for (String group : this.consumerTable.keySet()) {
- MQConsumerInner impl = this.consumerTable.get(group);
- if (impl != null) {
- try {
- impl.doRebalance();
- } catch (Exception e) {
- log.error("doRebalance exception", e);
- }
- }
- }
- }
- @Override
- public void doRebalance() {
- if (this.rebalanceImpl != null) {
- this.rebalanceImpl.doRebalance();
- }
- }
- public void doRebalance() {
- // 前文copySubscription中初始化了SubscriptionInner
- Map<String, SubscriptionData> subTable = this.getSubscriptionInner();
- if (subTable != null) {
- for (final Map.Entry<String, SubscriptionData> entry : subTable.entrySet()) {
- final String topic = entry.getKey();
- try {
- this.rebalanceByTopic(topic);
- } catch (Exception e) {
- if (!topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)) {
- log.warn("rebalanceByTopic Exception", e);
- }
- }
- }
- }
- this.truncateMessageQueueNotMyTopic();
- }
VI. rebalanceByTopic -- 核心步骤之一
rebalanceByTopic方法中根据消费者的消费类型为BROADCASTING或CLUSTERING做不同的逻辑处理。CLUSTERING逻辑包括BROADCASTING逻辑,本部分只介绍集群消费负载均衡的逻辑。
集群消费负载均衡逻辑主要代码如下(省略了log等代码):
- //1.从topicSubscribeInfoTable列表中获取与该topic相关的所有消息队列
- Set<MessageQueue> mqSet = this.topicSubscribeInfoTable.get(topic);
- //2. 从broker端获取消费该消费组的所有客户端clientId
- List<String> cidAll = this.mQClientFactory.findConsumerIdList(topic, consumerGroup);
- f (null == mqSet) { ... }
- if (null == cidAll) { ... }
- if (mqSet != null && cidAll != null) {
- List<MessageQueue> mqAll = new ArrayList<MessageQueue>();
- mqAll.addAll(mqSet);
- Collections.sort(mqAll);
- Collections.sort(cidAll);
- // 3.创建DefaultMQPushConsumer对象时默认设置为AllocateMessageQueueAveragely
- AllocateMessageQueueStrategy strategy = this.allocateMessageQueueStrategy;
- List<MessageQueue> allocateResult = null;
- try {
- // 4.调用AllocateMessageQueueAveragely.allocate方法,获取当前client分配消费队列
- allocateResult = strategy.allocate(
- this.consumerGroup,
- this.mQClientFactory.getClientId(),
- mqAll,
- cidAll);
- } catch (Throwable e) {
- return;
- }
- // 5. 将分配得到的allocateResult 中的队列放入allocateResultSet 集合
- Set<MessageQueue> allocateResultSet = new HashSet<MessageQueue>();
- if (allocateResult != null) {
- allocateResultSet.addAll(allocateResult);
- }
- 、
- //6. 更新updateProcessQueue
- boolean changed = this.updateProcessQueueTableInRebalance(topic, allocateResultSet);
- if (changed) {
- this.messageQueueChanged(topic, mqSet, allocateResultSet);
- }
- }


rocketmq消费负载均衡--push消费为例的更多相关文章
- RocketMQ-2.RocketMQ的负载均衡
目录 RocketMQ的负载均衡 producer对MessageQueue的负载均衡 producer负载均衡 系统计算路由MessageQueue 自定义路由MessageQueue Consum ...
- Nginx 简单的负载均衡配置演示样例
近期在做开放查询应用的时候,因为数据两天特别多,两千多万条呢,用户訪问需求也比較大,所以就用nginx做了 负载均衡,以下是改动之后的相关内容. http://www.cnblogs.com/xiao ...
- RocketMQ(消息重发、重复消费、事务、消息模式)
分布式开放消息系统(RocketMQ)的原理与实践 RocketMQ基础:https://github.com/apache/rocketmq/tree/rocketmq-all-4.5.1/docs ...
- 深入剖析 RocketMQ 源码 - 负载均衡机制
RocketMQ作为一款流行的消息中间件在各大互联网应用广泛,本文主要分析RocketMq在消息生产和消费过程中的负载均衡机制,并创新提出消费端负载均衡策略的改写以实现固定IP消费的可能.
- 通过http、https域名访问静态网页、nginx配置负载均衡(nginx配置)
很多场景下需要可以通过浏览器访问静态网页,不想把服务器ip地址直接暴露出来,通过nginx可以解决这个问题. 实现http域名访问静态网页 1.域名解析配置(本文都是以阿里云为例,其他平台,操作步骤类 ...
- ③SpringCloud 实战:使用 Ribbon 客户端负载均衡
这是SpringCloud实战系列中第三篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...
- 玩转Spring Cloud之服务注册发现(eureka)及负载均衡消费(ribbon、feign)
如果说用Spring Boot+Spring MVC是开发单体应用(或单体服务)的利器,那么Spring Boot+Spring MVC+Spring Cloud将是开发分布式应用(快速构建微服务)的 ...
- spring cloud(服务消费者(利用ribbon实现服务消费及负载均衡)——初学二)
Ribbon是一个基于HTTP和TCP客户端的负载均衡器,利用ribbon实现服务消费,并实现客户端的负载均衡. 一.准备工作(利用上一节的内容) 启动服务注册中心 启动computer-servic ...
- Spring Cloud ---- 服务消费与负载均衡(feign)
feign是一个声明式的伪客户端,只需要创建一个接口并且注解,它具有可插拔的特性.feign集合了Ribbon,再与Eurake结合实现服务的注册发现与负载均衡.结合Hystrix,具有熔断功能. 1 ...
随机推荐
- odoo10 修改产品单价的小数点位数
odoo10 修改产品单价的小数点位数 由于产品价格原因,单价需要保留小数点后 5 位,所以需要修改单价的小数点位数. 开启开发模式 找到数据库编辑 找到小数点精度 修改产品的小数点位数
- [LeetCode系列]有序链表转换为平衡BST的递归解法
给定有序链表(元素由小到大), 试问如何将其转换为一个平衡BST? 平衡BST: 任意节点的左右子树的深度差值不大于1. 主要思想是用递归. Trick是使用快慢指针来获取中间节点. 获得中间节点后, ...
- 1.远程仓库的使用(github)
1.登录Github,新建一个仓库(远程仓库) (1)使用Github账号密码登录 (2)点击+旁边的小三角,选择new repository--输入repository name--点击create ...
- SQL的复习与总结
检索数据 关键字: SELECT DISTINCT LIMIT OFFSET FROM SELECT与FROM用于基础的检索,基本语法为: SELECT column_name,column_name ...
- Markdown初步使用
一.兼容 HTML Markdown 的理念是,能让文档更容易读.写和随意改.HTML 是一种发布的格式,Markdown 是一种书写的格式.就这样,Markdown 的格式语法只涵盖纯文本可以涵盖的 ...
- 笔记:LNK2001不代表链接器真的需要链接相关符号
环境:VS2008 我们都知道,链接器在生成可执行程序时,会忽略那些没有用到的符号.但是昨天遇到一个链接问题,看起来与这条基本策略并不相符.首先看一个静态链接库的结构: lib | |---- ...
- Zookeeper--集群管理
Zookeeper--集群管理 在多台服务器组成的集群中,需要监控每台服务器的状态,一旦某台服务器挂掉了或有新的机器加入集群,集群都要感知到,从而采取相应的措施.一个主动的集群可以自动感知节点的死亡和 ...
- python is 和 == 的区别
一.is 和 == 的区别 == 比较 比较的俩边的值 is 比较 比较的是内存地址 id() 二.小数据池 数字小数据池的范围 -5 ~ 256 字符串中如果有特殊字符他们的内存地址就不一样 字符串 ...
- String.Format数字格式化输出 {0:N2} {0:D2} {0:C2} (转)
String.Format数字格式化输出 {:N2} {:D2} {:C2} (转) //格式为sring输出 // Label1.Text = string.Format("asdfads ...
- shelve模块(超级好用~!)
''' python中的shelve模块,可以提供一些简单的数据操作 他和python中的dbm很相似. 区别如下: 都是以键值对的形式保存数据,不过在shelve模块中, key必须为字符串,而值可 ...