rocketMq之消息种类(七)

消息种类

  • 基本消息

生产者生产消息,消费者直接进行消费

发送流程

接收流程

  • 顺序消息

消息有序是指按照消息的发送顺序来消费(FIFO)。RocketMQ可以严格保证消息有序,可以分为分区有序和全局有序

  1. 如何保证分区有序?生产者把一个业务的消息有序的放入到一个队列中,消费者顺序消费这个队列的消息

生产者代码

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();
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值