大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目

生产者的核心配置:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第1张图片

一致性的保证:https://blog.csdn.net/Memery_last/article/details/83791165

生产者的核心配置。

2.投递到broker失败重新发送。

3.最大消息的大小。

4.主题下队列的数量。

5.是否自动创建,生产环境要设置为false。

7.consumer订阅topic可以配置为组,生产环境建议关闭。

10.Broker的服务地址。

12.每天执行过期文件删除是什么时候。

14.broker的监听端口。

15.消息的存储地址。

16.queue的消息条数。consumequeue每个默认是30W条。

17.单个commitLog默认是1G的。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第2张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第3张图片

这个可以拉大在电脑内存不足的时候。

---------------------------01-----------------------

ASYNC_MASTER:同步双写。

SYNC-MASTER:异步复制。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第4张图片

一个同步刷盘错误  两个同步双写错误。

第二个式同步双写。第三个是同步双写没找到子节点。

消息在堆同步到内存同步到磁盘。

第二点:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第5张图片

演示:

--------------------------------------------------------------------------------------------------

同步双写,异步刷盘

第三种:主从模式下配置为同步双写。没有找到子节点。一般第三种式比较常见的错误。

第一步:主节点改为同步复制。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第6张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第7张图片

第二步:代码不改。杀掉从节点SLAVE。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第8张图片

---------------------------------------------------------------------------------

测试:把主broker改为异步复制,重复上诉的步骤

异步的话不用给从节点直接返回成功。

------------------02-------------------

很重要的:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第9张图片

一条消息无论重试多少次,其MessageID和key都是不变的。

broker挂了,生产者是不能及时感知的。

消费者虽然消费消息了,但是只能给broker以ACK确认才可以在队列删除消息。

第一个知识点,我们如何设置生产者的重试的次数呢?

代码:02-06/02

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第10张图片

代码

// 生产者的重试次数
producer.setRetryTimesWhenSendFailed(3);

生产者的重试的话,如何保证消息不重复生产呢?

这里有key,加入我们把订单号作为key。

    @RequestMapping("/api/v1/pay_cb")
    public Object callback(String text) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {

        Message message = new Message(JmsConfig.TOPIC,"taga", "业务订单的key,防止重复消费",("hello fdy rocketmq = "+text).getBytes() );

        SendResult sendResult = payProducer.getProducer().send(message);
        System.out.println(sendResult);

        return new HashMap<>();
    }

生产者不要过多的关注。

代码:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第11张图片

第二个知识点消费者的消息重试:

广播模式不支持消息重试的。

一般3-4次。

模拟:第一步:看下这个包装类。这个是Message的包装类。这个我本地没有写代码直接看截图。

基本的原理就是消费端没有给broker返回CONSUMER_SUCCESS,就一直重试。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第12张图片

第二步:改造代码

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第13张图片

第三步:模拟异常,就不返回成功给broker了。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第14张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第15张图片

第三步:我们如何做异常的处理呢?在catch里面。并返回success。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第16张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第17张图片

返回CONSUMER_SUCCESS就删除队列的消息

返回RECONSUME_LATER就根据重试次数重试

在catch里面返回SUCCESS,自己处理错误。

----------------------------------------------------------------------------------------

第三个知识点:广播不重试

第一步:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第18张图片

第二步:

改为集群模式:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第19张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第20张图片

广播模式不支持重试的!!!!!!!!!!!!!!!!!!!!

--------------03--------------

我们之前都是同步的发送消息,现在我们异步的发送消息。

异步发送消息在发送端是不支持重试的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

代码:02

参考网址:https://rocketmq.apache.org/docs/simple-example/

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第21张图片

发送异步的消息。

异步消息是不会重试的。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第22张图片

@RestController
public class PayController {

    @Autowired
    private PayProducer payProducer;


    @RequestMapping("/api/v1/pay_cb")
    public Object callback(String text) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {

        Message message = new Message(JmsConfig.TOPIC,"taga", "6666key",("hello fdy rocketmq = "+text).getBytes() );

        // 如何异步的发送消息?
        payProducer.getProducer().send(message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
               System.out.printf("发送结果 %s,body=%s",sendResult.getSendStatus(),sendResult);
            }

            @Override
            public void onException(Throwable e) {
               e.printStackTrace();
               // 补偿机制 根据业务场景看是不是重试机制的
            }
        });
        return new HashMap<>();
    }
}

快速响应不关心结果用的是异步的。

------------------04------------------

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第23张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第24张图片

发送消息的多种场景对比:

异步:比如我们注册用户,注册成功了就返回,在onSuccess回调函数里面去发放和优惠券。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第25张图片

oneWay:例如日志搜集。

 // 如何oneWay的发送消息
        payProducer.getProducer().sendOneway(message);

看下源码:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第26张图片

应用场景:我们点击的淘宝的点击动作回传回服务器。点击淘宝的操作链路,用户的完整行为。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第27张图片

---------------------------05------------------------

延时消息:

我们看下源码:消息被消费的延迟级别。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第28张图片

