SpringBoot——消息

一、消息服务的基本概念

1、消息服务中两个重要概念:
消息代理(message broker,消息服务器)和目的地(destination)当消息发送者发送消息以后,将由消息代理接管,消息代理保证消息传递到指定目的地。

2、消息队列主要有两种形式的目的地:

(1) 队列(queue):点对点消息通信(point-to-point)。

  • 发送者发送消息,消息代理将其放入一个队列中,在合适的时候,消息接收者从队列中获取消息内容。

(2) 主题(topic):发布(publish)/订阅(subscribe)消息通信。

  • 发送者发送消息到主题,多个接收者订阅这个主题,那么就会在消息到达时,同时收到消息。

3、消息队列主要可以完成:
(1)异步处理
应用请求不用依次进行处理,提升整体系统的吞吐能力。
在这里插入图片描述

(2)应用间解耦
应用间进行关联时,无需植入过多的接口,能够极大的减少耦合程度。
在这里插入图片描述

(3)流量削峰
当处理秒杀类业务时,能够让后端服务器依据自己的能力来处理业务,可以在一定程度上减少服务器的压力,防止冲垮服务器。
在这里插入图片描述
4、消息服务协议规范

(1)JMS(Java Message Service)JAVA消息服务

  • Java API
  • JMS 定义了JAVA API层面的标准;在java体系中,多个clien均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差。
  • 基于JVM消息代理的规范,ActiveMQ、HornetMQ是JMS实现。

(2)AMQP(Advanced Message Queuing Protocol)

  • 网络级协议
  • 高级消息队列协议,也是一个消息代理的规范,兼容JMS
  • AMQP定义了wire-level层的协议标准;天然具有跨平台、跨语言特性。
  • RabbitMQ是AMQP的实现。

(3)JMS和AMQP对比

JMS AMQP
定义 Java API 网络级协议
是否跨平台/语言
消息模型 (1)点对点
(2)发布/订阅
(1)direct exchange
(2)fanout exchange
(3)topic change
(4)headers exchange
(5)system exchange
后四种和JMS的pub/sub模型没有太大差别,仅是在路由机制上做了更详细的划分;
支持消息类型 TextMessage、
MapMessage、
BytesMessage、
StreamMessage、
ObjectMessage、
Message (只有消息头和属性)
byte[] 当实际应用时,有复杂的消息,可以将消息序列化后发送。

5、Spring对消息服务的支持

  • spring-jms提供了对JMS的支持
  • spring-rabbit提供了对AMQP的支持 需要ConnectionFactory的实现来连接消息代理
  • 提供JmsTemplate、RabbitTemplate来发送消息
  • @JmsListener(JMS)、@RabbitListener(AMQP)注解在方法上监听消息代理发布的消息
  • @EnableJms、@EnableRabbit开启支持

6、SpringBoot对消息服务的配置

  • JmsAutoConfiguration
  • RabbitAutoConfiguration

二、AMQP实现——RabbitMQ

RabbitMQ是一个基于erlang语言开发的AMQP(Advanved Message Queue Protocol)开源实现。

1、基本概念

(1)Message
消息由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

(2)Publisher
消息的生产者,是一个向交换器发布消息的客户端应用程序。

(3)Exchange
服务器中的交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列,交换器决定了消息的去向。Exchange有4种类型:direct(默认),fanout, topic, 和headers。

(4)Queue
消息队列,用来保存消息。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息在队列里面,等待消费者连接到这个队列将其取走。

(5)Binding
绑定,用于消息队列和交换器之间的关联。绑定就是用路由键将交换器和消息队列连接起来的路由规则。Exchange 和Queue的绑定可以是多对多的关系。

(6)Connection
网络连接,比如一个TCP连接。

(7)Channel
信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP 连接。

(8)Consumer
消息的消费者,可以从消息队列中取得消息的客户端应用程序。

(9)Virtual Host
虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个vhost 本质上就是一个mini 版的RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是AMQP 概念的基础,必须在连接时指定,
RabbitMQ 默认的vhost 是/

(10)Broker
表示消息队列服务器实体
在这里插入图片描述

2、RabbitMQ的运行机制

