动力节点RocketMQ笔记二、RocketMQ与重复消费

本文介绍了RocketMQ的重复消费问题及其原因,包括CLUSTERING模式下负载均衡时可能出现的重复消费。解决方案是使用布隆过滤器进行消息去重,通过Hutool库实现布隆过滤器,并在消费者端进行消费前的去重检查。同时,文章还涵盖了RocketMQ的消息发送和监听流程、消费模式、发送不同类型的异步消息、顺序消息、死信消息处理等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8. RocketMQ快速入门

RocketMQ提供了发送多种发送消息的模式,例如同步消息,异步消息,顺序消息,延迟消息,事务消息等,我们一一学习

8.1 消息发送和监听的流程

我们先搞清楚消息发送和监听的流程,然后我们在开始敲代码

8.1.1 消息生产者

| 1.创建消息生产者producer,并制定生产者组名
2.指定Nameserver地址
3.启动producer
4.创建消息对象,指定主题Topic、Tag和消息体等
5.发送消息

6.关闭生产者producer

8.1.2 消息消费者

| 1.创建消费者consumer,制定消费者组名
2.指定Nameserver地址
3.创建监听订阅主题Topic和Tag等
4.处理消息

5.启动消费者consumer

8.2 搭建Rocketmq-demo

8.2.1 加入依赖

|    
       
org.apache.rocketmq       
rocketmq-client       
4.9.2

4.4.0                junit        junit        4.12                org.projectlombok        lombok        1.18.22      | | --- |

8.2.2 编写生产者

| /** * 测试生产者 * * @throws Exception */
@Testpublic void testProducer() throws Exception {   
_// 创建默认的生产者    _
DefaultMQProducer producer = new DefaultMQProducer(“test-group”);   
_// 设置nameServer地址    _
producer.setNamesrvAddr(“localhost:9876”);   
_// 启动实例    _
producer.start();   
for (int i = 0; i < 10; i++) {       
_// 创建消息        _
_// 第一个参数:主题的名字        _
_// 第二个参数:消息内容        _
Message msg = new Message(“TopicTest”, ("Hello RocketMQ " + i).getBytes());       
SendResult send = producer.send(msg);       
System.out.println(send);   
}   
_// 关闭实例    _producer.shutdown();

}

8.2.3 编写消费者

|     _/**     * 测试消费者     *     * @throws Exception     */    _
@Test    public void testConsumer() throws Exception {       
_// 创建默认消费者组        _
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(“consumer-group”);       
_// 设置nameServer地址        _
consumer.setNamesrvAddr(“localhost:9876”);       
_// 订阅一个主题来消费   表示没有过滤参数 表示这个主题的任何消息        _consumer.subscribe(“TopicTest”, "");       
_// 注册一个消费监听 _
_MessageListenerConcurrently 是多线程消费,默认20个线程,可以参看consumer.setConsumeThreadMax()        _
consumer.registerMessageListener(new MessageListenerConcurrently() {            @Override           
public ConsumeConcurrentlyStatus consumeMessage(List msgs,                                                           
ConsumeConcurrentlyContext context) {               
System.out.println(Thread.currentThread().getName() + “----” + msgs);               
_// 返回消费的状态 如果是CONSUME_SUCCESS 则成功,若为RECONSUME_LATER则该条消息会被重回队列,重新被投递                _
_// 重试的时间为messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h                _
// 也就是第一次1s 第二次5s 第三次10s  …  如果重试了18次 那么这个消息就会被终止发送给消费者
_//                _
_return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;                _
return ConsumeConcurrentlyStatus.RECONSUME_LATER;           
}        });       
_// 这个start一定要写在registerMessageListener下面        _
consumer.start();       
System.in.read();

}

8.2.4 测试

启动生产者和消费者进行测试

9. 消费模式

MQ的消费模式可以大致分为两种,一种是推Push,一种是拉Pull。
Push是服务端【MQ】主动推送消息给客户端,优点是及时性较好,但如果客户端没有做好流控,一旦服务端推送大量消息到客户端时,就会导致客户端消息堆积甚至崩溃。
Pull是客户端需要主动到服务端取数据,优点是客户端可以依据自己的消费能力进行消费,但拉取的频率也需要用户自己控制,拉取频繁容易造成服务端和客户端的压力,拉取间隔长又容易造成消费不及时。
Push模式也是基于pull模式的,只能客户端内部封装了api,一般场景下,上游消息生产量小或者均速的时候,选择push模式。在特殊场景下,例如电商大促,抢优惠券等场景可以选择pull模式

10.   RocketMQ发送同步消息

上面的快速入门就是发送同步消息,发送过后会有一个返回值,也就是mq服务器接收到消息后返回的一个确认,这种方式非常安全,但是性能上并没有这么高,而且在mq集群中,也是要等到所有的从机都复制了消息以后才会返回,所以针对重要的消息可以选择这种方式

11.   RocketMQ发送异步消息

异步消息通常用在对响应时间敏感的业务场景,即发送端不能容忍长时间地等待Broker的响应。发送完以后会有一个异步消息通知

11.1 异步消息生产者

| @Testpublic void testAsyncProducer() throws Exception {   
_// 创建默认的生产者    _
DefaultMQProducer producer = new DefaultMQProducer(“test-group”);   
_// 设置nameServer地址    _
producer.setNamesrvAddr(“localhost:9876”);   
_// 启动实例    _producer.start();   
Message msg = new Message(“TopicTest”, (“异步消息”).getBytes());**    **
**producer.send(msg, new SendCallback() {        **
**@Override        **
**public void onSuccess(SendResult sendResult) {            **
**System.out.println(“发送成功”);        **
**}        **
**@Override        **
**public void onException(Throwable e) {            **
System.out.println(“发送失败”);       **
** }    });
   
System.out.println(“看看谁先执行”);   
_// 挂起jvm 因为回调是异步的不然测试不出来    _
System.in.read();   
_// 关闭实例    _
producer.shutdown();

}

11.2 异步消息消费者

| @Testpublic void testAsyncConsumer() throws Exception {   
_// 创建默认消费者组    _
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(“consumer-group”);   
_// 设置nameServer地址    _consumer.setNamesrvAddr(“localhost:9876”);   
_// 订阅一个主题来消费   表示没有过滤参数 表示这个主题的任何消息    _
consumer.subscribe(“TopicTest”, "
");   
_// 注册一个消费监听 MessageListenerConcurrently是并发消费    _
_// 默认是20个线程一起消费,可以参看 consumer.setConsumeThreadMax()    _consumer.registerMessageListener(new MessageListenerConcurrently() {       
@Override       
public ConsumeConcurrentlyStatus consumeMessage(List msgs,                                                       
ConsumeConcurrentlyContext context) {           
_// 这里执行消费的代码 默认是多线程消费            _
System.out.println(Thread.currentThread().getName() + “----” + msgs);           
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;       
}    });   
consumer.start();   
System.in.read();

}

12.   RocketMQ发送单向消息

这种方式主要用在不关心发送结果的场景,这种方式吞吐量很大,但是存在消息丢失的风险,例如日志信息的发送

12.1 单向消息生产者

| @Testpublic void testOnewayProducer() throws Exception {   
_// 创建默认的生产者    _
DefaultMQProducer producer = new DefaultMQProducer(“test-group”);   
_// 设置nameServer地址    _
producer.setNamesrvAddr(“localhost:9876”);   
// 启动实例    _
producer.start();   
Message msg = new Message(“TopicTest”, (“单向消息”).getBytes());   
// 发送单向消息**
    _producer.sendOneway(msg);**   
_// 关闭实例    _
producer.shutdown();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值