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

生产者的核心配置。

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

3.最大消息的大小

4.主题下队列的数量

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

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

10.Broker的服务地址

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

14.broker的监听端口

15.消息的存储地址

16.queue的消息条数

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

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

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

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

第二点:

演示:

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

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

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

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

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

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

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

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

很重要的:

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

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

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

代码

// 生产者的重试次数
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<>();
    }

生产者不要过多的关注。

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

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

一般3-4次。

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

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

第二步:改造代码

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

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

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

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

第一步:

第二步:

改为集群模式:

集群式不支持重试的!!!!!!!!!!!!!!!!!!!!

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

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

异步发送消息式不支持重试的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

代码:02

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

发送异步的消息。

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

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

        // 如何异步的发送消息?
        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-----------------------------------------------------------------------------------

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

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

oneWay:例如日志搜集。

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

看下源码:

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

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

延时消息:

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

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

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

 message.setDelayTimeLevel(2);

应用场景:

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

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

MessageQueueSelector实战。

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

这个是同步的发送消息。

        // 如何指定队列发送消息
        // 记住一个知识点,最后一个参数是通过传给arg的
        SendResult sendResult = payProducer.getProducer().send(message, new MessageQueueSelector() {
            @Override
            public MessageQueue select(List<MessageQueue> 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);

修下面演示异步发送的。

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

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

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

payProducer.getProducer().send(message, new MessageQueueSelector() {
            @Override
            public MessageQueue select(List<MessageQueue> 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-----------------------------------------------------------------------------------

顺序消息在电商应用。

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

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

-----------------------------------------------------------------------08-----------------------------------------------------------------------------------

顺序消息的讲解:

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

同一个订单。

看下官方的例子:

消费:

这个式比较古老的了。

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

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

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

第一步:写生产订单。

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

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

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

第三步:发送成功

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

顺序消费的消费者。

代码:

第一步:写consumer

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

第二步:再写consumer

第三步查看消费:

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

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

-----

多consumer怎么办?

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

架构:

每个consumer两个queue。

8080的

8081的

第三步:启动三个consumer

则每个分一个队列。

第四步:总结

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

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

发布了308 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_28764557/article/details/104272673