RocketMq 顺序消费、分区消息、延迟发送消息、Topic、tag分类 实战 (生产者) (二)

本文介绍了如何在SpringBoot项目中配置RocketMQ的生产者端,包括设置访问密钥、秘密密钥、TCP接入地址、主题和分组ID等,并展示了如何使用`brOrderProducer`Bean发送顺序消息,以及shardingKey在消息分区中的应用。

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

1、生产者端配置

@Configuration
public class OrderProducerClient {

    @Autowired
    private RocketMqDcProperties rocketMqDcProperties;

    @Bean(name = "brOrderProducer", initMethod = "start", destroyMethod = "shutdown")
    public OrderProducerBean brOrderProducer() {
        OrderProducerBean orderProducerBean = new OrderProducerBean();
        orderProducerBean.setProperties(rocketMqDcProperties.getProducerProperties());
        return orderProducerBean;
    }
}

这是RocketMq生产者的配置类,OrderProducerBean是顺序生产者的对象,@Bean注解的作用是把RocketMq相关的配置set到OrderProducerBean对象中去,并把这个对象注入到Spring容器当中,对象名称是brOrderProducer(注意这个对象名称在下面发送消息要用到)

@ConfigurationProperties(prefix = "rocket.mq.dc")
@Configuration
@Data
public class RocketMqDcProperties {

    /**
     * 阿里云身份验证AccessKey ID,在阿里云用户信息管理控制台获取。
     */
    @Valid
    private String accessKey;

    /**
     * 阿里云身份验证AccessKey Secret,在阿里云用户信息管理控制台获取。
     */
    @Valid
    private String secretKey;

    /**
     * 设置TCP接入域名,进入控制台的实例详情页面的TCP协议客户端接入点区域查看。
     */
    @Valid
    private String nameSrvAddr;

    /**
     * 顺序消息类型的topic
     */
    @Valid
    private String orderTopic;

    /**
     * TCP协议下创建的
     * 您在控制台创建的Group ID,用于对消费者或生产者实例进行分类。
     */
    private String orderGroupId;

    /**
     * TCP协议下创建的
     * 您在控制台创建的Group ID,用于对消费者或生产者实例进行分类。
     */
    private String policyChangeGroupId;

    /**
     * TCP协议下创建的
     * 您在控制台创建的Group ID,用于对消费者或生产者实例进行分类。
     */
    private String xbsPolicyChangeGroupId;

    /**
     * TCP协议下创建的
     * 您在控制台创建的Group ID,用于对消费者或生产者实例进行分类。
     */
    private String eventGroupId;
    
	/**
     * TCP协议下创建的
     * 您在控制台创建的Group ID,用于对消费者或生产者实例进行分类。
     */
    private String targetGroupId;

    /**
     * 设置Consumer实例的消费线程数,默认值:20。
     */
    private Integer consumeThreadNums = 20;

    /**
     * 设置消息消费失败的最大重试次数,默认值:16。
     */
    private Integer maxReconsumeTimes = 16;

    /**
     * 设置每条消息消费的最大超时时间,超过设置时间则被视为消费失败,等下次重新投递再次消费。每个业务需要设置一个合理的值,默认值:15,单位:分钟。
     */
    private Integer consumeTimeout = 5;

    /**
     * 只适用于顺序消息,设置消息消费失败的重试间隔时间(毫秒)。
     */
    private Integer suspendTimeMillis = 30000;

    /**
     * 是否开启消息处理(默认开户)
     */
    private boolean enabled = true;

    /**
     * 事件MQ配置
     */
    public Properties getEventProperties() {
        return getProperties(this.eventGroupId);
    }

    /**
     * 指标MQ配置
     */
    public Properties getTargetProperties() {
        return getProperties(this.targetGroupId);
    }