(1)AMQP 中的消息路由
AMQP 中消息的路由过程和Java 开发者熟悉的JMS 存在一些差别,AMQP 中增加了Exchange 和Binding 的角色。生产者把消息发布到Exchange 上,而Binding 决定交换器的消息应该发送到那个队列。

(2)Exchange
Exchange分发消息时不同分发策略有所区别,目前共四种类型:direct、fanout、topic、headers 。headers 匹配消息队列通过AMQP 消息的header而不是路由键,目前几乎用不到了。

direct: 消息中的路由键(routing key)需要与队列名完全匹配。

fanout:(发布/订阅) 每个发到fanout 类型交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处理路由键,很像子网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快的。

topic: 将路由键和某个模式进行匹配。两个通配符:#匹配0个或多个单词,*匹配一个单词。
在这里插入图片描述

3、RabbitMQ安装与测试

(1)拉取RabbitMQ

docker pull 阿里云镜像加速地址/library/rabbitmq:3-management

(2)查看是否安装成功

docker images

在这里插入图片描述

(3)启动RabbitMQ
5672:服务器端口
15672:后台管理界面端口

docker run -d -p 5672:5672 -p 15672:15672 --name myRabbitMQ 92c743b6c055

(4)查看运行的容器
docker ps
在这里插入图片描述
(5)访问后台管理界面
默认用户名/密码为:guest/guest
在这里插入图片描述

(6)测试

1)添加交换器和队列
添加一个新的exchange
在这里插入图片描述
一共添加了三个交换器:
在这里插入图片描述
添加四个队列:
在这里插入图片描述

2)绑定

direct绑定:
在这里插入图片描述
在这里插入图片描述
fanout绑定:
无需绑定路由规则。
在这里插入图片描述

topic绑定:
在这里插入图片描述
3)发送消息测试:
对于队列,只有路由键和队列名完全匹配才可以。
在这里插入图片描述
收到消息:
在这里插入图片描述
在这里插入图片描述
对于fanout,无论路由键是什么,都是以广播的形式发给所有队列:
在这里插入图片描述
对于主题:
只有匹配指定路由规则的队列才可以收到消息,这里只有cbj.news和glp.news可以收到消息。
在这里插入图片描述

4、SpringBoot和RabbitMQ整合

RabbitAutoConfiguration
RabbitProperties:封装了RabbitMQ的配置
RabbitTemplate:给RabbitMQ发送和接收消息
AmqpAdmin :系统管理功能组件

(1)引入依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

(2)application.properties配置

spring.rabbitmq.host=47.94.230.49
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

(3)测试RabbitMQ
发送消息/接收消息

  • send(exchange,routekey,message);使用send发送消息,message需要自己构建(包括消息头和消息体)
  • convertAndSend(exchange,routeKey,object):object默认作为消息体,并且会自动序列化发送给Rabbitmq.

在这里插入图片描述

RabbitMQ管理界面得到的数据:
在这里插入图片描述

RabbitTemplate在处理消息时,默认使用SimpleMessageConverter():
在这里插入图片描述
在RabbitAutoConfiguration中配置RabbitTemplate时,可以从容器中导入自己的MessageConverter:
在这里插入图片描述
(4)自定义一个MessageConverter

@Configuration
public class myAMQPConfig {
    
     
    @Bean
    public MessageConverter myMessageconverter(){
    
    
       return new Jackson2JsonMessageConverter();
    }
}

配置完消息转换器之后:
在这里插入图片描述
(5)监听消息列表
监听消息列表,实时接收消息
使用@RabbitListener来监听消息,需要开启Rabbit相关的注解@EnableRabbit

在主启动类上加上注解:@EnableRabbit
在这里插入图片描述
可以利用Message获取消息体以及消息头
在这里插入图片描述
(6)在Java程序中创建Exchange、队列以及绑定规则
AmqpAdmin:管理组件,用来创建Exchange,Queue,Binding

创建Exchange:
在这里插入图片描述
创建队列:

在这里插入图片描述
创建绑定关系:

Binding(
String destination, 要绑定的目的地
Binding.DestinationType destinationType, 目的地类型
String exchange, 交换器
String routingKey, 路由规则
@Nullable Map<String, Object> arguments 参数
)

在这里插入图片描述

三、JMS实现——ActiveMQ

待更新

猜你喜欢

转载自blog.csdn.net/glpghz/article/details/112387496
今日推荐