rocketMq
rocketmq集群 rabbitmq集群
RabbitMQ 基于erlang语言开发,因此响应速度快些
RocketMQ 阿里 基于Java开发 高级特性: 普通消息、顺序消息、延迟消息、事务消息 可靠性强 吞吐量 高
activemq Apache java实现 实现JMS消息集成框架 吞吐量低
https://wenku.baidu.com/view/37933508e1bd960590c69ec3d5bbfd0a7956d5f5.html
使用命令java -version查看使用的jdk
由于使用的是openjdk,故需要在mq的bin\tools.sh中添加/usr/lib/jvm/jre-1.8.0-openjdk/lib/ext
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib:${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext:/usr/lib/jvm/jre-1.8.0-openjdk/lib/ext"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
unzip 解压zip包
问题解决-重启虚拟机 启动日志 service iptables stop tail -f /home/xmh/logs/rocketmqlogs/namesrv.log tail -f ~/logs/rocketmqlogs/broker.log cd /home/xmh/soft/mq/rocketmq/rocketmq/rocketmq-all-4.8.0-bin-release 启动 nohup ./mqnamesrv & nohup ./mqbroker -n 127.0.0.1:9876 autoCreateTopicEnable=true & 手动创建topic ./mqadmin updateTopic -c DefaultCluster -n 127.0.0.1:9876 -t TopicTest ./mqadmin topicList 关闭 ./mqshutdown namesrv ./mqshutdown broker
集群消费 实际使用中,一台服务用一个消费者,其他业务需要接收消息,单独建消费者 1,默认是集群消费 2,不设置group直接设置MessageModel即可生效 BROADCASTING 广播 CLUSTERING 集群 3.集群模式,一条消息只会被同Group中的一个Consumer消费 4.集群模式,多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据 广播消费 消息将对一 个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。 实现顺序消费 https://blog.csdn.net/yanwendonge/article/details/109188473 将orderId取模,同一个订单的消息会放到同一个队列里。 生产者 SendResult sendResult = producer.send(msg,messageQueueSelector,""); private static MessageQueueSelector messageQueueSelector = new MessageQueueSelector() { @Override public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) { try { int id = arg.hashCode(); int index = Math.abs(id) % mqs.size(); return mqs.get(index); } catch (Exception e) { e.printStackTrace(); return mqs.get(0); } } }; 消费者 //单线程顺序消费 consumer.setConsumeThreadMin(1); consumer.setConsumeThreadMax(1); consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { int i =0; for (MessageExt msg:msgs){ System.out.println((i++)+" "+new String(msg.getBody())+"*****"+msg); } // 标记该消息已经被成功消费 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); //多线程顺序消费 consumer.setConsumeThreadMin(4); consumer.setConsumeThreadMax(8); consumer.registerMessageListener( new MessageListenerOrderly() { @Override public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) { int i =0; for (MessageExt msg:msgs){ System.out.println((i++)+" "+new String(msg.getBody())+"*****"+msg); } // 标记该消息已经被成功消费 return ConsumeOrderlyStatus.SUCCESS; } }); 经试验:多个消费者无法实现顺序消费,最终由一个消费者接收所有消息 注意: 1,producer.send(msg, new SendCallback() { 该写法时常报错 2,出现消息没有被消费者接收的现象,重启客户端,mq服务器
public static void main(String[] args) throws Exception { // 实例化消息生产者Producer DefaultMQProducer producer = new DefaultMQProducer("xmhProducer2"); // 设置NameServer的地址 producer.setNamesrvAddr("192.168.89.137:9876"); // 启动Producer实例s producer.start(); SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss:SSS"); int messageCount =100; // 根据消息数量实例化倒计时计算器 final CountDownLatch2 countDownLatch = new CountDownLatch2(messageCount); for (int i = 0; i < messageCount; i++) { final int index = i; Message msg = new Message("TopicTest", "TagA", ("xmh1******************helloworld"+i+"-"+df.format(new Date())).getBytes(RemotingHelper.DEFAULT_CHARSET)); // 发送消息到一个Broker // SendResult sendResult = producer.send(msg,messageQueueSelector,""); SendResult sendResult = producer.send(msg); // // 通过sendResult返回消息是否成功送达 System.out.println(new String(msg.getBody())+" "+sendResult); // producer.send(msg, new SendCallback() {//,messageQueueSelector // @Override // public void onSuccess(SendResult sendResult) { // System.out.println(new String(msg.getBody())); // } // @Override // public void onException(Throwable e) { // System.out.printf("%-10d Exception %s %n", index, e); // e.printStackTrace(); // } // }); } // 等待5s countDownLatch.await(5, TimeUnit.SECONDS); // 如果不再发送消息,关闭Producer实例。 producer.shutdown(); } public static void main(String[] args) throws InterruptedException, MQClientException { // 实例化消费者 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("xmhgroup"); // 设置NameServer的地址 consumer.setNamesrvAddr("192.168.89.137:9876"); // 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息 consumer.subscribe("TopicTest", "*"); consumer.setMessageModel(MessageModel.CLUSTERING);//BROADCASTING 广播 或 集群 consumer.setConsumerGroup("group1"); //单线程顺序消费 // consumer.setConsumeThreadMin(1); // consumer.setConsumeThreadMax(1); // 注册回调实现类来处理从broker拉取回来的消息 consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { int i =0; for (MessageExt msg:msgs){ System.out.println((i++)+" "+new String(msg.getBody())+"*****"+msg); } // 标记该消息已经被成功消费 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); //多线程顺序消费 // consumer.registerMessageListener( new MessageListenerOrderly() { // @Override // public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) { // int i =0; // for (MessageExt msg:msgs){ // System.out.println((i++)+" "+new String(msg.getBody())+"*****"+msg); // } // // 标记该消息已经被成功消费 // return ConsumeOrderlyStatus.SUCCESS; // } // }); // 启动消费者实例 consumer.start(); System.out.printf("Consumer Started.%n"); } 默认配置 brokerClusterName = DefaultCluster brokerName = broker-a brokerId = 0 deleteWhen = 04 fileReservedTime = 48 brokerRole = ASYNC_MASTER flushDiskType = ASYNC_FLUSH #所属集群名字 brokerClusterName=rocketmq-cluster #broker名字,注意此处不同的配置文件填写的不一样 例如:在a.properties 文件中写 broker-a 在b.properties 文件中写 broker-b brokerName=broker-a #0 表示 Master,>0 表示 Slave brokerId=0 #nameServer地址,分号分割 namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876 #在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 defaultTopicQueueNums=4 #是否允许 Broker 自动创建Topic,建议线下开启,线上关闭 autoCreateTopicEnable=true #是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭 autoCreateSubscriptionGroup=true #Broker 对外服务的监听端口 listenPort=10911 #删除文件时间点,默认凌晨 4点 deleteWhen=04 #文件保留时间,默认 48 小时 fileReservedTime=120 #commitLog每个文件的大小默认1G mapedFileSizeCommitLog=1073741824 #ConsumeQueue每个文件默认存30W条,根据业务情况调整 mapedFileSizeConsumeQueue=300000 #destroyMapedFileIntervalForcibly=120000 #redeleteHangedFileInterval=120000 #检测物理文件磁盘空间 diskMaxUsedSpaceRatio=88 #存储路径 storePathRootDir=/usr/local/rocketmq/store #commitLog 存储路径 storePathCommitLog=/usr/local/rocketmq/store/commitlog #消费队列存储路径存储路径 storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue #消息索引存储路径 storePathIndex=/usr/local/rocketmq/store/index #checkpoint 文件存储路径 storeCheckpoint=/usr/local/rocketmq/store/checkpoint #abort 文件存储路径 abortFile=/usr/local/rocketmq/store/abort #限制的消息大小 maxMessageSize=65536 #flushCommitLogLeastPages=4 #flushConsumeQueueLeastPages=2 #flushCommitLogThoroughInterval=10000 #flushConsumeQueueThoroughInterval=60000 #Broker 的角色 #- ASYNC_MASTER 异步复制Master #- SYNC_MASTER 同步双写Master #- SLAVE brokerRole=ASYNC_MASTER #刷盘方式 #- ASYNC_FLUSH 异步刷盘 #- SYNC_FLUSH 同步刷盘 flushDiskType=ASYNC_FLUSH #checkTransactionMessageEnable=false #发消息线程池数量 #sendMessageThreadPoolNums=128 #拉消息线程池数量 #pullMessageThreadPoolNums=128