RocketMQ基础语法笔记

由于一个项目中要简单的用一下RocketMQ,所以下面做一些学习笔记供自己后面查阅复习(图片来源于黑马Rocket教程)

需要导入的依赖如下(版本号可能要和你在服务器s)

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.3.2</version>
</dependency>

下下哦i 

 

 一.消息生产者Producer的三种写法

1.发送同步消息

可以调用SendResult的一些方法来获取消息状态,消息id,队列id等信息

public class SynProducer {
    public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
        DefaultMQProducer producer = new DefaultMQProducer("group1");
        producer.setNamesrvAddr("rocketmq所在服务器的ip地址:端口号");
        producer.start();
        for (int i = 0; i <10 ; i++) {
            Message msg = new Message("base","Tag1",("Hello Worrld 同步消息"+i).getBytes());
            SendResult result = producer.send(msg);
//            SendStatus sendStatus = result.getSendStatus();
//            String msgId = result.getMsgId();
//            int queueId = result.getMessageQueue().getQueueId();
            System.out.println("发送结果"+result);
            TimeUnit.SECONDS.sleep(1);
        }
        producer.shutdown();
    }
}

2.发送异步消息

流程和发送同步消息差不多,只不过这里要设置发送异步消息的回调函数。这里一定要注意,因为是异步消息,所以可能会消息还没回调,主线程已经执行了producer.shutdown(),所以这里我让主线程睡了5秒

public class AsyncProducer {
    public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
        DefaultMQProducer producer = new DefaultMQProducer("group1");
        producer.setNamesrvAddr("IP地址:端口号");
        producer.start();
        for (int i = 0; i <10 ; i++) {
            Message msg = new Message("base","Tag1",("Hello Worrld 异步消息"+i).getBytes());
            producer.send(msg, new SendCallback() {
                /**
                 * 发送成功的回调函数
                 * @param sendResult
                 */
                public void onSuccess(SendResult sendResult) {
                    System.out.println("发送成功"+sendResult);
                }

                /**
                 * 发送失败的回调函数
                 * @param throwable
                 */
                public void onException(Throwable throwable) {
                    System.out.println("发送异常"+throwable);
                }
            });
        }
        TimeUnit.SECONDS.sleep(5);
        producer.shutdown();
    }
}

 

3.发送单向消息

没有返回消息,好像一般不用

public class OneWayProducer {
        public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
            DefaultMQProducer producer = new DefaultMQProducer("group1");
            producer.setNamesrvAddr("IP地址:端口号");
            producer.start();
            for (int i = 0; i <10 ; i++) {
                Message msg = new Message("base","Tag1",("Hello Worrld,单向消息"+i).getBytes());
                producer.sendOneway(msg);//单向发送消息
            }
            producer.shutdown();
        }
    }

二.Consumer消费者的三种写法

1.消息消费的基本流程

 

下面是消费者的代码。线程就阻塞着监听消息,消息一产生,消费者就输出出来

public class Consumer {
    public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");//要指定要消费的group
        consumer.setNamesrvAddr("IP地址:端口号");
        consumer.subscribe("base", "Tag1");//消费base中的Tag1
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            //接收消息内容
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                for(Message ext: list){
                    System.out.println(new String(ext.getBody()));
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
    }
}

 

2.消费者广播模式和负载均衡模式

广播模式:所有消息消费者都分别消费一遍

负载均衡模式(默认):消费者共同消费消息

可以用consumer.setMessageModel(MessageModel.BROADCASTING);来设置成广播模式

consumer.setMessageModel(MessageModel.BROADCASTING);

3.顺序消息

rocketmq中发送消息和接收消息的顺序是不一致的,因为broker中存在多个消息队列,多个处理信息可能被放在不同的消息队列中,然后消费者多线程读取消息,此时无法保证消息的读取顺序,解决方法是把局部整体的消息放进一个队列即可

 

 

 

同一个订单被同一个线程处理(因为一个线程处理一个队列,一组消息又都在同一个队列里,自然处理这组消息的线程相同)

 

4.延时消息

延时时间只能用rocketmq指定的。这里的延时不是发送消息延时,而是消费者接收延时

在生产者中给消息设置延时时间

 

5.批量消息

批量消息:传集合即可

6.支持sql语法过滤 

 

 

 

三.事务消息 

 

事务执行的流程大致如下图,先发送半消息到MQ server,MQ Server响应之后,开始执行Local Tranction,在代码中会重写执行事务消息和回查事务消息的方法 

 

下面是TransactionProducer的代码

代码的重点producer.setTransactionListener里重写的两个方法,我让tags=TAGA的消息提交,TAGB的消息回滚,TAGC的消息处于中间状态,然后在checkLocalTransaction回查的时候进行提交,所以理论上消费者可以收到Hello Worrd Transaction0和Hello Worrd Transaction3

 

public class TransactionProducer {
    public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
        TransactionMQProducer producer = new TransactionMQProducer("group5");
        producer.setNamesrvAddr("ip地址:端口号");


        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;
            }
        });
        producer.start();
        String[] tags = {"TAGA","TAGB","TAGC"};

        for (int i = 0; i <3 ; i++) {
            Message msg = new Message("TransactionTopic",tags[i],("Hello Worrd Transaction"+i).getBytes());
            SendResult result = producer.sendMessageInTransaction(msg,null);//null表示对所有消息都进行事务控制
//            SendStatus sendStatus = result.getSendStatus();
//            String msgId = result.getMsgId();
//            int queueId = result.getMessageQueue().getQueueId();
            System.out.println("发送结果"+result);
            TimeUnit.SECONDS.sleep(1);
        }
        //producer.shutdown(); //因为事务中要回查消息,所以producer最好别停
    }
}

下面是TransactionConsumer的代码

public class TransactionConsumer {
    public static void main(String[] args) throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group5");//要指定要消费的group
        consumer.setNamesrvAddr("ip地址:端口号");
        consumer.subscribe("TransactionTopic", "*");//消费Transaction Topic中的全部消息
        consumer.setMessageModel(MessageModel.BROADCASTING);
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            //接收消息内容
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                for(Message ext: list){
                    System.out.println(new String(ext.getBody()));
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
        System.out.println("消费者启动");
    }
}

下图是测试结果,确实如预测的那样

 

 

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值