相关概念:
RocketMQ的作用:不同应用间通信、流量削峰等
RocketMQ相关概念说明:
生产者:生产消息
生产组:相同生产组保持相同的业务行为(从找到的资料来看,同组内一个生产者宕机后,其它生产者会接替该生产者的任务)
消费者:消费消息
消费组:在同一个消费组内,消息不会被重复消费;对于不同消费组,各个消费组之间互不影响,即同一个消息会被不同消费组分别消费
Topic:区分消息队列的标识
Tag:对Topic进一步细分的标识
Message:MQ中的消息
RocketMQ的使用:
Producer和Consumer的初始化:
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
@Component
public class RocketMqFactory {
private DefaultMQProducer producer;
// DefaultMQPushConsumer和DefaultMQPullConsumer的区别是:push由RocketMQ服务器主动下发消息给消费者,而pull是由消费者自己去拉取RocketMQ的消息
private DefaultMQPushConsumer consumer;
@Autowired
private RocketMqConfiguration configuration;
@PostConstruct
private void initConsumer() {
consumer = new DefaultMQPushConsumer();
consumer.setNamesrvAddr(configuration.getMqAddr());
consumer.setConsumerGroup(configuration.getConsumerGroup());
}
@PostConstruct
private void initProducer() {
producer = new DefaultMQProducer();
producer.setNamesrvAddr(configuration.getMqAddr());
producer.setProducerGroup(configuration.getProducerGroup());
try {
// 在发送消息前启动Producer
producer.start();
log.info("producer start success. Start time:{}", new SimpleDateFormat().format(new Date()));
} catch (MQClientException e) {
log.error("start producer failed.", e.getErrorMessage());
}
}
public void sendMsg(String topic, String tag, String msg) {
Message message = new Message(topic, tag, msg.getBytes());
try {
producer.send(message);
} catch (Exception e) {
log.error("send message failed.", e.getMessage());
}
}
public DefaultMQPushConsumer getConsumer(String topic, String tag) {
try {
consumer.subscribe(topic, tag);
} catch (MQClientException e) {
log.error("subscribe fail. topic:{}, tag:{}, errorMsg:{}", topic, tag, e.getErrorMessage());
}
return consumer;
}
}
发送消息:
producer.sendMsg(topic, tag, msg);
消费消息:
由于消费者是被动接受RocketMQ推送的消息,所以需要随着项目的启动而启动
@PostConstruct
private void listenMessage() {
DefaultMQPushConsumer mqConsumer = mq.getConsumer(topic, tag);
mqConsumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
if (list == null || list.isEmpty()) {
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
MessageExt ext = list.get(0);
if (ext == null || ext.getBody() == null || ext.getBody().length == 0) {
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
// todo 消费消息;
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
try {
mqConsumer.start();
} catch (MQClientException e) {
log.error("Consumer start fail. Message:{}", e.getErrorMessage());
}
}