​RocketMQ使用浅析(二)​

上篇文章介绍了RocketMQ的构成与消息发送方式,接下来我们继续RocketMQ的消费模式、事务消息与持久化。上一篇文章的链接:RocketMQ使用浅析(一)

RocketMQ消费方式

1.推模式

RocketMQ服务器主动给客户端推送消息,当客户端连接到服务器时,服务器会hold这个连接一段时间,这个时间如果有新消息到达,会通过hold的这个连接通道直接返回给客户端,消息推送非常及时,但是对于服务端的压力比较大

        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumerGroup");

        //设置namesrv地址
        consumer.setNamesrvAddr("localhost:9876");
        //订阅主题和标签
        consumer.subscribe("TOPIC_TEST", "*");
        //注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {

            System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);

            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; //返回消费状态

        });
        consumer.start(); //启动消费者

2.拉模式

客户端通过长轮询主动去拉服务端的消息,可以自主控制消息的消费时间,RocketMQ服务端的压力会减轻

拉模式采用的DefaultMQPullConsumer来实现。

RocketMQ事务消息

RocketMQ的事务消息解决了,消息已发送出去,但是本地事务异常回滚,无法进行消息撤回的问题。

事务消息分为以下步骤

1.生产者向Broker发送半消息

2.所有半消息存储在固定Topic:RMQ_SYS_TRANS_HALF_TOPIC中,对于消费者不可见

3.服务端将消息持久化,并向生产者返回ACK确认发送成功

4.生产者执行本地事务,根据事务结果向服务器进行二次确认(commit或者rollback)

5.如果服务端收到为提交,就将半消息拷贝到原始队列中,等待消费者消费

6.如果服务端迟迟收不到二次确认,会返查生产者,查看消息的状态

        TransactionMQProducer producer = new TransactionMQProducer("producer_group");
        producer.setNamesrvAddr("localhost:9876");

        // RocketMQ服务端消息返查
        producer.setTransactionCheckListener(msg -> LocalTransactionState.COMMIT_MESSAGE);
        producer.start();

        // 消息内容
        Message message = new Message("topic_name", "tag_name", "Transactional Message".getBytes());

        // 本地事务
        LocalTransactionExecuter executer = (msg, arg) -> {

            return LocalTransactionState.COMMIT_MESSAGE;
        };

        //消息发送
        producer.sendMessageInTransaction(message, executer);

消息如何持久化

1.当个Broker实例下,当生产者发送的消息内容,全部会写到一个日志数据文件来存储(commitlog)

2.当消息到达 commitlog 后,会采用异步转发到消息队列,也就是 consumerqueue,该文件夹下有三级目录:
第一级目录:topic命名的文件夹

第二级目录:MessageQueue 队列ID命名的文件夹

第三级目录: 具体的consumerQueue文件(该文件记录了,commitLog文件的位移offset,根据位移就能从commitLog找到具体的消息)

这样分层之后, RocketMQ 至少可以得到以下几个讯息:

  • 2.1 先通过topic名称,可以定位到具体的文件夹;
  • 2.2 然后根据消息队列ID找到具体的文件;
  • 2.3 最后根据文件内容,或得位移offset,然后根据定位commitLog消息内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值