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;
}
}
至此,我们生产者端配置完成。