Spring支持的消息中间件
1、概念
大部分应用通过消息服务中间件来提升异步通信,扩展解耦能力
组成:消息代理message broker 和目的地destination。但消息发送者发送消息以后,将消息代理接管,消息代理保证消息传递到目的地
消息队列的两种形式的目的地
- 队列:点对点消息通信
- 主题:发布订阅消息通信
实现消息通信的中间件
- JMS java message service Java消息服务:基于JVM消息代理的规范,activeMQq,HornetMQq是JMS实现的
- AMQP Advanced message Queuing protocol 高级消息队列协议,也是一个消息代理的规范,兼容JMS。是RabbitMQ是AMQP的实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZnIP0yXD-1600566534349)(https://i.loli.net/2020/09/19/XMxjaWpcbuGZAo6.png)]
spring支持
- Spring-jms提供对JMS的支持
- spring-rabbit提供了对AMQP的支持
- 需要ConnectionFactory的实现来连接消息代理
- 提供JMSTemplate和RabbitTemplate来发送消息
- @JMSListener,@RabbitListener注解在方法上监听消息代理发送消息
- @EnableJMS,@EnableRabbit
2、RabbitMQ
组成部分
-
message:消息头和消息体
-
publisher:消息的发送者
-
exchange:消息队列服务器
-
queue:队列
-
virtual host:虚拟主机(实体服务主机)
-
binding:exchange和queue的绑定规则
-
channels:信道,多到复用技术
-
connection:TCP连接
-
consumer:消息接受者
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NhszeZKx-1600566534356)(https://i.loli.net/2020/09/19/1T45WgDdjZ6JSwp.png)]
RabbitMQ运行机制
AMQP中的消息路由
Exchange类型:粉发消息时根据类型的不同分发侧率有区别:
- direct:单播模式
- fanout:广播模式
- topic;发布与订阅
- headers:不使用了
消息中的路由键routing key,如果和binding中的绑定键binding key一致,交换机就将消息发送到对应的队列中。
注意的是topic:交换机通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上,他将路由键和绑定键的字符创切分成单词,这些单词之间用逗号隔开,符号#匹配0或者多个单词,*匹配一个单词
3、开发流程
-
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
-
配置连接
spring: rabbitmq: host: 192.168.80.130 username: guest password: guest # virtual-host:
-
导入操作RabbitMQ的模板对象
package com.robin.rabbitmq;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
class RabbitmqApplicationTests {
//操作rabbitmq的模板
@Autowired
RabbitTemplate rabbitTemplate;
//给指定的路由键发送消息
@Test
void contextLoads() {
Map<String,Object> map=new HashMap<>();
map.put("11","first");
map.put("22", "dwafaw");
rabbitTemplate.convertAndSend("exchange.fanout","",map);
}
//接受队列的消息
@Test
public void recerver(){
Object o = rabbitTemplate.receiveAndConvert("atrobin.emps");
System.out.println(o.getClass());
}
}
- rabbitmq默认会把发过去的数据序列化,但是可以自定义数据格式,比如自定义为json
package com.robin.rabbitmq.config;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
- 可以通过设置监听器,来监控队列的消息
package com.robin.rabbitmq.service;
import com.robin.rabbitmq.bean.Book;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
@Service
public class BookService {
@RabbitListener(queues = "atrobin.emps")
public void bookListener(Book book){
System.out.println(book);
}
}
注意要在主程序类上,加上注解@EnableRabbit