1 单生产者单消费者消息发送
1.1 新建maven项目
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.9.0</version>
</dependency>
1.2 生产者
public class Producer {
public static void main(String[] args) throws Exception {
// 谁来发
DefaultMQProducer producer = new DefaultMQProducer("group1");
// 发给谁
producer.setNamesrvAddr("localhost:9876");
producer.start();
// 消息主体
Message msg = new Message("topic1", "hello rocketmq".getBytes("UTF-8"));
// 获取结果
SendResult result = producer.send(msg);
System.out.println("返回结果:" + result);
// 关闭连接
producer.shutdown();
}
}
1.3 消费者
public class Consumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
consumer.setNamesrvAddr("localhost:9876");
//3.设置接收消息对应的topic,对应的sub标签为任意
consumer.subscribe("topic1","*");
//3.开启监听,用于接收消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
//遍历消息
for (MessageExt msg : list) {
System.out.println("收到消息:"+msg);
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
System.out.println("接受消息服务已经开启!");
}
}
2 单生产者多消费者消息发送
单生产者产生的消息可以被同一个消费者消费,也可以被多个消费者消费
生产者发送十条消息
for (int i = 0; i < 10; i++) {
String message = "hello rocketmq" + i;
Message msg = new Message("topic2", message.getBytes("UTF-8"));
// 获取结果
SendResult result = producer.send(msg);
System.out.println("返回结果:" + result);
}
消费者消费消息
允许多次启动
启动两个消费者,这个时候会出现每个消费者收到五个消息。(负载均衡模式:默认模式)
要想让生产者生产的消息每个消费者都全部获取,可以将负载均衡模式改为广播模式或
通过修改组名,每个消费者组名不同就可以全部获取
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
即集群模式下,同个主题对于不同组是“广播模式”,每个组都会消费同个消息;会重复消费;对于同个组是“集群模式”,每个消费者平坦消息,不会重复消费;
思考: Consumerl、2同组就要都收到全部10条消息?
消费模式默认是MessageModel.CLUSTERING
现在我把它设置为 BROADCASTING
模式
consumer.setMessageModel(MessageModel.BROADCASTING);
3 消息类别
3.1 同步消息
一条消息发送并且接收到返回消息后才发送下一条消息,常用于类似于邮件发送、短信发送的场景
特征:即时性较强,重要的消息,且必须有回执的消息,例如短信,通知(转账成功)
3.2 异步消息
特征:即时性较弱,但需要有回执的消息,例如订单中的某些信息
下面是生产者异步发送的代码,producer.send(msg, sendCallback()) 是异步的,下面代码会先打印异步发送完成,再打印消息结果。因此之前写的producer.shutdown();
要删掉,不然会先执行producer.shutdown();
再执行异步方法,导致没有producer。
for (int i = 0; i < 10; i++) {
String message = "hello rocketmq + 异步" + i;
Message msg = new Message("topic3", message.getBytes("UTF-8"));
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println(sendResult);
}
@Override
public void onException(Throwable throwable) {
// 业务逻辑
System.out.println(throwable);
}
});
System.out.println("异步发送完成");
}
3.3 单向消息
特征:不需要有回执的消息,例如日志类消息
producer.sendOneway(message);
3.3 延时消息
特征:消息发送时并不直接发送到消息服务器,而是根据设定的等待时间到达,起到延时到达的缓冲作用
可以给每个消息设置延时
// 设置延迟时间为等级3
msg.setDelayTimeLevel(3);
SendResult sendResult = producer.send(msg);
目前支持的延时类型有:
3.4 批量消息
特征:一次发送多条消息,节约网络开销
生产者发送一次消息就要和nameServer建立连接,和broker建立连接,在真实环境中每秒可以发几万甚至几十万的消息,会造成连接过多系统性能下降。而批量发送就可以集中一次发送。
String msg = "hello rocketmq producer batch";
List<Message> messageList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
Message message = new Message("topic4", msg.getBytes(StandardCharsets.UTF_8));
messageList.add(message);
}
producer.send(messageList);
4 消息过滤
4.1 tag 过滤
4.2 sql过滤
使用 SQL 过滤, 需要在broker.conf文件中添加配置enablePropertyFilter=true
在生产者中追加属性
Message msg = new Message("topic6", "tag3","hello rocketmq".getBytes("UTF-8"));
// 给消息追加属性
msg.putUserProperty("name", "zhangsan");
msg.putUserProperty("age", "12");
在消费者过滤
consumer.subscribe("topic6", MessageSelector.bySql("age > 16"));
5 SpringBoot整合RocketMQ
5.1 项目搭建
5.1.1 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
5.1.3 producer 服务搭建
yml文件
rocketmq:
name-server: localhost:9876
producer:
group: group1
server:
port: 8088
实现
@Autowired
private RocketMQTemplate rocketMQTemplate;
@GetMapping("send")
public String send() {
User user = new User("cc", 19);
rocketMQTemplate.convertAndSend("topic10", user);
return "success";
}
5.1.3 consumer 服务搭建
yml文件
server:
port: 8089
rocketmq:
name-server: localhost:9876
producer:
group: group1
servie监听
@Service
@RocketMQMessageListener(topic = "topic10", consumerGroup = "group1")
public class ConsumerService implements RocketMQListener<User> {
@Override
public void onMessage(User user) {
System.out.println(user);
}
}
5.2 其他功能
5.2.1 消息类别
@GetMapping("send")
public String send() {
User user = new User("cc", 19);
rocketMQTemplate.convertAndSend("topic10", user);
return "success";
}
@GetMapping("syncSend")
public String syncSend() {
User user = new User("cc", 19);
SendResult result = rocketMQTemplate.syncSend("topic10", user);
return "同步发送成功";
}
@GetMapping("asyncSend")
public String asyncSend() {
User user = new User("cc", 19);
rocketMQTemplate.asyncSend("topic10", user, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println(sendResult);
}
@Override
public void onException(Throwable throwable) {
System.out.println(throwable);
}
}, 1000);
return "异步发送成功";
}
@GetMapping("sendOneWay")
public String sendOneWay() {
User user = new User("cc", 19);
rocketMQTemplate.sendOneWay("topic10", user);
return "单向消息发送成功";
}
@GetMapping("sendDelayLevel")
public String sendDelayLevel() {
User user = new User("cc", 19);
rocketMQTemplate.syncSend("topic10", MessageBuilder.withPayload(user).build(), 2000, 3);
return "延时消息发送成功";
}
@GetMapping("sendMatch")
public String sendMatch() {
List<User> users= new ArrayList<>();
for (int i = 0; i < 3; i++) {
User user = new User("小" + i, i);
users.add(user);
}
rocketMQTemplate.syncSend("topic10", users, 1000);
return "批量发送成功";
}
5.2.2 消息过滤
5.2.2.1 tag过滤
@RocketMQMessageListener(topic = "topic10", consumerGroup = "group1", selectorExpression = "tag1 || tag2")
5.2.2.2 sql过滤
@RocketMQMessageListener(topic = "topic10", consumerGroup = "group1", selectorType = SelectorType.SQL92,
selectorExpression = "age >= 18", messageModel = MessageModel.BROADCASTING)