1、RocketMQ消息队列简单介绍

  这里简单介绍一下RocketMQ的消息队列的模型

  一个topic对应多个队列如下图:

  

  生产者和消费者分别向队列中发送和消费消息,生产者和消费者都可以是多个,通过组名进行群组约束。由于负载因素造成生产消息会生产到各个queue中。

  消费群组进行queue消费时首先因为负载因素,queue会分配给各自的消费实例中,如果消费组有变化会重新分配,导致queue分配乱序。

  另外一个消费者实例消费对应的queue时,消费者使用线程池进行处理消息。

  以上各种操作都会导致消息不一定先处理就会先完成,所以造成消息消费不是严格顺序处理的。

  所以在之前的版本中假如我们要求要严格按照顺序进行消息处理的话就必须进行单队列单线程进行消息消费处理

  4.0.0之后版本支持顺序消费处理,我们看一看他是如何处理的。。。

2、顺序消费原来介绍

  根据上面的简单介绍我们知道一个topic对应多个队列,我们生产消息的时候就可以针对队列的数量和消息的有效标识进行取模进行队列选择发送,如下示例代码

package org.apache.rocketmq.example.ordermessage;

import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException; public class Producer {
public static void main(String[] args) throws UnsupportedEncodingException {
try {
MQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
producer.start(); String[] tags = new String[] {"TagA", "TagB", "TagC", "TagD", "TagE"};
for (int i = 0; i < 100; i++) {
int orderId = i % 10;
Message msg =
new Message("TopicTestjjj", tags[i % tags.length], "KEY" + i,
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}
}, orderId); System.out.printf("%s%n", sendResult);
} producer.shutdown();
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
e.printStackTrace();
}
}
}

  比如我们使用订单号作为和queue的ID取模的关键字段,我们就可以保证这个订单号的消息都会发送给一个队列,这样我们就保证了生产者生产消息在业务上是有序的

  接下来我们看看消费端是怎样实现的。

  1、消费者与broker建立连接分配队列的时候会尝试给队列加锁,如果成功则获取queue消费权利,否则尝试下一个queue。

  2、如果消费模式为集群每20秒对分配给自己的队列自动加锁

  3、消息消费时对queue进行加锁,同一时刻只允许一个线程对一个queue进行消费

  4、根据消费时间进行队列和线程的切换默认60s(这个时间就是锁住队列的时间)

  5、消息重试次数超过最大次数之后将消息移入死信queue

  

  根据以上几点可以保证一个队列中的消息可以按顺序进行消费。

3、总结

  RocketMQ4.0.0对顺序消息做了升级,但是牺牲了部分消费性能。因为要给队列加锁,并且只能一个队列同一时间只能有一个线程处理消息。

  至于为什么是60秒(时间可设置)进行线程切换可能是更好的利用cpu或者不因为某个队列消息异常拖慢其他队列消息处理吧,还有待深入研究。

  

  本人理解如有误请广大网友指正,谢谢!

