1、RocketMQ消息队列简单介绍

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

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

  

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

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

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

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

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

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

2、顺序消费原来介绍

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

  1. package org.apache.rocketmq.example.ordermessage;
  2.  
  3. import java.io.UnsupportedEncodingException;
  4. import java.util.List;
  5. import org.apache.rocketmq.client.exception.MQBrokerException;
  6. import org.apache.rocketmq.client.exception.MQClientException;
  7. import org.apache.rocketmq.client.producer.DefaultMQProducer;
  8. import org.apache.rocketmq.client.producer.MQProducer;
  9. import org.apache.rocketmq.client.producer.MessageQueueSelector;
  10. import org.apache.rocketmq.client.producer.SendResult;
  11. import org.apache.rocketmq.common.message.Message;
  12. import org.apache.rocketmq.common.message.MessageQueue;
  13. import org.apache.rocketmq.remoting.common.RemotingHelper;
  14. import org.apache.rocketmq.remoting.exception.RemotingException;
  15.  
  16. public class Producer {
  17. public static void main(String[] args) throws UnsupportedEncodingException {
  18. try {
  19. MQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
  20. producer.start();
  21.  
  22. String[] tags = new String[] {"TagA", "TagB", "TagC", "TagD", "TagE"};
  23. for (int i = 0; i < 100; i++) {
  24. int orderId = i % 10;
  25. Message msg =
  26. new Message("TopicTestjjj", tags[i % tags.length], "KEY" + i,
  27. ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
  28. SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
  29. @Override
  30. public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
  31. Integer id = (Integer) arg;
  32. int index = id % mqs.size();
  33. return mqs.get(index);
  34. }
  35. }, orderId);
  36.  
  37. System.out.printf("%s%n", sendResult);
  38. }
  39.  
  40. producer.shutdown();
  41. } catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }

  比如我们使用订单号作为和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. 解决小米手机USB安装apk时AS报错:INSTALL_FAILED_USER_RESTRICTED

    今天,直接用AS在小米手机上运行安装的时候总是报错:INSTALL_FAILED_USER_RESTRICTED,于是乎,通过以下方式解决: 在开发者选项将USB安装打开,然后,哈,解决了.记录一下.

  2. 【转载】c++中堆、栈内存分配

    一.内存划分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数参数值,局部变量值等.其操作方式类似于数据结构中栈.2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时 ...

  3. java中强大的免费的集成开发环境(IDE)eclipse的使用技巧及注意事项

    1调整字体,window->prefernce->Appereance->colors and fonts->Basic->Text font双击即可进行编辑 2.设置行 ...

  4. 数据库【mongodb】之pymongo

    一个Python操作mongodb的模块 # coding=utf-8 from pymongo import MongoClient #实例化client,建立连接 client = MongoCl ...

  5. 小白学习Python之路---开发环境的搭建

    本节内容 1.Python的介绍 2.发展史 3.安装Python 4.搭建开发环境 5.Hello World程序 一.Python的介绍 Python的创始人为荷兰人吉多·范罗苏姆(Guido v ...

  6. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之五 || Swagger的使用 3.3 JWT权限验证【必看】

    前言 关于JWT一共三篇 姊妹篇,内容分别从简单到复杂,一定要多看多想: 一.Swagger的使用 3.3 JWT权限验证[修改] 二.解决JWT权限验证过期问题 三.JWT完美实现权限与接口的动态分 ...

  7. Docker & ASP.NET Core (5):Docker Compose

    第一篇:把代码连接到容器 第二篇:定制Docker镜像 第三篇:发布镜像 第四篇:容器间的连接 Docker Compose简介 Compose是一个用来定义和运行多容器Docker应用的工具.使用C ...

  8. Jenkins集群搭建

    Jenkins的目的是加快CI/CD的步伐,集群的搭建也不是必须的,当一台服务器的构建速度受到限制下,可以考虑使用主从并发构建,来加快构建速度.作为一款超级管家的角色,Jenkins的资料非常多,Je ...

  9. 安装Phalcon报错:gcc: Internal error: Killed (program cc1)

    起因 安装Phalcon可以参考github上面的README.md 下面是我在阿里云ECS服务器上面执行命令的过程: # 安装依赖 sudo yum install php-devel pcre-d ...

  10. Spring Boot(四):Thymeleaf 使用详解

    在上篇文章Spring Boot (二):Web 综合开发中简单介绍了一下 Thymeleaf,这篇文章将更加全面详细的介绍 Thymeleaf 的使用.Thymeleaf 是新一代的模板引擎,在 S ...