rocketmq可通过push与pull方式对消息消费,下面简单介绍下两种方式使用及优缺点。首先引入rocketmq相关jar,并创建生产者
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.9.1</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
public static void main(String[] args) throws MQClientException, InterruptedException {
DefaultMQProducer producer = new DefaultMQProducer("producer_test");
producer.setNamesrvAddr("ip:9876");
producer.setInstanceName(UUID.randomUUID().toString());
producer.start();
for (int i = 0; i < 10; i++) {
try {
Message msg = new Message("TopicTest",
("producetMessage" + i).getBytes(RemotingHelper.DEFAULT_CHARSET)// body
);
SendResult sendResult = producer.send(msg);
System.out.println(sendResult);
} catch (Exception e) {
e.printStackTrace();
}
}
producer.shutdown();
}
push模式
push模式由mq主动将消息推给消费者,可以认为消息是实时处理的,但在push过程中,不会考虑消费者处理能力,当消费者处理能力较弱或处理较慢时会造成消费者缓冲区溢出。push模式代码如下:
public static void main(String[] args) throws InterruptedException, MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_test");
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
consumer.setNamesrvAddr("ip:9876");
consumer.setInstanceName(UUID.randomUUID().toString());
consumer.subscribe("TopicTest", "*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
for (Message msg : msgs) {
System.out.println(new String(msg.getBody()) + " === date:" + new Date());
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
System.out.println("start success");
}
pull模式
pull模式本质为批处理,通过消费者设置固定频率去mq拉取,但在pull过程中不会考虑mq存储能力,频率间隔过大会导致mq消息积压。pull代码如下:
rivate static final Map<MessageQueue, Long> map = new HashMap<MessageQueue, Long>();
public static void main(String[] args) throws MQClientException {
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("consumer_test");
consumer.setNamesrvAddr("ip:9876");
consumer.start();
Set<MessageQueue> mqs = consumer.fetchSubscribeMessageQueues("TopicTest");
for (MessageQueue mq : mqs) {
SINGLE_MQ: while (true) {
try {
Thread.sleep(3000);
PullResult pullResult = consumer.pullBlockIfNotFound(mq, null, getOffset(mq), 1); // 每次取一条消息,同步阻塞拉取
System.out.println(" === offset:" + getOffset(mq) + " === date:" + new Date()
+ " === status:" + pullResult.getPullStatus());
setOffset(mq, pullResult.getNextBeginOffset());
switch (pullResult.getPullStatus()) {
case FOUND:
List<MessageExt> messageExtList = pullResult.getMsgFoundList();
for (MessageExt m : messageExtList) {
System.out.print(new String(m.getBody()));
}
case NO_MATCHED_MSG:
break;
case NO_NEW_MSG:
break SINGLE_MQ;
case OFFSET_ILLEGAL:
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
consumer.shutdown();
}
private static void setOffset(MessageQueue mq, long offset) {
map.put(mq, offset);
}
private static long getOffset(MessageQueue mq) {
Long offset = map.get(mq);
if (offset != null)
return offset;
return 0;
}