文档背景
简单学习一下RocketMQ的快速入门
安装
需要安装的话 参考:https://blog.csdn.net/TheLongir/article/details/125409851?spm=1001.2014.3001.5501
预览: http://edu.thelongi.cn:8082/ (占内存,已经被停掉了)
- Producer
- 消息生产者,负责产生消息,一般由业务系统负责产生消息。
- Producer Group
- 一类 Producer 的集合名称,这类 Producer 通常发送一类消息,且发送逻辑一致。
- Consumer
- 消息费者,负责消费消息,一般是后台系统负责异步消费。
- Push Consumer
- 服务端向消费者端推送消息
- Pull Consumer
- 消费者端向服务定时拉取消息
- Consumer Group
- 一类 Consumer 的集合名称,这类 Consumer 通常消费一类消息,且消费逻辑一致。
- NameServer
- 集群架构中的组织协调员
- 收集broker的工作情况
- 不负责消息的处理
- Broker
- 是RocketMQ的核心负责消息的发送、接收、高可用等(真正干活的)
- 需要定时发送自身情况到NameServer,默认10秒发送一次,超时2分钟会认为该broker失效。
- Topic
- 不同类型的消息以不同的Topic名称进行区分,如User、Order等
- 是逻辑概念
- Message Queue
- 消息队列,用于存储消息
其实很好理解,nameserver是负责调度而不参与消息处理的。也就是说,事实上的流程是生产者将message定好topic,贴上tag,打好包发送给broker。broker根据逻辑去排序和处理,然后放在对应的topic的队列中。如果当中由消费者订阅了broker的这个topic那么则根据consumer的逻辑处理message。该message可以是同步也可以使异步。
代码中的常量 比如 Rocket的地址我都是用的自定义常量来代替。注意替换成你们定义的常量即可
topic由生产者创建,于broker管理
package cn.itcast.rocketmq.topic;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
public class TopicDemo {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer(RocketMqConst.PRODUCER_GROUP);
//设置nameserver的地址
producer.setNamesrvAddr(RocketMqConst.ADDR);
// 启动生产者
producer.start();
/**
* 创建topic,参数分别是:broker的名称,topic的名称,queue的数量
*
*/
producer.createTopic(RocketMqConst.BROKER_NAME, "my-topic", 8);
System.out.println("topic创建成功!");
producer.shutdown();
}
}
异步消息
package cn.itcast.rocketmq.sendmsg;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
public class AsyncProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer(RocketMqConst.PRODUCER_GROUP);
producer.setNamesrvAddr(RocketMqConst.ADDR);
producer.start();
// 发送消息
String msg = "我的第一个异步发送消息!";
Message message = new Message("my-topic", msg.getBytes("UTF-8"));
producer.send(message, new SendCallback() {
public void onSuccess(SendResult sendResult) {
System.out.println("发送成功了!" + sendResult);
System.out.println("消息id:" + sendResult.getMsgId());
System.out.println("消息队列:" + sendResult.getMessageQueue());
System.out.println("消息offset值:" + sendResult.getQueueOffset());
}
public void onException(Throwable e) {
System.out.println("消息发送失败!" + e);
}
});
// producer.shutdown();
}
}
同步消息
package cn.itcast.rocketmq.sendmsg;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
public class SyncProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer(RocketMqConst.PRODUCER_GROUP);
producer.setNamesrvAddr(RocketMqConst.ADDR);
producer.start();
//发送消息
String msg = "我的第一个消息!";
Message message = new Message(RocketMqConst.MY_TOPIC, "delete", msg.getBytes("UTF-8"));
SendResult sendResult = producer.send(message);
System.out.println("消息id:" + sendResult.getMsgId());
System.out.println("消息队列:" + sendResult.getMessageQueue());
System.out.println("消息offset值:" + sendResult.getQueueOffset());
System.out.println(sendResult);
producer.shutdown();
}
}
Consumer
package cn.itcast.rocketmq.order;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.message.MessageExt;
import java.io.UnsupportedEncodingException;
import java.util.List;
public class OrderConsumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(RocketMqConst.ORDER_CONSUMER);
consumer.setNamesrvAddr(RocketMqConst.ADDR);
consumer.subscribe(RocketMqConst.MY_TOPIC_ORDER, "*");
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
try {
System.out.println(Thread.currentThread().getName() + " "
+ msg.getQueueId() + " "
+ new String(msg.getBody(),"UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs);
return ConsumeOrderlyStatus.SUCCESS;
}
});
consumer.start();
}
}
Producer
package cn.itcast.rocketmq.order;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
public class OrderProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer(RocketMqConst.ORDER_PRODUCER);
producer.setNamesrvAddr(RocketMqConst.ADDR);
producer.start();
for (int i = 0; i < 100; i++) {
int orderId = i % 10; // 模拟生成订单id
String msgStr = "order --> " + i +", id = "+ orderId;
Message message = new Message(RocketMqConst.MY_TOPIC_ORDER, "ORDER_MSG",
msgStr.getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = producer.send(message, (mqs, msg, arg) -> {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}, orderId);
System.out.println(sendResult);
}
producer.shutdown();
}
}
如果consumer启动报错,说该broker无法添加filter规则。
解决方法: 在broker.conf中添加enablePropertyFilter=true
Consumer
package cn.itcast.rocketmq.filter;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.MessageSelector;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import java.io.UnsupportedEncodingException;
import java.util.List;
public class ConsumerFilter {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(RocketMqConst.CONSUMER_GROUP);
consumer.setNamesrvAddr(RocketMqConst.ADDR);
// 订阅消息,接收的是所有消息
//consumer.subscribe(RocketMqConst.MY_TOPIC_FILTER, "*");
//consumer.subscribe("my-topic-filter", MessageSelector.bySql("sex='女' AND age>=18"));
consumer.subscribe("my-topic-filter", MessageSelector.bySql("sex='男' AND age=20"));
consumer.registerMessageListener(new MessageListenerConcurrently() {
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
try {
for (MessageExt msg : msgs) {
System.out.println("消息:" + new String(msg.getBody(), "UTF-8"));
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("接收到消息 -> " + msgs);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者
consumer.start();
}
}
Producer
package cn.itcast.rocketmq.filter;
import cn.itcast.rocketmq.config.RocketMqConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
public class SyncProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer(RocketMqConst.PRODUCER_GROUP);
producer.setNamesrvAddr(RocketMqConst.ADDR);
producer.start();
//发送消息
String msg = "这是一个用户的消息, id = 1003";
Message message = new Message(RocketMqConst.MY_TOPIC_FILTER, "delete", msg.getBytes("UTF-8"));
message.putUserProperty("sex","男");
message.putUserProperty("age","20");
SendResult sendResult = producer.send(message);
System.out.println("消息id:" + sendResult.getMsgId());
System.out.println("消息队列:" + sendResult.getMessageQueue());
System.out.println("消息offset值:" + sendResult.getQueueOffset());
System.out.println(sendResult);
producer.shutdown();
}
}