● 同步消息
● 异步消息
企业级应用中广泛使用的三种异步消息传递技术
JMS
AMOP
MQTT
JMS
● JMS(Java Message Service):一个规范,等同于JDBC规范,提供了与消息服务相关的API接口
● JMS消息模型
◆ peer-2-peer:点对点模型,消息发送到一个队列中,队列保存消息。队列的消息只能被一个消费者消费,或超时
◆ publish-subscribe:发布订阅模型,消息可以被多个消费者消费,生产者和消费者完全独立,不需要感知对方的存在
● JMS消息种类
◆ TextMessage
◆ MapMessage
◆ BytesMessage
◆ StreamMessage
◆ ObjectMessage
◆ Message(只有消息头和属性)
●JMS实现:ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)
AMQP
AMQP(advanced message queuing protocol):一种协议(高级消息队列协议,也是消息代理规范),规范了网络交换的数据格式,兼容JMS
● 优点:具有跨平台性,服务器供应商,生产者,消费者可以使用不同的语言来实现
● AMQP消息模型
◆direct exchange
◆fanout exchange
◆topic exchange
◆headers exchange
◆system exchange
● AMQP消息种类:byte[]
● AMQP实现:RabbitMQ、StormMQ、RocketMQ
JMS之ActiveMQ的使用
● 下载地址:https://activemq.apache.org/components/classic/download/
● 安装:解压缩
● 启动服务
路径 apache-activemq-5.17.2-bin\apache-activemq-5.17.2\bin\win64
点击 activemq.bat
● 访问服务器
◆ http://127.0.0.1:8161/
◆ 服务端口:61616,管理后台端口:8161
◆ 用户名&密码:admin
Spring整合activemq
1.导入坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency>
2.配置yml
spring:
activemq:
broker-url: tcp://localhost:61616
jms:
pub-sub-domain: true
template:
default-destination: chj
3.使用
@Service
public class MessageServiceActivemqImpl implements MessageService {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Override
public void sendMessage(String id) {
System.out.println("待发送的订单已纳入队列,id:"+id);
jmsMessagingTemplate.convertAndSend("order.queue.id",id);
}
@Override
public String doMessage() {
String id = jmsMessagingTemplate.receiveAndConvert(String.class);
System.out.println("已完成短信发送业务,id:"+id);
return id;
}
}
4.流程性业务消息消费完转入下一个消息队列
@Component
public class MessageListener {
@JmsListener(destination = "order.queue.id")
@SendTo("order.other.queue.id")
public String receive(String id){
System.out.println("已完成短信发送业务,id:"+id);
return "new"+id;
}
}
AMQP之RabbitMQ
● RabbitMQ基于Erlang语言编写,需要安装Erlang
● Erlang
◆ 下载地址:https:/www.erlang.org/downloads
◆ 安装:一键傻瓜式安装,安装完毕需要重启,需要依赖Windows组件
◆ 环境变量配置
■ ERLANG HOME
■ PATH
RabbitMQ
●下载地址:https://rabbitmq.com/install-windows.html
●安装:一键傻瓜式安装
●开启服务:cmd管理员
启动服务
rabbitmq-service.bat start
关闭服务
rabbitmq-service.bat stop
查看服务状态
rabbitmqctl status
●查看已安装的插件列表
rabbitmq-plugins.bat list
●开启management插件
rabbitmq-plugins.bat enable rabbitmq_management
●浏览器打开http://localhost:15672/
服务端口:5672,管理后台端口:15672
账号密码:guest
SpringBoot整合RabbitMQ
1.导入SpringBoot整合RabbitMQ坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
2.配置yml
rabbitmq: host: localhost port: 5672
direct
3.定义消息队列(direct)
@Configuration
public class RabbitConfigDirect {
//定义消息队列
@Bean
public Queue directQueue(){
//durable:是否特久化,默认False
//exclusive:是否当前连接专用,默认False,连接关闭后队列即被删除
//autoDelete:是否自动删除,当生产者或消费者不再使用此队列,自动删除
return new Queue("direct_queue",true,false,false);
}
@Bean
public Queue directQueue2(){
return new Queue("direct2_queue",true,false,false);
}
//定义交换机
@Bean
public DirectExchange directExchange(){
return new DirectExchange("directExchange");
}
//绑定消息队列和交换机
@Bean
public Binding bindingDirect(){
return BindingBuilder.bind(directQueue()).to(directExchange()).with("direct_binding");
}
@Bean
public Binding bindingDirect2(){
return BindingBuilder.bind(directQueue2()).to(directExchange()).with("direct_binding");
}
}
4.生产与消费消息(direct)
@Service
public class MessageServiceRabbitmqDirectImpl implements MessageService {
@Autowired
private AmqpTemplate amqpTemplate;
@Override
public void sendMessage(String id) {
System.out.println("待发送的订单已纳入队列,id:"+id);
amqpTemplate.convertAndSend("directExchange","direct_binding",id);
}
@Override
public String doMessage() {
return null;
}
}
5.使用消息监听器对消息队列监听(direct)
@Component
public class MessageListener {
@RabbitListener(queues = "direct_queue")
public void receive(String id){
System.out.println("已完成短信发送业务(rabbitmq direct 1),id:"+id);
}
}
6.使用多消息监听器对消息队列监听进行消息轮循处理(direct)
@Component
public class MessageListener2 {
@RabbitListener(queues = "direct_queue")
public void receive(String id){
System.out.println("已完成短信发送业务(rabbitmq direct 2),id:"+id);
}
}
topic
1..定义消息队列(topic)
@Configuration
public class RabbitConfigTopic {
//定义消息队列
@Bean
public Queue topicQueue(){
return new Queue("topic_queue",true,false,false);
}
@Bean
public Queue topicQueue2(){
return new Queue("topic_queue2",true,false,false);
}
//定义交换机
@Bean
public TopicExchange topicExchange(){
return new TopicExchange("topicExchange");
}
//绑定消息队列和交换机
@Bean
public Binding bindingTopic(){
return BindingBuilder.bind(topicQueue()).to(topicExchange()).with("topic_binding.*.id");
}
@Bean
public Binding bindingTopic2(){
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic_binding.orders.*");
}
}
2..生产与消费消息(topic)
@Service
public class MessageServiceRabbitmqTopicImpl implements MessageService {
@Autowired
private AmqpTemplate amqpTemplate;
@Override
public void sendMessage(String id) {
System.out.println("待发送的订单已纳入队列,id:"+id);
amqpTemplate.convertAndSend("topicExchange","topic_binding.orders.id",id);
}
@Override
public String doMessage() {
return null;
}
}
3.使用消息监听器对消息队列监听(topic)
@Component
public class MessageListener {
@RabbitListener(queues = "topic_queue")
public void receive(String id){
System.out.println("已完成短信发送业务(rabbitmq topic 1),id:"+id);
}
@RabbitListener(queues = "topic_queue2")
public void receive2(String id){
System.out.println("已完成短信发送业务(rabbitmq topic 2),id:"+id);
}
}
RocketMQ (jdk1.8)
●下载地址:下载 | RocketMQ (apache.org)
●安装:解压缩
◆默认服务端口:9876
●环境变量配置
◆ROCKETMQ HOME
◆PATH
◆NAMESRV_ADDR(建议):127.0.0.1:9876
● 命名服务器与broker
使用rocketmq
●启动命名服务器
mqnamesrv.cmd
●启动broker
mqbroker.cmd
spring整合RocketMq
1.导入坐标
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency>
2.配置yml
rocketmq:
name-server: localhost:9876
producer:
group: rocketmq_group
3.生产消息(同步/异步)
@Service
public class MessageServiceImpl implements MessageService {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Override
public void sendMessage(String id) {
System.out.println("待发送的订单已纳入队列,id:"+id);
// rocketMQTemplate.convertAndSend("order_id",id); 下面为异步消息
SendCallback callback=new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("消息发送成功");
}
@Override
public void onException(Throwable throwable) {
System.out.println("消息发送失败");
}
};
rocketMQTemplate.asyncSend("order_id",id, callback);
}
@Override
public String doMessage() {
return null;
}
}
4.使用消息监听器对消息队列监听
@Component
@RocketMQMessageListener(topic = "order_id",consumerGroup = "rocketmq_group")
public class MessageListener implements RocketMQListener<String> {
@Override
public void onMessage(String id) {
System.out.println("已完成短信发送业务(rocketmq),id:"+id);
}
}
Kafka
●Kafka 一种高吞吐量的分布式发布订阅消息系统,提供实时消息功能。
●下载地址:https://kafka.apache.org/downloads
◆windows系统下3.0.0版本存在BUG,建议使用2.X版本
●安装:解压缩
●启动zookeeper
◆zookeeper-server-start.bat ..\..\config\zookeeper.properties
◆默认端口:2181
●启动kafka
◆kafka-server-start.bat ..\..\config\server.properties
◆默认端口:9092
●创建topic
kafka-topics.bat --zookeeper 127.0.0.1:2181 --create --replication-factor 1 --partitions 1 --topic aty
●查看topic
kafka-topics.bat --zookeeper 127.0.0.1:2181 --list
●删除topic
kafka-topics.bat --delete --zookeeper localhost:2181 --topic chj
●使用生产者和消费者 :在生产者输入的消息会同步到消费者,中文会乱码
kafka-console-producer.bat --broker-list 127.0.0.1:9092 --topic aty 生产者
kafka-console-consumer.bat --bootstrap-server 127.0.0.1:9092 --topic aty --from-beginning 消费者
SpringBoot整合 Kafka
●导入Kafka坐标
<dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency>
●配置yml
kafka:
bootstrap-servers: localhost:9092
consumer:
group-id: order
●生产消息
@Service
public class MessageServiceKafkaImpl implements MessageService {
@Autowired
private KafkaTemplate<String,String> kafkaTemplate;
@Override
public void sendMessage(String id) {
System.out.println("待发送的订单已纳入队列,id:"+id);
kafkaTemplate.send("aty",id);
}
@Override
public String doMessage() {
return null;
}
}
●使用消息监听器对消息队列监听
@Component
public class MessageListener {
@KafkaListener(topics = "aty")
public void onMessage(ConsumerRecord<String,String> record) {
System.out.println("已完成短信发送业务(kafka),id:"+record.value());
}
}
MOTT
●MQTT(Message Queueing Telemetry Transport)消息队列遥测传输,专为小设备设计,是物联网(IOT)生态系统中主要成分之一