消息队列 RocketMQ - 收发定时消息

消息队列RocketMQ是什么?

消息队列 RocketMQ 版是阿里云基于 Apache RocketMQ 构建的低延迟、高并发、高可用、高可靠的分布式消息中间件。消息队列 RocketMQ 版既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性。

核心概念
  • Topic:消息主题,一级消息类型,生产者向其发送消息。
  • 生产者:也称为消息发布者,负责生产并发送消息至 Topic。
  • 消费者:也称为消息订阅者,负责从 Topic 接收并消费消息。
  • 消息:生产者向 Topic 发送并最终传送给消费者的数据和(可选)属性的组合。
  • 消息属性:生产者可以为消息定义的属性,包含 Message Key 和 Tag。
  • Group:一类生产者或消费者,这类生产者或消费者通常生产或消费同一类消息,且消息发布或订阅的逻辑一致。

订阅关系一致

由于消息队列 RocketMQ 版的订阅关系主要由 Topic + Tag 共同组成。
因此,保持订阅关系一致意味着同一个消费者 Group ID 下所有的实例需在以下两方面均保持一致。
- 订阅的 Topic 必须一致
- 订阅的 Topic 中的 Tag 必须一致
正确订阅关系图

多个Group ID订阅了多个topic,并且每个Group ID里的多个消费者实例的订阅关系保持了一致。在这里插入图片描述

错误订阅关系图

单个Group ID订阅了多个Topic,但是该Group ID里的多个消费者实例的订阅关系并没有保持一致。
单个

使用RocketMQ编写的一个定时消息

生产者

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;

import lombok.extern.slf4j.Slf4j;
import com.aliyun.openservices.ons.api.SendResult;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Properties;

@Slf4j
public class ProducerTest {
    public static void main(String[] args) {
        Properties properties = new Properties();
        // 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.AccessKey, "XXX");
        // 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.SecretKey, "XXX");
        // 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看
        properties.put(PropertyKeyConst.NAMESRV_ADDR, "XXX");
        Producer producer = ONSFactory.createProducer(properties);
        // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可。
        producer.start();
        Message msg = new Message(
                // Message 所属的 Topic
                "Topic",
                // Message Tag 可理解为 Gmail 中的标签,对消息进行再归类,方便 Consumer 指定过滤条件在消息队列 RocketMQ 版的服务器过滤
                "tag",
                // Message Body 可以是任何二进制形式的数据,消息队列 RocketMQ 版不做任何干预,需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
                "market".getBytes());
      
        try {
            // 定时消息,单位毫秒(ms),在指定时间戳(当前时间之后)进行投递,例如 2020-4-10 00:00:00 投递。如果被设置成当前时间戳之前的某个时刻,消息将立刻投递给消费者。
            long timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2020-4-8 00:00:00").getTime();
            msg.setStartDeliverTime(timeStamp);
             // 设置代表消息的业务关键属性,请尽可能全局唯一
        // 以方便您在无法正常收到消息情况下,可通过控制台查询消息并补发。
        // 注意:不设置也不会影响消息正常收发
            msg.setKey("market");
            // 发送消息,只要不抛异常就是成功
            SendResult sendResult = producer.send(msg);
            log.info("Message Id:{}" , sendResult.getMessageId());
        }
        catch (Exception e) {
            // 消息发送失败,需要进行重试处理,可重新发送这条消息或持久化这条数据进行补偿处理
            log.info("Send mq message failed.Topic is={} ,ex={}", msg.getTopic(), e.toString());
            e.printStackTrace();
        }
        // 在应用退出前,销毁 Producer 对象
        // 注意:如果不销毁也没有问题
        producer.shutdown();
    }
}       

消费者

import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Consumer;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;

import lombok.extern.slf4j.Slf4j;
import java.util.Properties;

@Slf4j
public class ConsumerTest {
   public static void main(String[] args) {
       Properties properties = new Properties();
        // 您在控制台创建的 Group ID
       properties.put(PropertyKeyConst.GROUP_ID, "XXX");
        // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
       properties.put(PropertyKeyConst.AccessKey, "XXX");
        // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
       properties.put(PropertyKeyConst.SecretKey, "XXX");
        // 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看
       properties.put(PropertyKeyConst.NAMESRV_ADDR,
         "XXX");
          // 集群订阅方式 (默认)
          // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING);
          // 广播订阅方式
          // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING);

       Consumer consumer = ONSFactory.createConsumer(properties);
       consumer.subscribe("TopicTestMQ", "TagA||TagB", new MessageListener() { //订阅多个 Tag
           public Action consume(Message message, ConsumeContext context) {  //定时消息 接收
               // 对定时消息的处理
               ......
               log.info("定时消息执行完毕.. topic:{}, msgId:{}", message.getTopic(),message.getMsgID());
               return Action.CommitMessage;
           }
       });

       consumer.start();
       System.out.println("Consumer Started");
   }
}            

如有不懂,请参考官方文档:https://help.aliyun.com/product/29530.html?spm=a2c4g.11186623.6.540.661b3002Tuf6np

发布了2 篇原创文章 · 获赞 6 · 访问量 208

猜你喜欢

转载自blog.csdn.net/EveryOneBye/article/details/105390627