RocketMQ
http://rocketmq.apache.org/docs/quick-start/
解压后添加启动脚本
nohup sh bin/mqnamesrv >> logs/namesrv.log >& &
nohup sh bin/mqbroker -n localhost: >> logs/broker.log >& &
启动broker的时候可能会报错
修改bin/runbroker.sh里面的JVM配置
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g"
关闭
sh bin/mqshutdown broker
sh bin/mqshutdown namesrv
关于拒绝连接异常
Caused by: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.17.0.1:> failed
解决方案:https://my.oschina.net/simpleton/blog/3022576
监控界面:https://github.com/apache/rocketmq-externals/tree/master/rocketmq-console
参考文章:https://www.cnblogs.com/cac2020/p/9447938.html
按文中部署后运行程序还报错:
直接在/etc/hosts中添加
127.0.0.1 dev-server02
再次运行即可
集群部署
使用2台机器,用2m-noslave 模式
2台机器IP为:
172.20.102.194 mq2
172.20.102.150 mq1
在两台机器的/etc/hosts中添加上面的配置
在mq1机器上配置
conf/2m-noslave/broker-a.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
namesrvAddr=127.0.0.1:;mq2:
在mq2上配置
conf/2m-noslave/broker-b.properties
brokerClusterName=DefaultCluster
brokerName=broker-b
namesrvAddr=127.0.0.1:;mq1:
分别启动mq1和mq2的namesrv
nohup sh bin/mqnamesrv >> logs/app.log >& &
启动mq1的broker
nohup sh bin/mqbroker -c conf/2m-noslave/broker-a.properties >> logs/broker.log >& &
启动mq2的broker
nohup sh bin/mqbroker -c conf/2m-noslave/broker-b.properties >> logs/broker.log >& &
在监控界面中查看
spring boot 中使用
https://www.jianshu.com/p/8c4c2c2ab62e
spring-boot-starter-rocketmq
使用的时候如果遇到rocketMQTemplate bean
报错
需要配置producer
rocketmq:
name-server: 172.20.102.150:
producer:
group: ${spring.application.name}
将rocketmq.name-server 修改为 rocketmq.nameServer
这里要注意处理tag为空的情况
//根据Topic分组
Map<String, List<MessageExt>> topicGroups = msgs.stream().collect(Collectors.groupingBy(MessageExt::getTopic));
for (Map.Entry<String, List<MessageExt>> topicEntry : topicGroups.entrySet()) {
String topic = topicEntry.getKey();
//根据tags分组
List<MessageExt> messageExts=topicEntry.getValue();
for(MessageExt messageExt:messageExts){
String tag= messageExt.getTags();
if(StringUtils.isEmpty(tag)){
messageExt.setTags("*");
}
}
Map<String, List<MessageExt>> tagGroups = topicEntry.getValue().stream().collect(Collectors.groupingBy(MessageExt::getTags));
for (Map.Entry<String, List<MessageExt>> tagEntry : tagGroups.entrySet()) {
String tag = tagEntry.getKey();
//消费某个主题下,tag的消息
this.consumeMsgForTag(topic,tag,tagEntry.getValue());
}
}
非spring boot 中使用
添加beans
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd"> <cache:annotation-driven/> <bean id="messageListeners" class="com.rongdu.cashloan.cl.mq.MQConsumeMsgListenerProcessor"></bean> <bean id="rocketmqConsumer" class="org.apache.rocketmq.client.consumer.DefaultMQPushConsumer" init-method="start" destroy-method="shutdown">
<property name="consumerGroup" value="${rocketmq.consumer.groupName}"/>
<property name="namesrvAddr" value="${rocketmq.consumer.namesrvAddr}"/>
<property name="messageListener" ref="messageListeners"/>
<property name="subscription">
<map>
<entry key="${rocketmq.consumer.topics}" value="${rocketmq.consumer.tags}" />
</map>
</property>
<property name="consumeMessageBatchMaxSize" value="${rocketmq.consumer.consumeMessageBatchMaxSize}"></property>
</bean> <bean id="rocketMQProducer" class="org.apache.rocketmq.client.producer.DefaultMQProducer" init-method="start" destroy-method="shutdown">
<property name="producerGroup" value="${rocketmq.producer.groupName}"/>
<property name="namesrvAddr" value="${rocketmq.producer.namesrvAddr}"/>
<!-- 失败重试次数 -->
<property name="retryTimesWhenSendFailed" value="${rocketmq.producer.retryTimesWhenSendFailed}" />
</bean> </beans>
mq-beans
添加配置
#该应用是否启用生产者
rocketmq.producer.isOnOff=on
#发送同一类消息的设置为同一个group,保证唯一,默认不需要设置,rocketmq会使用ip@pid(pid代表jvm名字)作为唯一标示
rocketmq.producer.groupName=cashloan-producer
#mq的nameserver地址
rocketmq.producer.namesrvAddr=172.20.102.150:
rocketmq.producer.topics=cashloan_risk_control_req
#消息最大长度 默认1024*(4M)
rocketmq.producer.maxMessageSize=
#发送消息超时时间,默认3000
rocketmq.producer.sendMsgTimeout=
#发送消息失败重试次数,默认2
rocketmq.producer.retryTimesWhenSendFailed= ###consumer
##该应用是否启用消费者
rocketmq.consumer.isOnOff=on
rocketmq.consumer.groupName=cashloan-consumer
#mq的nameserver地址
rocketmq.consumer.namesrvAddr=172.20.102.150:
#该消费者订阅的主题和tags("*"号表示订阅该主题下所有的tags),格式:topic~tag1||tag2||tag3;topic2~*;
rocketmq.consumer.topics=cashloan_risk_control_result
rocketmq.consumer.tags=* rocketmq.consumer.consumeThreadMin=
rocketmq.consumer.consumeThreadMax=
#设置一次消费消息的条数,默认为1条
rocketmq.consumer.consumeMessageBatchMaxSize=
application-properties
生产者
Message msg = new Message("cashloan_risk_control_req" /* Topic */,
"TagA" /* Tag */,
(String.valueOf(borrowId)).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
);
SendResult sendResult = producer.send(msg);
消息监听
@Component
public class MQConsumeMsgListenerProcessor implements MessageListenerConcurrently {
private static final Logger logger = LoggerFactory.getLogger(MQConsumeMsgListenerProcessor.class); @Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
if(CollectionUtils.isEmpty(msgs)){
logger.info("接受到的消息为空,不处理,直接返回成功");
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
MessageExt messageExt = msgs.get();
logger.info("接受到的消息为:"+messageExt.toString());
if(messageExt.getTopic().equals("cashloan_risk_control")){
if(messageExt.getTags().equals("borrowId")){
//TODO 判断该消息是否重复消费(RocketMQ不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你自己在业务端去重)
//TODO 获取该消息重试次数
int reconsume = messageExt.getReconsumeTimes();
if(reconsume ==){//消息已经重试了3次,如果不需要再次消费,则返回成功
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
//TODO 处理对应的业务逻辑 }
}
// 如果没有return success ,consumer会重新消费该消息,直到return success
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
}
RocketMQ的更多相关文章
- RocketMQ原理解析-Remoting
Remoting2. 通信层底层传输协议 RocketMq服务器与客户端通过传递RemotingCommand来交互,通过NettyDecoder,对RemotingCommand进行协议的编码与解码 ...
- RocketMQ原理解析-Broker
broker 1. broker的启动 brker的启动 Broker向namesrv注册 1. 获取namesrv的地址列表(是乱序的) 2. 遍历向每个namesrv注册topic的配置信息top ...
- RocketMQ原理解析-Consumer
consumer 1.启动 有别于其他消息中间件由broker做负载均衡并主动向consumer投递消息,RocketMq是基于拉模式拉取消息,consumer做负载均衡并通过长轮询向broker拉消 ...
- RocketMQ原理解析-Producer
producer producer 1.启动流程 Producer如何感知要发送消息的broker即brokerAddrTable中的值是怎么获得的, 1. 发送消息的时候指定会指定topic,如果 ...
- 分布式开放消息系统(RocketMQ)的原理与实践
分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回避不了两个问题: 消息的顺序问题 消息的重复问题 RocketMQ作为阿里开源的一 ...
- rocketmq生产者和消费者
1.生产者: package com.ebways.mq.test.mq; import com.alibaba.rocketmq.client.exception.MQClientException ...
- rocketmq查看命令
首先进入 RocketMQ 工程,进入/RocketMQ/bin 在该目录下有个 mqadmin 脚本 . 查看帮助: 在 mqadmin 下可以查看有哪些命令 a: 查看具体命令的使 ...
- rocketmq生产者部署的机器注意事项
报错: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'warningP ...
- Kafka vs RocketMQ——多Topic对性能稳定性的影响-转自阿里中间件
引言 上期我们对比了RocketMQ和Kafka在多Topic场景下,收发消息的对比测试,RocketMQ表现稳定,而Kafka的TPS在64个Topic时可以保持13万,到了128个Topic就跌至 ...
- Kafka vs RocketMQ—— Topic数量对单机性能的影响-转自阿里中间件
引言 上一期我们对比了三类消息产品(Kafka.RabbitMQ.RocketMQ)单纯发送小消息的性能,受到了程序猿们的广泛关注,其中大家对这种单纯的发送场景感到并不过瘾,因为没有任何一个网站的业务 ...
随机推荐
- 可拖动div
客户要求,页面有图片并且可以随意拖动 具体实现: css: #div1{ width: 30px; height: 30px; /*一定要绝对定位*/ position: absolute; /*初始 ...
- 导入别人的项目eclipse 出现乱码 该如何处理
- pandas库的学习笔记
Environment pandas 0.21.0 python 3.6 jupyter notebook 开始 习惯上,我们导入如下: import pandas as pd import nump ...
- 从文件中读取数组数据————Java
自己总结一下Java文件的读取类似数组数据的方法,自己可以快速查看. 一.规整化数据: 对于数组数据是一一对应的情况 ArrayList<String> arrayList = new A ...
- SVN用法及常见问题分析
SVN中英文对比: 1,今天遇到的新问题,在父节点里面找不到子节点文件夹,在子节点里面可以上传但是却一直上传不上去. 具体原因:子文件夹里面有个.svn文件(打开隐藏的项目可见),是的子文件夹的svn ...
- Java项目下的classpath路径包括哪里
https://my.oschina.net/zjllovecode/blog/916927 classpath指的是.classpath下kind="src" 的路径
- Cookie的几点忠告
1.不要在COOKIE中保存明文的敏感信息 2.不要在COOKIE中保存永久的敏感信息,即每个COOKIE 都需要有时效性,过期则失效. 参考 XSS跨站攻击相关资料 http://www.cnblo ...
- SaaS应用十大关键NFR - 第2部分
SaaS应用十大关键NFR - 第2部分 在继续上一篇关于SaaS应用的十大关键NFR的博客之后,我们来看看接下来的5个对SaaS解决方案架构产生深刻影响的关键NFR. SaaS应用的关键NFR 多租 ...
- html-有趣的标签-会移动的文字
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- [纪录片] 鸟瞰中国 ——China from Above
上周末我看了一部纪录片<鸟瞰中国>,觉得特别有意思,想要分享给你. 制作背景 <鸟瞰中国>是由中国五洲传播中心与美国国家地理频道联合拍摄的纪录片,由KNNY PNG.KLAUS ...