RocketMQ4.3.x对顺序消息的理解的更多相关文章

  1. RocketMQ入门到入土(二)事务消息&顺序消息

    接上一篇:RocketMQ入门到入土(一)新手也能看懂的原理和实战! 一.事务消息的由来 1.案例 引用官方的购物案例: 小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小 ...

  2. 聊一聊顺序消息(RocketMQ顺序消息的实现机制)

    当我们说顺序时,我们在说什么? 日常思维中,顺序大部分情况会和时间关联起来,即时间的先后表示事件的顺序关系. 比如事件A发生在下午3点一刻,而事件B发生在下午4点,那么我们认为事件A发生在事件B之前, ...

  3. RocketMQ源码 — 十、 RocketMQ顺序消息

    RocketMQ本身支持顺序消息,在使用上发送顺序消息和非顺序消息有所区别 发送顺序消息 SendResult sendResult = producer.send(msg, new MessageQ ...

  4. RocketMQ学习笔记(9)----RocketMQ的Producer 顺序消息

    1. 顺序消息原理图 2. 什么是顺序消息? 消费消息的顺序要求同发送消息的顺序一致,在RocketMQ中,主要指的是局部顺序,即一类消息为满足顺序性,必须Producer单线程顺序发送,并且发送给到 ...

  5. RocketMQ顺序消息

    rocketmq的顺序消息需要满足2点: 1.Producer端保证发送消息有序,且发送到同一个队列.2.consumer端保证消费同一个队列. 生产端: RocketMQ可以严格的保证消息有序.但这 ...

  6. 【mq读书笔记】顺序消息

    注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...

  7. junit4X系列源码--Junit4 Runner以及test case执行顺序和源代码理解

    原文出处:http://www.cnblogs.com/caoyuanzhanlang/p/3534846.html.感谢作者的无私分享. 前一篇文章我们总体介绍了Junit4的用法以及一些简单的测试 ...

  8. 20171126-handler消息机制理解

    1.handler消息机制的理解 http://www.jianshu.com/p/8343a39b8a2c?s_q_s_h_a_r_e_1MTAzNTIwODAxNTExNTg5NTkwMzE0Nz ...

  9. 一条sql语句搞定基于mysql的sql执行顺序的基本理解

    对数据库基本操作是每个程序员基本功,如何理解并快速记住sql执行的顺序呢,其实一条复杂的sql就能搞定: SELECT DISTINCT <select_list> FROM <le ...

随机推荐

  1. android Fragment中使用Toolbar

    在Activity中可以直接使用 setSupportActionBar(toolbar); 就可以重写 onCreateOptionsMenu 和 onOptionsItemSelected 方法: ...

  2. 解决Maven环境变量配置后,’mvn’不是内部或外部命令的问题

    1. 前往https://maven.apache.org/download.cgi下载的Maven程序,解压放在一个路径下 2.新建环境变量MAVEN_HOME,赋值:解压路径如:  D:\env\ ...

  3. 使用d3.v5实现饼状图

    效果图: 饼状图: 目录结构: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  4. eShopOnContainers 知多少[4]:Catalog microservice

    引言 Catalog microservice(目录微服务)维护着所有产品信息,包括库存.价格.所以该微服务的核心业务为: 产品信息的维护 库存的更新 价格的维护 架构模式 如上图所示,本微服务采用简 ...

  5. Java的设计模式

    一.什么是设计模式: 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...

  6. 死磕 java集合之ConcurrentHashMap源码分析(二)——扩容

    本章接着上一章,链接直达请点我. 初始化桶数组 第一次放元素时,初始化桶数组. private final Node<K,V>[] initTable() { Node<K,V> ...

  7. 【工利其器】必会工具之(三)systrace篇(1)官网翻译

    前言 Android 开发者官网中对systrace(Android System Trace)有专门的介绍,本篇文章作为systrace系列的开头,笔者先不做任何介绍,仅仅翻译一下官网的介绍.在后续 ...

  8. Entity Framework 查漏补缺 (二)

    数据加载 如下这样的一个lamda查询语句,不会立马去查询数据库,只有当需要用时去调用(如取某行,取某个字段.聚合),才会去操作数据库,EF中本身的查询方法返回的都是IQueryable接口. 链接: ...

  9. 关于px,分辨率,ppi的辨析

    概述  在本篇文章的开始,我先为大家解释一下这三个名词的概念.  px全称为pixel--像素.pc及移动设备的屏幕就是通过往像素矩阵中填充颜色,从而在宏观上体现出图像.像素越小,图像越清晰.  分辨 ...

  10. Spring学习(二):Spring支持的5种Bean Scope

    序言 Scope是定义Spring如何创建bean的实例的.Spring容器最初提供了两种bean的scope类型:singleton和prototype,但发布2.0以后,又引入了另外三种scope ...