IDEA整合Maven项目
-
idea搭建maven项目
https://blog.csdn.net/weixin_39209728/article/details/85853516
-
idea整合tomcat
https://blog.csdn.net/lsqingfeng/article/details/90199876
https://www.cnblogs.com/best/p/8543022.html
https://www.cnblogs.com/creasybear/p/11598255.html
-
idea启动tomcat控制台乱码
https://blog.csdn.net/nan_cheung/article/details/79337273
-
idea启动tomcat项目jsp页面乱码
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
-
tomcat添加配置后启动失败
- 添加配置
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- tomcat启动报错
org.apache.catalina.LifecycleException: 协议处理器启动失败 Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
-
参考链接
https://segmentfault.com/a/1190000021838764
消息发送总体思路
-
导入RocketMQ客户端依赖
<!-- 原生rocketmq client --> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.4.0</version> </dependency>
-
消息发送者步骤分析
-
创建消息生产者producer,并制定生产者组名
-
指定NameServer地址
-
启动Producer
-
创建消息对象,指定主题Topic、Tag和消息体
-
发送消息
-
关闭生产者Producer
-
-
消息消费者步骤分析
-
创建消费者Consumer,指定消费者组名
-
指定Nameserver地址
-
订阅主题Topic和Tag
-
设置回调函数,处理消息
-
启动消费者
-
基本样例
同步消息
- 案例代码
import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.common.message.Message; import java.util.concurrent.TimeUnit; /** * 可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知、短信通知 */ public class SyncProducer { public static void main(String[] args) throws Exception { //1. 创建消息生产者producer,并制定生产者组名 DefaultMQProducer producer = new DefaultMQProducer("group1"); //2. 指定NameServer地址 producer.setNamesrvAddr("192.168.159.133:9876;192.168.159.134:9876"); //3. 启动Producer producer.start(); for (int i = 0; i < 10; i++) { //4. 创建消息对象,指定主题Topic、Tag和消息体 /** * 参数1:消息主题Topic * 参数2:消息标签Tag * 参数3:消息内容 */ Message message = new Message("base", "tag1", ("武汉加油" + i).getBytes()); //5. 发送消息 SendResult result = producer.send(message); System.out.println("发送结果:" + result); /** * Thread.sleep(1000);它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出InterrupttedException异常(如果有线程中断了当前线程)。 * TimeUnit具有更好的可读性,不需要进行复杂的单位换算 */ //线程睡眠1秒 TimeUnit.SECONDS.sleep(1); } //6. 关闭生产者Producer producer.shutdown(); } }
异步消息
-
案例代码
import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.client.producer.SendCallback; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.common.message.Message; import java.util.concurrent.TimeUnit; /** * 发送异步消息:通常对响应时间敏感的业务场景,即发送不能容忍长时间地等待broker的响应 */ public class AsyncProducer { public static void main(String[] args) throws Exception { //1. 创建消息生产者producer,并制定生产者组名 DefaultMQProducer producer = new DefaultMQProducer("group1"); //2. 指定NameServer地址 producer.setNamesrvAddr("192.168.159.133:9876;192.168.159.134:9876"); //3. 启动Producer producer.start(); for (int i = 0; i < 10; i++) { //4. 创建消息对象,指定主题Topic、Tag和消息体 /** * 参数1:消息主题Topic * 参数2:消息标签Tag * 参数3:消息内容 */ Message message = new Message("base", "tag2", ("武汉加油" + i).getBytes()); //5. 发送消息结果包含 发送状态,消息id,消息接收队列id producer.send(message, new SendCallback() { //发送成功回调函数 @Override public void onSuccess(SendResult sendResult) { System.out.println("发送成功结果:" + sendResult); } @Override public void onException(Throwable throwable) { System.out.println("发送失败结果:" + throwable); } }); /** * Thread.sleep(1000);它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出InterrupttedException异常(如果有线程中断了当前线程)。 * TimeUnit具有更好的可读性,不需要进行复杂的单位换算 */ //线程睡眠1秒 TimeUnit.SECONDS.sleep(1); } //6. 关闭生产者Producer producer.shutdown(); System.out.println("发送完成"); } }
单向消息
-
案例代码
import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message; import java.util.concurrent.TimeUnit; /** * 发送单向消息:这种方式主要用于不特别关心发送结果的场景,例如日志发送 */ public class OneWayProducer { public static void main(String[] args) throws Exception { //1.创建消息生产者Producer,并制定生产者组名 DefaultMQProducer producer = new DefaultMQProducer("group1"); //2.指定NameServer地址 producer.setNamesrvAddr("192.168.159.133:9876;192.168.159.134:9876"); //3.启动producer producer.start(); for (int i = 0; i < 10; i++) { //4.创建消息对象,指定主题Topic,Tag和消息体 /** * 参数1:消息主题Topic * 参数2:消息标签Tag * 参数3:消息内容 */ Message message = new Message("base", "tag3", ("武汉加油" + i).getBytes()); //5.发送单向消息 producer.send(message); System.out.println("发送单向消息"); /** * Thread.sleep(1000);它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出InterrupttedException异常(如果有线程中断了当前线程)。 * TimeUnit具有更好的可读性,不需要进行复杂的单位换算 */ //线程睡眠1秒 TimeUnit.SECONDS.sleep(1); } //6.关闭生产者 producer.shutdown(); } }
消费消息
-
样例代码
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; import java.util.List; public class Consumer { public static void main(String[] args) throws Exception { //1. 创建消费者Consumer,指定消费者组名 (推送模式) DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1"); //2. 指定Nameserver地址 consumer.setNamesrvAddr("192.168.159.133:9876;192.168.159.134:9876"); //3. 订阅主题Topic和Tag consumer.subscribe("base","tag3"); //设置消费模式:默认是负载均衡模式,这里选用是广播 consumer.setMessageModel(MessageModel.BROADCASTING); //4. 设置回调函数,处理消息 consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { //接收消息内容 for (MessageExt messageExt : list) { System.out.println(new String(messageExt.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); //5. 启动消费者 consumer.start(); } }
顺序消息
-
介绍
消息有序:是指可以按照消息的发送顺序来消费(FIFO)。RocketMQ可以严格的保证消息有序,可以分为分区有序或者全局有序
-
原理分析
默认情况下消息发送会采取Round Robin轮询方式把消息发送到不同的queue(分区队列),而消费消息的时候从多个queue中拉取消息,这种情况下导致发送和消费不能保证顺序。但相对于每一个queue消息都是有序的。
全局有序:发送和消费参与的queue只有一个。
分区有序:发送和消费参与的queue有多个。
-
流程分析
-
顺序消息生产
订单号相同的消息(创建/付款/推送/完成)会被先后发送到同一个队列中
- 构建订单集合
import java.util.ArrayList;
import java.util.List;
public class OrderStep {
private long orderId;
private String desc;
public long getOrderId() {
return orderId;
}
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "OrderStep{" +
"orderId=" + orderId +
", desc='" + desc + '\'' +
'}';
}
public static List<OrderStep> buildOrders() {
// 1039L 创建 付款 推送 完成
// 1065L 创建 付款
// 7235L 创建 付款 推送
List<OrderStep> orderList = new ArrayList<>();
OrderStep demo = new OrderStep();
demo.setOrderId(1039L);
demo.setDesc("创建");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(1039L);
demo.setDesc("付款");
orderList.add(demo);
demo.setOrderId(1039L);
demo.setDesc("推送");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(1039L);
demo.setDesc("完成");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(1065L);
demo.setDesc("创建");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(1065L);
demo.setDesc("付款");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(7235L);
demo.setDesc("创建");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(7235L);
demo.setDesc("付款");
orderList.add(demo);
demo = new OrderStep();
demo.setOrderId(7235L);
demo.setDesc("推送");
orderList.add(demo);
return orderList;
}
}
- 消息生产者
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import java.util.List;
public class Producer {
public static void main(String[] args) throws Exception {
//1.创建消息生产者producer,并指定生产者组名
DefaultMQProducer producer = new DefaultMQProducer("group1");
//2.指定NameServer地址
producer.setNamesrvAddr("192.168.159.133:9876;192.168.159.134:9876");
//3.启动producer
producer.start();
//构建消息集合
List<OrderStep> orderStepList = OrderStep.buildOrders();
//发送消息
for (int i = 0; i < orderStepList.size(); i++) {
String body = orderStepList.get(i) + "";
Message message = new Message("OrderTopic", "Order", i + "i", body.getBytes());
/**
* 参数1:消息对象
* 参数2:消息队列选择器
* 参数3:选择队列的业务标识(订单id)
*/
SendResult result = producer.send(message, new MessageQueueSelector() {
/**
*
* @param list 队列集合
* @param message 消息对象
* @param o 业务标识的参数
* @return
*/
@Override
public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
long orderId = (Long) o;
//取余,建议根据实际场景使用hash算法
long index = orderId % list.size();
return list.get((int) index);
}
}, orderStepList.get(i).getOrderId());
System.out.println("发送结果:" + result);
}
producer.shutdown();
}
}
-
顺序消息消费
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly; import org.apache.rocketmq.common.message.MessageExt; import java.util.List; public class Consumer { public static void main(String[] args) throws Exception { //1.创建消费者Consumer,制定消费者组名 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1"); //2.指定NameServer地址 consumer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); //3.订阅主题Topic和Tag consumer.subscribe("OrderTopic","*"); //4.注册消息监听器 consumer.registerMessageListener(new MessageListenerOrderly() { @Override public ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext consumeOrderlyContext) { for (MessageExt messageExt : list) { System.out.println("线程名称:【" + Thread.currentThread().getName() + "】消费消息:" + new String(messageExt.getBody())); } return ConsumeOrderlyStatus.SUCCESS; } }); //5.启动消费者 consumer.start(); System.out.println("消费者启动了..."); } }
延时消息
-
场景分析
例如电商里,提交了一个订单就可以发送一个延时消息,1h后去检查这个订单状态,如果还是未付款就取消订单释放库存
-
延时等级
-
消息生产者
public class Producer { public static void main(String[] args) throws Exception { // 1.创建消息生产者producer,并制定生产者组名 DefaultMQProducer producer = new DefaultMQProducer("group1"); // 2.指定NameServer地址 producer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 3.启动producer producer.start(); for (int i = 0; i < 10; i++) { // 4.创建消息对象,指定主题Topic、Tag和消息体 /* 参数1:消息主题Topic 参数2:消息Tag 参数3:消息内容 */ Message msg = new Message("DelayTopic","tag1",("hello world"+i).getBytes()); // 设置延迟时间 RocketMq并不支持任意时间的延时,需要试着几个固定的延时等级 // 从1s到2h分别对应着等级1到18 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h msg.setDelayTimeLevel(2); // 5.发送消息结果包含 发送状态 消息id 消息接收队列id等 SendResult result = producer.send(msg); System.out.println("发送结果"+result); // 线程睡眠1秒 TimeUnit.SECONDS.sleep(1); } // 6关闭生产者producer producer.shutdown(); } }
-
消息消费者
public class Consumer { public static void main(String[] args) throws MQClientException { // 1.创建消费者Consumer,制定消费者组名 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1"); // 2.指定Nameserver地址 consumer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 3.订阅主题Topic和Tag consumer.subscribe("DelayTopic","tag1"); // 消费模式:默认是负载均衡模式,还有一种是广播模式 // consumer.setMessageModel(MessageModel.BROADCASTING); // 4.设置回调函数,处理消息 consumer.registerMessageListener(new MessageListenerConcurrently() { //接收消息内容 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { for (MessageExt messageExt : list) { System.out.println("消息id:【"+messageExt.getMsgId()+"】,延时时间:"+(System.currentTimeMillis()-messageExt.getStoreTimestamp())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); // 5.启动消费者consumer consumer.start(); System.out.println("消费者启动"); } }
批量消息
-
介绍
批量发送消息能显著提高传递消息的性能。限制是这些批量消息应该有相同的topic,相同的waitStoreMsgOK,而且不能是延时消息。此外,这一批消息的总大小不应超过4MB -
消息分割类
import org.apache.rocketmq.common.message.Message; import java.util.Iterator; import java.util.List; import java.util.Map; public class ListSplitter implements Iterator<List<Message>> { private final int SIZE_LIMIT = 1000 * 1000; private final List<Message> messages; private int currIndex; public ListSplitter(List<Message> messages) { this.messages = messages; } @Override public boolean hasNext() { return currIndex < messages.size(); } @Override public List<Message> next() { int nextIndex = currIndex; int totalSize = 0; for (; nextIndex < messages.size(); nextIndex++) { Message message = messages.get(nextIndex); int tmpSize = message.getTopic().length() + message.getBody().length; Map<String, String> properties = message.getProperties(); for (Map.Entry<String, String> entry : properties.entrySet()) { tmpSize += entry.getKey().length() + entry.getValue().length(); } tmpSize = tmpSize + 20; //for log overhead if (tmpSize > SIZE_LIMIT) { //it is unexpected that single message exceeds the SIZE_LIMIT //here just let it go, otherwise it will block the splitting process if (nextIndex - currIndex == 0) { //if the next sublist has no element, add this one and then break, otherwise just break nextIndex++; } break; } if (tmpSize + totalSize > SIZE_LIMIT) { break; } else { totalSize += tmpSize; } } List<Message> subList = messages.subList(currIndex, nextIndex); currIndex = nextIndex; return subList; } }
-
消息生产者
import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message; import org.apache.rocketmq.remoting.common.RemotingHelper; import java.util.ArrayList; import java.util.List; public class Producer { public static void main(String[] args) throws Exception { DefaultMQProducer producer = new DefaultMQProducer("BatchProducerGroup"); producer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); producer.start(); List<Message> msgs = new ArrayList<>(); for (int i = 0; i < 1000; i++) { try { // Create a message instance, specifying topic, tag and message body. Message msg = new Message( "batch_send_message_topic" /* Topic */, "TagA" /* Tag */, ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */ ); msgs.add(msg); } catch (Exception e) { e.printStackTrace(); } } //then you could split the large list into small ones: ListSplitter splitter = new ListSplitter(msgs); while (splitter.hasNext()) { try { List<Message> listItem = splitter.next(); producer.send(listItem); } catch (Exception e) { e.printStackTrace(); //handle the error } } // Shut down once the producer instance is not longer in use. producer.shutdown(); } }
-
消息消费者
public class Consumer { public static void main(String[] args) throws MQClientException { // 1.创建消费者Consumer,制定消费者组名 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1"); // 2.指定Nameserver地址 consumer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 3.订阅主题Topic和Tag consumer.subscribe("batchTopic","*"); // 消费模式:默认是负载均衡模式,还有一种是广播模式 // consumer.setMessageModel(MessageModel.BROADCASTING); // 4.设置回调函数,处理消息 consumer.registerMessageListener(new MessageListenerConcurrently() { //接收消息内容 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { for (MessageExt messageExt : list) { System.out.println(new String(messageExt.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); // 5.启动消费者consumer consumer.start(); System.out.println("消费者启动"); } }
过滤消息
-
Tag方式过滤
-
SQL表达式基本语法
-
消息生产者
public class Producer { public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException { // 1.创建消息生产者producer,并制定生产者组名 DefaultMQProducer producer = new DefaultMQProducer("group1"); // 2.指定NameServer地址 producer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 3.启动producer producer.start(); for (int i = 0; i < 10; i++) { // 4.创建消息对象,指定主题Topic、Tag和消息体 /* 参数1:消息主题Topic 参数2:消息Tag 参数3:消息内容 */ Message msg = new Message("filterSqlTopic","tag1",("hello world"+i).getBytes()); // 注意:设置属性 msg.putUserProperty("i",String.valueOf(i)); // 5.发送消息结果包含 发送状态 消息id 消息接收队列id等 SendResult result = producer.send(msg); System.out.println("发送结果"+result); // 线程睡眠1秒 TimeUnit.SECONDS.sleep(1); } // 6关闭生产者producer producer.shutdown(); } }
-
消息消费者
public class ConsumerSql { public static void main(String[] args) throws MQClientException { // 1.创建消费者Consumer,制定消费者组名 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1"); // 2.指定Nameserver地址 consumer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 3.订阅主题Topic和Tag // 注意:通过tag筛选 //consumer.subscribe("filterTopic","tag1 || tag2"); // 注意:通过sql筛选 consumer.subscribe("filterSqlTopic", MessageSelector.bySql("i>5")); // 消费模式:默认是负载均衡模式,还有一种是广播模式 consumer.setMessageModel(MessageModel.BROADCASTING); // 4.设置回调函数,处理消息 consumer.registerMessageListener(new MessageListenerConcurrently() { //接收消息内容 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { for (MessageExt messageExt : list) { System.out.println(new String(messageExt.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); // 5.启动消费者consumer consumer.start(); System.out.println("消费者启动"); } }
事务消息
-
流程分析
-
流程分类
-
事务消息发送及提交
(1) 发送消息(half消息)
(2) 服务端响应消息写入结果
(3) 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)
(4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见) -
事务补偿
(1) 对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次"回查"
(2) Producer收到回查消息,检查回查消息对应的本地事务的状态
(3) 根据本地事务状态,重新Commit或者Rollback
-
事务消息状态
- TransactionStatus.CommitTransaction:提交事务,它允许消费者消费此消息
- TransactionStatus.RollbackTransaction:回滚事务,它允许该消息将被删除,不允许被消费
- TransactionStatus.Unknown:中间状态,它代表需要检查消息队列来确定状态
-
消息生产者
public class Producer { public static void main(String[] args) throws Exception { // 1.创建消息生产者producer,并制定生产者组名 事务生产者 TransactionMQProducer producer = new TransactionMQProducer("group5"); // 2.指定NameServer地址 producer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 生产者监听器 producer.setTransactionListener(new TransactionListener() { /** * 在该方法中执行本地事务 第二步 * @param message * @param o * @return */ public LocalTransactionState executeLocalTransaction(Message message, Object o) { if (StringUtils.equals("taga",message.getTags())){ return LocalTransactionState.COMMIT_MESSAGE; } else if (StringUtils.equals("tagb",message.getTags())){ return LocalTransactionState.ROLLBACK_MESSAGE; } else if (StringUtils.equals("tagc",message.getTags())){ return LocalTransactionState.UNKNOW; } return LocalTransactionState.UNKNOW; } /** * 该方法是mq进行消息事务状态回查 第三步 * @param messageExt * @return */ public LocalTransactionState checkLocalTransaction(MessageExt messageExt) { System.out.println("消息的tag:"+messageExt.getTags()); return LocalTransactionState.COMMIT_MESSAGE; } }); // 3.启动producer producer.start(); String[] tags = {"taga","tagb","tagc"}; for (int i = 0; i < 3; i++) { // 4.创建消息对象,指定主题Topic、Tag和消息体 /* 参数1:消息主题Topic 参数2:消息Tagf 参数3:消息内容 */ Message msg = new Message("transactionTopic",tags[i],("hello world"+i).getBytes()); // 5.发送消息结果包含 发送状态 消息id 消息接收队列id等 第一步 SendResult result = producer.sendMessageInTransaction(msg,null); System.out.println("发送结果"+result); // 线程睡眠1秒 TimeUnit.SECONDS.sleep(3); } // 6关闭生产者producer // producer.shutdown(); } }
-
消息消费者
public class Consumer { public static void main(String[] args) throws MQClientException { // 1.创建消费者Consumer,制定消费者组名 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group5"); // 2.指定Nameserver地址 consumer.setNamesrvAddr("192.169.159.134:9876;192.168.159.133:9876"); // 3.订阅主题Topic和Tag consumer.subscribe("transactionTopic","*"); // 4.设置回调函数,处理消息 consumer.registerMessageListener(new MessageListenerConcurrently() { //接收消息内容 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { for (MessageExt messageExt : list) { System.out.println(new String(messageExt.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); // 5.启动消费者consumer consumer.start(); System.out.println("消费者启动"); } }
-
使用限制