1.导入jar包:
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>ons-client</artifactId>
<version>${ali.ons-client.version}</version>
</dependency>
2.初始化消费者:
@Slf4j
@Component
public class MedalsCardsRktMqInits {
@Autowired
private MedalsCardsRktMqConfig rktMQConfig;
@Autowired
private MedalsCardsRktMqMsgListener rktMQMsgListener;
private Consumer consumer;
@Autowired
private Environment environment;
private static String[] demoEnvironment = {"dev","demo","load"};
@PostConstruct
public void initConsumer(){
log.info("desc:{}", "rocketmq consumer starting");
Properties pro = new Properties();
pro.put(PropertyKeyConst.AccessKey,rktMQConfig.getAccessKey());
pro.put(PropertyKeyConst.SecretKey,rktMQConfig.getSecretKey());
pro.put(PropertyKeyConst.ONSAddr,rktMQConfig.getOnsaddr());
pro.put(PropertyKeyConst.GROUP_ID,rktMQConfig.getGroupId());
pro.put(PropertyKeyConst.ConsumeThreadNums,10);
//默认是集群模式消费
pro.put(PropertyKeyConst.MessageModel, MessageModel.CLUSTERING);
//如果是测试环境设置成广播模式消费
Arrays.asList(demoEnvironment).forEach(demo->{
if(Arrays.asList(environment.getActiveProfiles()).contains(demo)){
pro.put(PropertyKeyConst.MessageModel, MessageModel.BROADCASTING);
}
});
log.info("desc:{},当前环境:{},设置的消息模式是:{}","rocketmq consumer 设置消息消费模式",
JSONObject.toJSONString(environment.getActiveProfiles()),pro.get(PropertyKeyConst.MessageModel));
consumer = ONSFactory.createConsumer(pro);
//自定义自己需要订阅TAG
List<String> subscribeTags = new ArrayList<>();
subscribeTags.add(CommonConstant.MEDALS_CARDS_TAG);
subscribeTags.add(CommonConstant.MEDALS_CARDS_REWARD_TAG);
consumer.subscribe(rktMQConfig.getConsumerTopics(),String.join(" || ",subscribeTags),rktMQMsgListener);
consumer.start();
log.info("desc:{}", "rocketmq consumer started");
}
@PreDestroy
public void destroyConsumer() {
consumer.shutdown();
}
}
其中MedalsCardsRktMqConfig是配置文件:
@Data
@Configuration
public class MedalsCardsRktMqConfig {
@Value("${aliyun.rocketmq.ONSAddr}")
private String onsaddr;
@Value("${aliyun.rocketmq.AccessKey}")
private String accessKey;
@Value("${aliyun.rocketmq.SecretKey}")
private String secretKey;
@Value("${aliyun.rocketmq.GroupId}")
private String groupId;
@Value("${aliyun.rocketmq.consumer.Topic}")
private String consumerTopics;
}
rktMQMsgListener 是要监听的消费者
@Slf4j
@Component
public class MedalsCardsRktMqMsgListener implements MessageListener {
@Autowired
private MedalCardService medalCardService;
@Override
public Action consume(Message message, ConsumeContext consumeContext) {
String uuid= UUID.randomUUID().toString().replaceAll("-","");
log.info("uuid:{},desc:{},params:{}",
uuid,"RocketMQ消费消息",JSONObject.toJSONString(message));
try {
//消费消息tag
String messageTag = message.getTag();
String messageBody = new String(message.getBody());
//处理勋章卡牌业务消息
if(CommonConstant.MEDALS_CARDS_TAG.equals(messageTag)){
UserMedalCardTaskMessage taskMessage = JSONObject.parseObject(messageBody, UserMedalCardTaskMessage.class);
taskMessage.setUuid(uuid);
log.info("uuid:{},desc:{},param:{}",uuid,"勋章卡牌业务消息消费",messageBody);
MedalsCardsContext medalsCardsContext = new MedalsCardsContext(taskMessage);
medalsCardsContext.handlerEvent();
}
//勋章卡牌获取金币
if(CommonConstant.MEDALS_CARDS_REWARD_TAG.equals(messageTag)){
AccountPO accountPO = JSONObject.parseObject(messageBody,AccountPO.class);
medalCardService.addUserGoldAndPoint(accountPO);
}
// 确认消息已经消费
log.info("uuid:{},desc:{},param:{}",uuid,"RocketMQ消费消息消费完成",messageTag);
return Action.CommitMessage;
}catch (Exception e){
log.error("uuid:{},desc:{},message:{}",uuid,"RocketMQ消费消息-异常",e);
// 稍后重新消费
return Action.ReconsumeLater;
}
}
}
这样当消息到来时就可以被监听并消费掉了。
待确认问题:
1.rocketmq怎么确认消息已经被消费了的,以及失败时如何重试
请参看:http://ju.outofmemory.cn/entry/343946
2.rocketmq消息消费模式广播消费和集群消费的区别是什么?
集群消费模式时,消息只能被消费组内的某一台机器消费,但可以被不同消费组内的不同机器消费;
广播消费模式时,消息会被消费组内的所有机器消费。