封面图:渤海大学,辽宁省锦州,2012年6月。
RocketMQ 是阿里巴巴于2012年开源的分布式消息中间件,后来捐赠给Apache软件基金会,并于 2017 年9月25日成为 Apache 的顶级项目。别的就不多说了,文末附有参考资料,可以学习使用,直接奉上代码。
测试环境是两台服务器搭建的双Master集群。
源代码
https://github.com/wu-boy/spring-boot-demo
jms模块下的rocketmq模块。
RocketMQ依赖
在Spring Boot项目中,可以使用RocketMQ的外部项目rocketmq-spring-boot-starter来方便集成。
源码地址:https://github.com/apache/rocketmq-spring,里面还有例子可供参考。
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
配置文件
rocketmq:
name-server: ip:port;ip:port
producer:
group: producer_group_test
global-config:
topic-string: topic_string
topic-user: topic_user
string-consumer-group: string_consumer_group
user-consumer-group: user_consumer_group
name-server配置的是RocketMQ集群,有几个服务器就配置几个IP地址和端口,IP和端口之间用分号隔开。
配置类
@Component
@ConfigurationProperties("global-config")
public class GlobalConfig {
/**
* 字符串主题
*/
private String topicString;
/**
* 用户主题
*/
private String topicUser;
/**
* 字符串消费者组
*/
private String stringConsumerGroup;
/**
* 用户消费者组
*/
private String userConsumerGroup;
// 请自行补充get/set
}
实体类User
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String username;
// 请自行补充get/set
}
字符串消费者
@Service
@RocketMQMessageListener(consumerGroup = "${global-config.string-consumer-group}", topic = "${global-config.topic-string}")
public class StringConsumer implements RocketMQListener<String> {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void onMessage(String message) {
log.info("消费字符串消息{}", message);
}
}
User消费者
@Service
@RocketMQMessageListener(consumerGroup = "${global-config.user-consumer-group}", topic = "${global-config.topic-user}")
public class UserConsumer implements RocketMQListener<User> {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void onMessage(User user) {
log.info("消费用户消息{}", user.getUsername());
}
}
创建RocketmqController进行测试
@RestController
@RequestMapping("rocketmq")
public class RocketmqController {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private GlobalConfig globalConfig;
@Resource
private RocketMQTemplate rocketMQTemplate;
/**
* 同步发送
* 页面访问http://localhost:8080/rocketmq/sync
* @throws Exception
*/
@GetMapping("sync")
public void sync(){
SendResult sendResult = rocketMQTemplate.syncSend(globalConfig.getTopicString(), "Hello world!");
log.info("同步发送字符串{}, 发送结果{}", globalConfig.getTopicString(), sendResult);
User user = new User();
user.setId("1");
user.setUsername("wusq");
sendResult = rocketMQTemplate.syncSend(globalConfig.getTopicUser(), user);
log.info("同步发送对象{}, 发送结果{}", globalConfig.getTopicUser(), sendResult);
}
/**
* 异步发送
* 页面访问http://localhost:8080/rocketmq/async
* @throws Exception
*/
@GetMapping("async")
public void async(){
rocketMQTemplate.asyncSend(globalConfig.getTopicString(), "Hello world!", new SendCallback() {
@Override
public void onSuccess(SendResult var1) {
log.info("异步发送成功{}", var1);
}
@Override
public void onException(Throwable var1) {
log.info("异步发送失败{}", var1);
}
});
}
/**
* 单向发送
* 页面访问http://localhost:8080/rocketmq/oneway
* @throws Exception
*/
@GetMapping("oneway")
public void oneway(){
rocketMQTemplate.sendOneWay(globalConfig.getTopicString(), "Hello world!");
log.info("单向发送");
}
}
Controller中演示了3种方式发送消息:
- 同步发送
指消息发送方发出数据后,会在接收方发回的响应之后才发送下一个数据包。 - 异步发送
指发送方发出数据后,不等待接收方发回响应,就接着发送下一个数据包。 - 单向发送
指只负责发送消息而不等待服务器回应且没有回调函数触发。
结束语
综上所述,RocketMQ结合Spring Boot使用,还是比较简单的。
消费者在消费一条数据的时候如果发生异常,这条数据也不会丢的,消费者会自动重新消费此条数据。
参考资料
《分布式消息中间件实践–详解消息中间件的高可用、高性能配置和原理》,倪伟著。