消息种类
- 基本消息
生产者生产消息,消费者直接进行消费
发送流程
接收流程
- 顺序消息
消息有序是指按照消息的发送顺序来消费(FIFO)。RocketMQ可以严格保证消息有序,可以分为分区有序和全局有序
- 如何保证分区有序?生产者把一个业务的消息有序的放入到一个队列中,消费者顺序消费这个队列的消息
生产者代码
public static void main(String[] argv) throws Exception {
//创建Producer,并指定生产者组名
DefaultMQProducer producer = new DefaultMQProducer("group1");
//指定NameServer的地址
producer.setNamesrvAddr("106.55.146.154:9876;39.106.142.155:9876");
//启动Producer
producer.start();
//创建消息对象,指定Topic、Tag及消息体
List<OrderInfo> list = OrderInfo.getExample();
while (true) {
for (int i=0; i<list.size(); i++) {
OrderInfo orderInfo = list.get(i);
Message message = new Message("OrderTopic", "Order", "index:" + i, orderInfo.toString().getBytes());
producer.send(message, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
int id = (int)o;
System.out.println(list.size());
System.out.println(list.toString());
return list.get(id % list.size());
}
}, orderInfo.getId());
}
sleep(10* 1000);
}
//关闭Producer
//producer.shutdown();
}
消费者代码
public static void main(String[] argv) throws Exception{
//创建Consumer,并指定消费者组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
//指定NameServer的地址
consumer.setNamesrvAddr("106.55.146.154:9876;39.106.142.155:9876");
//订阅Topic、Tag
consumer.subscribe("OrderTopic", "*");
//设置一个队列,一个线程
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext consumeOrderlyContext) {
for(MessageExt ext : list) {
System.out.println(Thread.currentThread().getId()+ new String(ext.getBody()));
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
//
consumer.start();
}
- 延迟消息
就是消息必须延迟一段时间才能被消费,修改的代码就是生产者把消息设置时间级别而已
msg.setDelayTimeLevel(5);
- 批量消息
注意:消息总长度不能大于4M,超过要分割
生产者代码
List<Message> list = new ArrayList<>();
list.add(new Message("batch", "tag1", ("hello world" + 1).getBytes()));
list.add(new Message("batch", "tag2", ("hello world" + 2).getBytes()));//发送消息
list.add(new Message("batch", "tag3", ("hello world" + 3).getBytes()));
SendResult result = producer.send(list);
- 过滤消息
1. describe方法进行过滤
consumer.subscribe("delay", "tag1");
2. 通过sql过滤
生产者
msg.putUserProperty("i", "" + i);
消费者
consumer.subscribe("delay", MessageSelector.bySql("i=5"));
- 事务消息
两个流程:
1.事务发送和提交
- 发送消息
- 回复消息
- 执行本地事务
- 根据本地事务的状态进行提交或回滚
2.事务补偿
- 对没有commit或rollback的消息进行回查
- 收到回查消息检查本地事务状态
- 根据本地状态进行commit或rollback
3. 事务状态
- 提交状态
- 回滚状态
- 中间状态
消费者代码
public static void main(String[] argv) throws Exception{
//创建Consumer,并指定消费者组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
//指定NameServer的地址
consumer.setNamesrvAddr("106.55.146.154:9876;39.106.142.155:9876");
//订阅Topic、Tag
consumer.subscribe("transaction", "*");
//设置回调函数、处理消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
list.forEach(v -> {
System.out.println(v.getTags());
});
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//
consumer.start();
}
生产者代码
public static void main(String[] argv) throws Exception {
//创建Producer,并指定生产者组名
TransactionMQProducer producer = new TransactionMQProducer("group1");
//指定NameServer的地址
producer.setNamesrvAddr("106.55.146.154:9876;39.106.142.155:9876");
producer.setTransactionListener(new TransactionListener() {
@Override
public LocalTransactionState executeLocalTransaction(Message message, Object o) {
System.out.println(message.getTags());
if ("tagA".equals(message.getTags())) {
return LocalTransactionState.COMMIT_MESSAGE;
} else if ("tagB".equals(message.getTags())) {
return LocalTransactionState.ROLLBACK_MESSAGE;
} else {
return LocalTransactionState.UNKNOW;
}
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
System.out.println("check");
return LocalTransactionState.COMMIT_MESSAGE;
}
});
//启动Producer
producer.start();
//创建消息对象,指定Topic、Tag及消息体
String[] tags = {"tagA", "tagB", "tagC"};
for (int i=0; i<3; i++) {
Message msg = new Message("transaction", tags[i], ("hello world" + i).getBytes());
//发送消息
SendResult result = producer.sendMessageInTransaction(msg, null);
System.out.println(result.getSendStatus());
System.out.println(result.getMsgId());
System.out.println(result.getMessageQueue());
TimeUnit.SECONDS.sleep(1);
}
//关闭Producer
//producer.shutdown();
}