分布式事物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: 中间状态,它代表需要检查消息队列来确定状态。
事物消息使用限制:
- 事务消息不支持延时消息和批量消息。
- 为了避免单个消息被检查太多次而导致半队列消息累积,我们默认将单个消息的检查次数限制为 15 次,但是用户可以通过 Broker 配置文件的
transactionCheckMax
参数来修改此限制。如果已经检查某条消息超过 N 次的话( N =transactionCheckMax
) 则 Broker 将丢弃此消息,并在默认情况下同时打印错误日志。用户可以通过重写AbstractTransactionCheckListener
类来修改这个行为。 - 事务消息将在 Broker 配置文件中的参数 transactionMsgTimeout 这样的特定时间长度之后被检查。当发送事务消息时,用户还可以通过设置用户属性 CHECK_IMMUNITY_TIME_IN_SECONDS 来改变这个限制,该参数优先于
transactionMsgTimeout
参数。 - 事务性消息可能不止一次被检查或消费,消费端要幂等处理
- 提交给用户的目标主题消息可能会失败,目前这依日志的记录而定。它的高可用性通过 RocketMQ 本身的高可用性机制来保证,如果希望确保事务消息不丢失、并且事务完整性得到保证,建议使用同步的双重写入机制。
- 事务消息的生产者 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包依赖
来源:CSDN
作者:就是现在
链接:https://blog.csdn.net/u014353343/article/details/104631732