    /**
     * 保单MQ配置
     */
    public Properties getPolicyChangeProperties() {
        return getProperties(this.policyChangeGroupId);
    }
    /**
     * 旧的渠道指标的公用配置
     */
    public Properties getProperties() {
        return  getProperties(this.orderGroupId);
    }
        /**
     * MQ配置
     */
    private Properties getProperties(String groupId) {
        Properties properties = new Properties();
        properties.setProperty(PropertyKeyConst.AccessKey, this.accessKey);
        properties.setProperty(PropertyKeyConst.SecretKey, this.secretKey);
        properties.setProperty(PropertyKeyConst.NAMESRV_ADDR, this.nameSrvAddr);
        properties.setProperty(PropertyKeyConst.GROUP_ID, groupId);
        properties.setProperty(PropertyKeyConst.ConsumeThreadNums, this.getConsumeThreadNums().toString());
        properties.setProperty(PropertyKeyConst.MaxReconsumeTimes, this.getMaxReconsumeTimes().toString());
        properties.setProperty(PropertyKeyConst.ConsumeTimeout, this.getConsumeTimeout().toString());
        properties.setProperty(PropertyKeyConst.SuspendTimeMillis, this.getSuspendTimeMillis().toString());
        return properties;
    }
        /**
     * 生产者公用配置
     */
    public Properties getProducerProperties() {
        Properties properties = new Properties();
        properties.setProperty(PropertyKeyConst.AccessKey, this.accessKey);
        properties.setProperty(PropertyKeyConst.SecretKey, this.secretKey);
        properties.setProperty(PropertyKeyConst.NAMESRV_ADDR, this.nameSrvAddr);
        return  properties;
    }

RocketMqDcProperties 这个类是RocketMq相关属性的配置类

发送消息,如下代码可以看到我们在这里用到了brOrderProducer这个Bean对象

	
    @Autowired
    private OrderProducerBean brOrderProducer;

    private void sendEventMQMessage(EventEnum event, Object body){

        String shardingKey = event.name();
        // 发送消息,只要不抛异常就是成功
        try {
            Message msg = new Message(
                    // Message所属的Topic
                    rocketMqDcProperties.getOrderTopic(),
                    // Message Tag 可理解为Gmail中的标签,对消息进行再归类,方便Consumer指定过滤条件在MQ服务器过滤
                    MqTagEnum.event.name(),
                    // Message Body 可以是任何二进制形式的数据, MQ不做任何干预
                    // 需要Producer与Consumer协商好一致的序列化和反序列化方式
                    //SerializeUtil.serialization(body)
                    JsonLUtils.toJSon(body).getBytes()
            );
            SendResult sendResult = brOrderProducer.send(msg, shardingKey);
            assert sendResult != null;
            log.info("event消息发送成功,topic = {},key = {},messageId = {}", sendResult.getTopic(), shardingKey, sendResult.getMessageId());
        } catch (ONSClientException e) {
            //日志记录错误信息与入参信息
            log.error("event消息发送失败,异常信息:", e);
            throw e;
        }
    }           

在这里我们可以看一下Message的构造方法,也就是说我封装一个消息对象,需要以下几个参数,Topic,Tags,还有消息体

public Message(String topic, String tags, byte[] body) {
        this(topic, tags, "", body);
    }

同时我们也可以看一下brOrderProducer.send() 方法的参数,首先必须要有Message对象,其次我这个是顺序消息,所以有对消息进行分区,shardingKey就是指定一个分区。

public SendResult send(Message message, String shardingKey) {
        return this.orderProducer.send(message, shardingKey);
    }

其次我们可以看下我这个shardingKey是怎么定义的,因为我们是通过事件上报来调用mq,所以我们定义了一个事件枚举,每个上报的事件类型就是一种shardingKey,如下,我只截取部门事件。

public enum EventEnum {

    /**
     * 投放页浏览
     */
    visit("投放页浏览",
            Lists.newArrayList(
                    TargetTypeEnum.pv,
                    TargetTypeEnum.uv
            )
    ),

    /**
     * 关注公众号
     */
    subscribe("关注公众号",
            Lists.newArrayList(
                    TargetTypeEnum.subscribe
            )
    ),

    /**
     * 取关公众号
     */
    unsubscribe("取关公众号",
            Lists.newArrayList(
                    TargetTypeEnum.unsubscribe
            )
    ),

    /**
     * 申请服务
     */
    register("申请服务",
            Lists.newArrayList(
                    TargetTypeEnum.register
            )
    ),

    /**
     * 保单托管
     */
    pm_confirm("保单托管",
            Lists.newArrayList(
                    TargetTypeEnum.pm,
                    TargetTypeEnum.pm_dac_t,
                    TargetTypeEnum.pm_dac_e,
                    TargetTypeEnum.pm_dac_es,
                    TargetTypeEnum.pm_dac,
                    TargetTypeEnum.pm_dac_k,
                    TargetTypeEnum.pm_dac_y
            )
    ),
    agent_offline(
            "顾问请假",
            Lists.newArrayList((
                            TargetTypeEnum.offline_time
                    )
            )),    
    sv_deal(
            "客户服务单成交",
            Lists.newArrayList(
                    TargetTypeEnum.sv_deal_cycle
            )
    );
        /**
     * 描述
     */
    public final String desc;

    /**
     * 对应指标类型
     */
    public final List<TargetTypeEnum> targetTypeList;


    EventEnum(String desc, List<TargetTypeEnum> targetTypeList) {
        this.desc = desc;
        this.targetTypeList = targetTypeList;
    }  
 }           

至此,我们生产者端配置完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值