RocketMq的介绍
RocketMq是阿里巴巴公司研发的一款消息中间间,虽然它支持的消息类型就只有一种,就是发布/订阅的模式。它是参照rabbitmq实现的,但是RocketMq为我们提供了一个非常重要的一个概念,那就是组。在一个组中我们可以定义多个消费者,生产者,当有多条信息发送过来时,会把信息平均分配给组内的所有成员,感觉就像是天生的负载均衡。但是我们可以通过设置消费者的消息类型,是广播的方式还是集群的方式。
首先我们会先安装RocketMq,
安装RocketMq可以参照我的博文在linux下安装rocketmq
接下来我们开始实现一个简单的消息的发送以及消费者(无序)
下面是生产者的代码
//定义一个生产者,并制定生产者的组名 MyDemo
DefaultMQProducer defaultMQProducer=new DefaultMQProducer("MyDemo");
//设置生成者中有几个队列数
defaultMQProducer.setDefaultTopicQueueNums(1);
//指定nameserver的地址
defaultMQProducer.setNamesrvAddr("47.106.132.60:9876");
//启动生产者
defaultMQProducer.start();
for (int i=0;i<10;i++){
//构建一个Message对象,第一个参数是Topic,
// 第二个参数是tag,标签,可以通过该参数进行选择消息
//第三个参数是消息体
Message message=new Message("MyTop","MyTag",("你好啊,这是第"+(i+1)+"条消息").getBytes());
//使用send发送消息,并返回sendResult,里面包含发送状态,信息Id,信息所在队列,某个Topic.某个Mq,
SendResult sendResult=defaultMQProducer.send(message);
System.out.println(sendResult);
Thread.sleep(1000);
}
//关闭消息生成者
defaultMQProducer.shutdown();
消费者的代码
//指定消费者的组名
DefaultMQPushConsumer consumer=new DefaultMQPushConsumer("MyConsumeDemo");
//设置nameserver的地址
consumer.setNamesrvAddr("47.106.132.60:9876");
//指定从何处开始读取消息
//CONSUME_FROM_FIRST_OFFSET 总是从队列的头部读取消息
//CONSUME_FROM_LAST_OFFSET 总是从队列的最后位置读取消息
//CONSUME_FROM_TIMESTAMP 指定从某个时间开始读取消息
//consumer.setConsumeTimestamp()配合 CONSUME_FROM_TIMESTAMP使用
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
//设置消费者消费信息的模式
//BROADCASTING 广播的方式,就是每个组中的成员都会收到所有的消息
//CLUSTERING 集群的方式,消息会平均的分配到每个组的所有成员,但是组之间还是会获取到所有信息
consumer.setMessageModel(MessageModel.BROADCASTING);
//指定消费者从哪里获取消息
//第一个参数 是指从那个Topic中获取消息
//第二个参数 是指从某个Topic下的某个表现中获取消息,多个使用"|"分割,*代表订阅这个Topic中所有的tag
consumer.subscribe("MyTop","MyTag");
//注册处理消息的事件
consumer.registerMessageListener(new MessageListenerConcurrently() {
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
for (MessageExt messageExt:list){
try {
System.out.println(new String(messageExt.getBody(),"utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//必须返回消息处理的状态
//CONSUME_SUCCESS 处理成功
//RECONSUME_LATER 处理失败或者稍后重试,这可以用来处理消费者的发生异常时信息的处理
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//开始监听
consumer.start();
如何实现消息发送失败的重试
在生产者这边就只需要修改几个地方就可以实现消息的失败重试,
1.1 指定失败重试的次数//指定消息发送失败重试的次数,我们可以通过启动日志可以看到消息重试的时间间隔 defaultMQProducer.setRetryTimesWhenSendFailed(3);
1.2 指定失败后是否使用其他的broker发送消息,默认为 false,
1.3 在发送消息时,我们会指定相应的时间,在多少时间之内失败,会重试defaultMQProducer.send(msg,1000)
在消费者这怎么处理消息失败的问题
2.1 第一种情况 消息没有发送到消费者,Rocketmq内部会自动的重发,重试。
2.2 第二种情况 当我们接受到信息,处理消息的时候发生了异常,我们可以通过返回 ConsumeConcurrentlyStatus.RECONSUME_LATER ;来让消息重发,重新处理。