• 16第四章:【01】普通消息


    一、消息发送分类

    Producer 对于消息的发送方式也有多种选择,不同的方式会产生不同的系统效果。

    1、同步发送消息

    同步发送消息是指,Producer 发出⼀条消息后,会在收到 MQ 返回的 ACK 之后才发下⼀条消息。该方式的消息可靠性最高,但消息发送效率太低。

    2、异步发送消息

    异步发送消息是指,Producer 发出消息后无需等待 MQ 返回 ACK,直接发送下⼀条消息。该方式的消息可靠性可以得到保障,消息发送效率也可以。

    3、单向发送消息

    单向发送消息是指,Producer 仅负责发送消息,不等待、不处理 MQ 的 ACK。该发送方式时 MQ 也不返回 ACK。该方式的消息发送效率最高,但消息可靠性较差。

    二、代码举例

    1、创建工程

    创建一个 Maven 的 Java 工程 rocketmq-test。

    2、导入依赖

    导入 rocketmq 的 client 依赖。

        <properties>
            <project.build.sourceEncoding>UTF-
                8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.apache.rocketmq</groupId>
                <artifactId>rocketmq-client</artifactId>
                <version>4.8.0</version>
            </dependency>
        </dependencies>

    3、定义同步消息发送生产者

     public class SyncProducer {
      public static void main(String[] args) throws Exception {
       // 创建一个producer,参数为Producer Group名称
       DefaultMQProducer producer = new DefaultMQProducer("pg");
       // 指定nameServer地址
       producer.setNamesrvAddr("rocketmqOS:9876");
       // 设置当发送失败时重试发送的次数,默认为2次
       producer.setRetryTimesWhenSendFailed(3);
       // 设置发送超时时限为5s,默认3s
       producer.setSendMsgTimeout(5000);
       // 开启生产者
       producer.start();
       // 生产并发送100条消息
       for (int i = 0; i < 100; i++) {
        byte[] body = ("Hi," + i).getBytes();
        Message msg = new Message("someTopic""someTag", body);
        // 为消息指定key
        msg.setKeys("key-" + i);
        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.println(sendResult);
       }
       //关闭producer
       producer.shutdown();
      }
     }

    消息发送状态:

     // 消息发送的状态
     public enum SendStatus {
      SEND_OK, // 发送成功
      FLUSH_DISK_TIMEOUT, // 刷盘超时。当Broker设置的刷盘策略为同步刷盘时才可能出现这种异常状态。异步刷盘不会出现
      FLUSH_SLAVE_TIMEOUT, // Slave同步超时。当Broker集群设置的Master-Slave的复制方式为同步复制时才可能出现这种异常状态。异步复制不会出现
      SLAVE_NOT_AVAILABLE, // 没有可用的Slave。当Broker集群设置为Master-Slave的复制方式为同步复制时才可能出现这种异常状态。异步复制不会出现
     }

    4、定义异步消息发送生产者

     public class AsyncProducer {
      public static void main(String[] args) throws Exception {
       DefaultMQProducer producer = new DefaultMQProducer("pg");
       producer.setNamesrvAddr("rocketmqOS:9876");
       // 指定异步发送失败后不进行重试发送
       producer.setRetryTimesWhenSendAsyncFailed(0);
       // 指定新创建的Topic的Queue数量为2,默认为4
       producer.setDefaultTopicQueueNums(2);
       producer.start();
       for (int i = 0; i < 100; i++) {
        byte[] body = ("Hi," + i).getBytes();
        try {
         Message msg = new Message("myTopicA""myTag", body);
         // 异步发送。指定回调
         producer.send(msg, new SendCallback() {
          // 当producer接收到MQ发送来的ACK后就会触发该回调方法的执行
          @Override
          public void onSuccess(SendResult sendResult) {
           System.out.println(sendResult);
          }

          @Override
          public void onException(Throwable e) {
           e.printStackTrace();
          }
         });
        } catch (Exception e) {
         e.printStackTrace();
        }
       } // end-for

       // sleep一会儿
       // 由于采用的是异步发送,所以若这里不sleep,
       // 则消息还未发送就会将producer给关闭,报错
       TimeUnit.SECONDS.sleep(3);
       producer.shutdown();
      }
     }

    5、定义单向消息发送生产者

     public class OnewayProducer {
      public static void main(String[] args) throws Exception{
       DefaultMQProducer producer = new DefaultMQProducer("pg");
       producer.setNamesrvAddr("rocketmqOS:9876");
       producer.start();
       for (int i = 0; i < 10; i++) {
        byte[] body = ("Hi," + i).getBytes();
        Message msg = new Message("single""someTag", body);
        // 单向发送
        producer.sendOneway(msg);
       }
       producer.shutdown();
       System.out.println("producer shutdown");
      }
     }

    6、定义消息消费者

     public class SomeConsumer {
      public static void main(String[] args) throws MQClientException {
       // 定义一个pull消费者
       // DefaultLitePullConsumer consumer = new
       DefaultLitePullConsumer("cg");
       // 定义一个push消费者
       DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("cg");
       // 指定nameServer
       consumer.setNamesrvAddr("rocketmqOS:9876");
       // 指定从第一条消息开始消费
       consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
       // 指定消费topic与tag
       consumer.subscribe("someTopic""*");
       // 指定采用“广播模式”进行消费,默认为“集群模式”
       // consumer.setMessageModel(MessageModel.BROADCASTING);
       // 注册消息监听器
       consumer.registerMessageListener(new MessageListenerConcurrently() {
        // 一旦broker中有了其订阅的消息就会触发该方法的执行,
        // 其返回值为当前consumer消费的状态
         @Override
         public ConsumeConcurrentlyStatus
         consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) 
    {
          // 逐条消费消息
          for (MessageExt msg : msgs) {
           System.out.println(msg);
          }
          //返回消费状态:消费成功
          return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
         }
        });

       // 开启消费者消费
       consumer.start();
       System.out.println("Consumer Started");
      }
     }
  • 相关阅读:
    设计手稿: 搜索引擎
    软件版本介绍
    VS2012中使用编译的Qt-5.1.1静态库开发程序
    POJ2236(并查集)
    Java关键字this的用法总结
    paip.提升用户体验-----c++ gcc 命令在notepad++扩展中的配置..
    MySQL基本查询语句练习
    [置顶] 提升代码内外部质量的22条经验
    mysql 数据库复制表 create table city1 like city;
    两个脚本
  • 原文地址:https://www.cnblogs.com/niujifei/p/16564317.html
Copyright © 2020-2023  润新知