RocketMQ是由阿里巴巴集团开发的一款分布式消息中间件。它是基于主题(Topic)的发布/订阅模式构建的,支持高并发、高可靠性的消息传递。它还提供了丰富的特性,如消息的事务性处理、消息的定时发送、消息的过滤和重试机制等。
RocketMQ还提供了可视化的管理控制台,方便管理和监控消息的发送和消费情况。
生产者会从NameService拉取Broker的路由信息,进行消息投递,通过指定的主题(Topic),以及标签,发送到特定的消息队列。然后消费者可以通过订阅特定的主题和标签,直接跟Broker建立连接通道,开始消费消息。
<parent>
<groupId> org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.5.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.apache.rocketmqgroupId>
<artifactId>rocketmq-spring-boot-starterartifactId>
<version>2.2.1version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
@SpringBootApplication
public class ApplicationStart {
public static void main(String[] args) {
SpringApplication.run(ApplicationStart.class);
}
}
rocketmq:
name-server: 127.0.0.1:9876
#生产者配置
producer:
#生产者组名字
group: "service-producer"
# 消息最大长度 默认 1024 * 1024 * 4 (4M)
max-message-size: 4194304
# 发送消息超时时间,默认 3000
send-message-timeout: 3000
# 发送消息失败重试次数,默认2
retry-times-when-send-failed: 2
# 异步消息发送失败重试次数
retry-times-when-send-async-failed: 2
#达到 4096 ,进行消息压缩
compress-message-body-threshold: 4096
consumer:
#消费者名字
group: "service-consumer"
#批量拉取消息数量
pull-batch-size: 10
message-model: CLUSTERING
selector-expression: "*"
package top.itimmortal.controller;
@RestController
@RequestMapping("/send")
public class RocketMQController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@GetMapping("/order/{name}")
public String sendMsg(@PathVariable("name") String name){
//需要发送的消息
Message<String> message = MessageBuilder.withPayload(name).build();
//"topic-order:tags-order-pay":指定主题和标签
rocketMQTemplate.send("topic-order:tags-order-pay",message);
return "发送完成";
}
}
除了使用send发送同步消息,还可以使用synSend,该方法更加灵活:
package top.itimmortal.controller
@RestController
@RequestMapping("/sync")
public class SyncSenController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@RequestMapping("order/{name}")
public String sync(@PathVariable("name") String name){
Message<String> message = MessageBuilder.withPayload(name).build();
//发送同步消息,1s发送不成功就超时
SendResult syncSend = rocketMQTemplate.syncSend("topic-order:tags-order-pay", message, 1000);
//判断是否超时
if (syncSend.getSendStatus() == SendStatus.SEND_OK) {
return "发送成功";
}
return "发送失败";
}
}
package top.itimmortal.controller;
@RestController
@RequestMapping("/async")
public class AsyncSendController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@RequestMapping("order/{name}")
public String sync(@PathVariable("name") String name){
//需要发送的消息
Message<String> message = MessageBuilder.withPayload(name).build();
//"topic-order:tags-order-pay":主题和标签
rocketMQTemplate.asyncSend("topic-order:tags-order-pay", message, new SendCallback() {//消息发送结果回调
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("成功");
}
@Override
public void onException(Throwable throwable) {
System.out.println("失败");
}
});
return "发送";
}
}
package top.itimmortal.controller;
@RestController
@RequestMapping("/sendOneWay")
public class SendOneWayController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@RequestMapping("order/{name}")
public String sync(@PathVariable("name") String name){
Message<String> message = MessageBuilder.withPayload(name).build();
//直接发送,不会返回任何信息
rocketMQTemplate.sendOneWay("topic-order:tags-order-pay",message);
return "发送成功";
}
}
MQ提供消息监听器:RocketMQListener,他会负责监听MQ中的消息从而进行消费。
package top.itimmortal.controller;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
@Component
@RocketMQMessageListener(
//消费者的名字
consumerGroup = "consumer-ordet",
//主题
topic = "topic-order",
//tags
selectorExpression = "tags-order-pay",
//消息消费模式:默认是CLUSTERING集群,还支持BROADCASTING广播
messageModel = MessageModel.CLUSTERING)
//消费者监听器 MessageExt:Message对象的子类
public class ConsumerController implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt message) {
//这里拿到的消息 message.getBody 是byte[]格式。
if(message.getBody() == null ||message.getBody().length == 0)return;
//拿到消息:如果发送的消息是字符串,那么需要把byte[]转为字符串
String msg = new String(message.getBody(), StandardCharsets.UTF_8);
System.out.println(msg);
}
}
把消息写到Broker后需要延迟一定时间才能被消费 , 在RocketMQ中消息的延迟时间不能任意指定,而是由特定的等级(1 到 18)来指定,分别有:
messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h;
这里还是使用同步消息做测试:
package top.itimmortal.controller;
@RestController
@RequestMapping("/sync")
public class SyncSenController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@RequestMapping("order/{name}")
public String sync(@PathVariable("name") String name){
Message<String> message = MessageBuilder.withPayload(name).build();
SendResult syncSend = rocketMQTemplate.syncSend("topic-order:tags-order-pay", message, 1000,3);//等级是 3,对应的是 10S
//判断
if (syncSend.getSendStatus() == SendStatus.SEND_OK) {
return "发送成功";
}
return "发送失败";
}
}