分布式事物2 基于rocketmq

梦想的初衷 提交于 2020-03-05 20:05:44

分布式事物2 基于rocketmq 

从rocketmq的官网可以看到,它又以下几种消息类型:

1)发送同步消息

这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知

2)发送异步消息

异步消息通常用在对响应时间敏感的业务场景,即发送端不能容忍长时间地等待Broker的响应。

3)单向发送消息

这种方式主要用在不特别关心发送结果的场景,例如日志发送。

 消息消费:

    1)负载均衡模式

      消费者采用负载均衡方式消费消息,多个消费者共同消费队列消息,每个消费者处理的消息不同

    2)广播模式

      消费者采用广播的方式消费消息,每个消费者消费的消息都是相同的

4)顺序消息

消息有序指的是可以按照消息的发送顺序来消费(FIFO)。RocketMQ可以严格的保证消息有序,可以分为分区有序或者全局有序。

顺序消费的原理解析,在默认的情况下消息发送会采取Round Robin轮询方式把消息发送到不同的queue(分区队列);而消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序。但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。当发送和消费参与的queue只有一个,则是全局有序;如果多个queue参与,则为分区有序,即相对每个queue,消息都是有序的。

5)延时

比如电商里,提交了一个订单就可以发送一个延时消息,1h后去检查这个订单的状态,如果还是未付款就取消订单释放库存。

// org/apache/rocketmq/store/config/MessageStoreConfig.java
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";

现在RocketMq并不支持任意时间的延时,需要设置几个固定的延时等级,从1s到2h分别对应着等级1到18

6)批量消息

批量发送消息能显著提高传递小消息的性能。限制是这些批量消息应该有相同的topic,相同的waitStoreMsgOK,而且不能是延时消息。此外,这一批消息的总大小不应超过4MB。如果消息的总长度可能大于4MB时,这时候最好把消息进行分割

7)过滤消息

RocketMq可以基于tag对消息进行过滤,可以使用SQL表达式筛选消息

8)事物消息

上图说明了事务消息的大致方案,其中分为两个流程:正常事务消息的发送及提交、事务消息的补偿流程。

1)事务消息发送及提交

(1) 发送消息(half消息)。

(2) 服务端响应消息写入结果。

(3) 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)。

(4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见)

2)事务补偿

(1) 对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次“回查”

(2) Producer收到回查消息,检查回查消息对应的本地事务的状态

(3) 根据本地事务状态,重新Commit或者Rollback

其中,补偿阶段用于解决消息Commit或者Rollback发生超时或者失败的情况。

3)事务消息状态

事务消息共有三种状态,提交状态、回滚状态、中间状态:

  • TransactionStatus.CommitTransaction: 提交事务,它允许消费者消费此消息。
  • TransactionStatus.RollbackTransaction: 回滚事务,它代表该消息将被删除,不允许被消费。
  • TransactionStatus.Unknown: 中间状态,它代表需要检查消息队列来确定状态。

事物消息使用限制:

  1. 事务消息不支持延时消息和批量消息。
  2. 为了避免单个消息被检查太多次而导致半队列消息累积,我们默认将单个消息的检查次数限制为 15 次,但是用户可以通过 Broker 配置文件的 transactionCheckMax参数来修改此限制。如果已经检查某条消息超过 N 次的话( N = transactionCheckMax ) 则 Broker 将丢弃此消息,并在默认情况下同时打印错误日志。用户可以通过重写 AbstractTransactionCheckListener 类来修改这个行为。
  3. 事务消息将在 Broker 配置文件中的参数 transactionMsgTimeout 这样的特定时间长度之后被检查。当发送事务消息时,用户还可以通过设置用户属性 CHECK_IMMUNITY_TIME_IN_SECONDS 来改变这个限制,该参数优先于 transactionMsgTimeout 参数。
  4. 事务性消息可能不止一次被检查或消费,消费端要幂等处理
  5. 提交给用户的目标主题消息可能会失败,目前这依日志的记录而定。它的高可用性通过 RocketMQ 本身的高可用性机制来保证,如果希望确保事务消息不丢失、并且事务完整性得到保证,建议使用同步的双重写入机制。
  6. 事务消息的生产者 ID 不能与其他类型消息的生产者 ID 共享。与其他类型的消息不同,事务消息允许反向查询、MQ服务器能通过它们的生产者 ID 查询到消费者。

参考:https://www.bilibili.com/video/av71654125?p=33

扩展:

1)windows下用命令行操作环境变量

切换到超级管理员命令行窗口

使用cmd命令添加path环境变量 当前窗口有效              
在cmd下输入: path=%path%;D:/Anaconda  接着按"Enter"回车键,其中: D:/Anaconda 是Python的安装目录。

Windows10命令行设置环境变量

set  可以设置临时环境变量,只有在当前窗口下有效

语法:set name=value

set name 可以查看环境变量

setx 可以永久设置环境变量

setx /m 永久设置环境变量

setx /m name "value"

setx -m 永久追加环境变量

setx -m name "%name%;value"

设置完之后需要重新打开一个命令行窗口才能看到效果,从此就不用

再图形界面一步步点击了,b格瞬间提高,哈哈

2)windows下安装rocketmq

参考:https://www.jianshu.com/p/4a275e779afa

问题:broker关闭之后,启动不了了,需要把

c:/user/你的用户名/里面的store里面的所有文件全部删除,再启动,就成功了

windows下rocketmq常用命令

start mqnamesrv.cmd   启动NAMESERVER

启动BROKER

start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

启动编译好的控制台界面

java -jar rocketmq-console-ng-1.0.0.jar

关闭broker

mqshutdown.cmd  mqbroker

关闭NAMESERVER

mqshutdown.cmd  mqnamesrv

在自己的笔记本电脑上成功启动了,cmd窗口成功启动了namesrv,broker,但是在发送消息时候,出错了,

Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 14  DESC: service not available now, maybe disk full, CL:  0.98 CQ: -1.00 INDEX: -1.00, maybe your broker machine memory too small.
 倒腾一番,可能是电脑的内存和硬盘空间不满足运行要求,需修改rocketmq jvm参数和自定义文件路径

在bin目录中的runserver.cmd runbroler.cmd中修改jvm的参数

rocketmq自定义文件路径 参考

http://www.mamicode.com/info-detail-1469937.html

4)maven依赖问题排查方法:

  • 检查是否MAVEN依赖冲突
  • 检查是否MAVEN依赖重复
    • mvn -X compile dependency:tree -Dverbose >a.log
    • 查看文件中是否有 conflict 标记的JAR包依赖
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!