注意:延时消息是在消息发送时候做的。

  // 如何同步的发送消息
 // SendResult sendResult = payProducer.getProducer().send(message);
// System.out.println(sendResult);

 message.setDelayTimeLevel(2);

应用场景:

1.生日推送。2.订单延时。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第29张图片

--------------------06-----------------

指定队列发送消息。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第30张图片

MessageQueueSelector实战。

为什么这么用?假设有三类订单,要是手机的订单所在的队列满了就会影响家居和运动的订单的消费,所以指定队列。

这个是同步的发送消息。

        // 如何指定队列发送消息
        // 记住一个知识点,最后一个参数是通过传给arg的
        SendResult sendResult = payProducer.getProducer().send(message, new MessageQueueSelector() {
            @Override
            public MessageQueue select(List mqs, Message msg, Object arg) {
                int queneNumber = Integer.parseInt(arg.toString());
                return mqs.get(queneNumber);
            }
        },1);
        System.out.printf("发送结果 %s,body=%s",sendResult.getSendStatus(),sendResult);

修下面演示异步发送的。

 // 如何指定队列发送消息异步发送
        payProducer.getProducer().send(message, new MessageQueueSelector() {
            @Override
            public MessageQueue select(List mqs, Message msg, Object arg) {
                int queneNumber = Integer.parseInt(arg.toString());
                return mqs.get(queneNumber);
            }
        }, 3, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.printf("发送结果 %s,body=%s",sendResult.getSendStatus(),sendResult);
            }

            @Override
            public void onException(Throwable e) {

            }
        });

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第31张图片

第一个可以用lambda表达式,第二个有两个函数不能用lambda表达式的。

异步发送改为lambda表达式的写法。

什么是异步的发送:就是在回调函数返回结果,程序往下进行。

payProducer.getProducer().send(message, new MessageQueueSelector() {
            @Override
            public MessageQueue select(List mqs, Message msg, Object arg) {
                int queneNumber = Integer.parseInt(arg.toString());
                return mqs.get(queneNumber);
            }
        }, 3, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.printf("发送结果 %s,body=%s",sendResult.getSendStatus(),sendResult);
            }

---------------07-------------------

顺序消息在电商应用。

顺序消息不能用异步的!!!!!!!!!!!!!!!!!!!!!

顺序消息是不支持广播的!!!!!!!!!!!!!!!!!!!!

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第32张图片

----08----

代码:

顺序消息的讲解:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第33张图片

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第34张图片

有序消费和并发消费:https://blog.csdn.net/qq_36804701/article/details/81481343

如何做到顺序消费:同一个业务的id放在同一个队列里面。订单号的业务取模放在队列里面。同一个订单号就放在同一个队列里面了。

取模的话肯定不大于这个数。

同一个订单。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第35张图片

-----------------------09-------

原因:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第36张图片

看下官方的例子:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第37张图片

消费:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第38张图片

这个是比较古老的了。

-----------------------10-------

代码:换代码了-02-06模块的。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第39张图片

我们实现一个订单的支付步骤消息投递。

第一步:写生产订单。

 

第二步:发送订单,通过订单的编号去选择进入哪个队列。

@RequestMapping("/api/v2/pay_cb")
    public Object callback() throws Exception {

        List list  = ProductOrder.getOrderList();

        for(int i=0; i< list.size(); i++){
            ProductOrder order = list.get(i);
            Message message = new Message(JmsConfig.ORDERLY_TOPIC,"",
                    order.getOrderId()+"",order.toString().getBytes());

         SendResult sendResult =  payProducer.getProducer().send(message, new MessageQueueSelector() {
                @Override
                public MessageQueue select(List mqs, Message msg, Object arg) {
                    Long id = (Long) arg;
                    long index = id % mqs.size();
                    return mqs.get((int)index);
                }
            },order.getOrderId());


         System.out.printf("发送结果=%s, sendResult=%s ,orderid=%s, type=%s\n", sendResult.getSendStatus(), sendResult.toString(),order.getOrderId(),order.getType());

        }



        return new HashMap<>();
    }

第三步:发送成功

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第40张图片

 

顺序消费的消费者。

代码:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第41张图片

消费者线程池:https://blog.csdn.net/prestigeding/article/details/78885420

第一步:写consumer

1是我们原来用的,现在我们要用到新的2。

第二步:再写consumer

第三步查看消费:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第42张图片

第四步:思考多个consumer怎么办?

topic里面有多个queue,consumer会平均分配queue的数量,consumer是小于queue的。

---------------------------------

多consumer怎么办?

第一步:相同的工程启动两次,换端口号。

架构:

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第43张图片

每个consumer两个queue。

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第44张图片8080的

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第45张图片8081的

第三步:启动三个consumer

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第46张图片

则每个分一个队列。

第四步:总结

大厂五剑客之RocketMQ---6--RocketMQ生产者---二周目_第47张图片

就在这里 和原来的不一样。

-------------------------11-------------------------

你可能感兴趣的:(MQ,XXD)