【云原生进阶之PaaS中间件】第四章RabbitMQ-1-简介及工作模式

这篇具有很好参考价值的文章主要介绍了【云原生进阶之PaaS中间件】第四章RabbitMQ-1-简介及工作模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

1 RabbitMQ简介

1.1 基本介绍

        RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。AMQP(Advanced Message Queue:高级消息队列协议)它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。RabbitMQ 最初起源于消息系统,用于在分布式系统中存储转发消息,具体有如下一些特点:

  • 可靠性: RabbitMQ 使用一些机制来保证可靠性,比如持久化、传输确认机制(ack)和发布确认等。
  • 灵活的路由策略: 在消息进入队列之前,通过 Exchange 来路由消息,对于典型的路由功能,RabbitMQ 已经提供了一些内置的 Exchange 来实现。针对复杂的路由功能,可以将多个 Exchange 绑在一起,也通过插件机制实现自己的 Exchange。
  • 消息集群: 多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker。
  • 高可用: 队列可以在集群中的集群上进行镜像,使得在部分节点出问题的情况下队列仍然可用。
  • 多种协议: RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等。
  • 多语言客户端: RabbitMQ 支持多种常用的语言,比如:Java、.NET 等
  • 管理界面: RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

1.2 业务场景

1.2.1 异步处理

        如: 用户注册发送,注册邮件、注册短信,

传统做法:

1、串行 (先发送邮件、再发短信)。问题:持续时间长

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

2、并行(将注册信息写入数据库后,同时发送邮件、短信),速度快、但不能满足高吞吐需求。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

消息队列做法:

        将数据写入数据库、同时发送消息给发送邮件和注册,异步处理

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

1.2.2 应用解耦

        如:双十一购物节,用户下单后、订单系统通知库存系统。

传统做法:

        订单系统调用库存系统接口。问题:库存接口故障,订单就会失败,而损失大量订单

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

消息队列做法

        订单系统:下单,订单系统完成持久化,将消息写入队列,返回下单成功给用户

        库存系统:订阅下单的消息,获取下单消息,进行库操作,就算库存系统故障,消息队列也能保证消息可靠投递,不会导致消息丢失。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

1.2.3 流量削峰

        如:秒杀活动、一般会因为流量过大,导致应用挂掉,一般在应用前端加入消息队列。

作用:

1、可以控制活动人数,超过一定阈值,订单直接丢弃。

2、可以缓解短时间的高流量压垮应用(应用程序按自己的最大处理能力获取订单)

消息队列做法:

1、用户的请求,服务器收到后,首先写入消息队列,加入消息队列长度最大值,则直接抛弃用户请求或跳转到错误页面

2、秒杀业务根据消息队列中的请求信息,再做后续处理

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

2 RabbitMQ系统架构

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

2.1 基本概念

2.1.1 Message(消息)

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

2.1.2 Publisher

        消息生产者,也是一个向交换器发布消息的客户端应用程序,就是投递消息的程序。

2.1.3 Consumer

        消息消费者,表示一个从消息队列中取得消息的客户端应用程序,就是接受消息的程序。

2.1.4 Broker

        表示消息队列服务器实体。它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输。

2.1.5 Virtual Host(虚拟主机)

        Virtual host是一个虚拟主机的概念,一个Broker中可以有多个Virtual host,每个Virtual host都有一套自己的Exchange和Queue,同一个Virtual host中的Exchange和Queue不能重名,不同的Virtual host中的Exchange和Queue名字可以一样。这样,不同的用户在访问同一个RabbitMQ Broker时,可以创建自己单独的Virtual host,然后在自己的Virtual host中创建Exchange和Queue,很好地做到了不同用户之间相互隔离的效果。每个vhost本质上就是一个mini版的rabbitmq服务器,拥有自己的队列、交换器、绑定和权限机制。vhost是AMQP概念的基础,必须在连接时指定,rabbitmq默认的vhost是 / 。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

2.1.6 Exchange

        交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。消息交换机,它指定消息按什么规则,路由到哪个队列。

2.1.7 Routing Key

        路由关键字,exchange根据这个关键字进行消息投递。

2.1.8 Binding(绑定)

        用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

        它的作用就是把exchange和queue按照路由规则绑定起来。

        绑定其实就是关联了exchange和queue,或者这么说:queue对exchange的内容感兴趣,exchange要把它的Message deliver到queue。

2.1.9 Queue(消息队列)

        消息的载体,每个消息都会被投到一个或多个队列,等待消费者连接到这个队列将其取走。它是消息的容器,也是消息的终点。

2.1.10 Connection

        每个producer(生产者)或者consumer(消费者)要通过RabbitMQ发送与消费消息,首先就要与RabbitMQ建立连接,这个连接就是Connection。Connection是一个TCP长连接。

2.1.11 Channel(信道,通道)

        Channel是在Connection的基础上建立的虚拟连接,RabbitMQ中大部分的操作都是使用Channel完成的,比如:声明Queue、声明Exchange、发布消息、消费消息等。

        看到此处,你是否有这样一个疑问:既然已经有了Connection,我们完全可以使用Connection完成Channel的工作,为什么还要引入Channel这样一个虚拟连接的概念呢?因为现在的程序都是支持多线程的,如果没有Channel,那么每个线程在访问RabbitMQ时都要建立一个Connection这样的TCP连接,对于操作系统来说,建立和销毁TCP连接是非常大的开销,在系统访问流量高峰时,会严重影响系统性能。

        Channel就是为了解决这种问题,通常情况下,每个线程创建单独的Channel进行通讯,每个Channel都有自己的channel id帮助Broker和客户端识别Channel,所以Channel之间是完全隔离的。Connection与Channel之间的关系可以比作光纤电缆,如果把Connection比作一条光纤电缆,那么Channel就相当于是电缆中的一束光纤,属于一种典型的多路复用连接技术。

2.1.12 集群节点

        RabbitMQ的集群节点包括内存节点、磁盘节点。顾名思义内存节点就是将所有数据放在内存,磁盘节点将数据放在磁盘。不过,如果在投递消息时,打开了消息的持久化,那么即使是内存节点,数据还是安全的放在磁盘。

        一个rabbitmq集群中可以共享 user,vhost,queue,exchange等,所有的数据和状态都是必须在所有节点上复制的,一个例外是,那些当前只属于创建它的节点的消息队列,尽管它们可见且可被所有节点读取。rabbitmq节点可以动态的加入到集群中,一个节点它可以加入到集群中,也可以从集群进行一个基本的负载均衡。

        集群中有两种节点:

1.内存节点:只保存状态到内存(一个例外的情况是:持久的queue的持久内容将被保存到disk)

2.磁盘节点:保存状态到内存和磁盘。

        内存节点虽然不写入磁盘,但是它执行比磁盘节点要好。集群中,只需要一个磁盘节点来保存状态 就足够了如果集群中只有内存节点,那么不能停止它们,否则所有的状态,消息等都会丢失。

2.2 重要组件实现

2.2.1 Exchange机制(交换器)

        Exchange是一个比较重要的概念,它是消息到达RabbitMQ的第一站,主要负责根据不同的分发规则将消息分发到不同的Queue,供订阅了相关Queue的消费者消费到指定的消息。那Exchange有哪些分发消息的规则呢?这就要说到Exchange的4种类型了:direct、fanout、topic、headers。

        在介绍这4种类型的Exchange之前,我们先来了解一下另外一个比较重要的概念:Routing key,翻译成中文就是路由键。当我们创建好Exchange和Queue之后,需要使用Routing key(通常叫作Binding key)将它们绑定起来,producer在向Exchange发送一条消息的时候,必须指定一个Routing key,然后Exchange接收到这条消息之后,会解析Routing key,然后根据Exchange和Queue的绑定规则,将消息分发到符合规则的Queue中。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        接下来,我们根据上面的流程再来详细介绍下面4种类型的Exchange。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

2.2.1.1 direct类型转发

        direct的意思是直接的,direct类型的Exchange会将消息转发到指定Routing key的Queue上,Routing key的解析规则为精确匹配。也就是只有当producer发送的消息的Routing key与某个Binding key相等时,消息才会被分发到对应的Queue上。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        比如我们现在有一个direct类型的Exchange,它下面绑定了三个Queue,Binding key分别是ORDER/GOODS/STOCK:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        然后我们向该Exchange中发送一条消息,消息的Routing key是ORDER:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        按照规则分析,这条消息应该被路由到MY_EXCHANGE_ORDER_QUEUE这个Queue。消息发送成功之后,我们去Queues中查看,发现确实只有MY_EXCHANGE_ORDER_QUEUE这个QUEUE接收到了一条消息。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        进入这个队列,通过getMessage取出消息查看,确实是我们刚才手动发送的那条消息。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        所以,direct类型的Exchange在分发消息时,必须保证producer发送消息的Routing key与Exchange和Queue绑定的Binding key相等才可以。

2.2.1.2 fanout 类型(广播)转发

        fanout是扇形的意思,该类型通常叫作广播类型。fanout类型的Exchange不处理Routing key,而是会将发送给它的消息路由到所有与它绑定的Queue上。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        比如我们现在有一个fanout类型的Exchange,它下面绑定了三个Queue,Binding key分别是ORDER/GOODS/STOCK:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        然后我们向该Exchange中发送一条消息,消息的Routing key随便填一个值abc:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        按照规则分析,这条消息应该被路由到所有与该Exchange绑定的Queue,即三个Queue都应该会受到消息。消息发送成功之后,我们去Queues中查看,发现确实每个QUEUE都接收到了一条消息。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        进入这三个QUEUE,通过getMessage取出消息查看,确实是我们刚才手动发送的那条消息。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        所以,fanout类型的Exchange不管Routing key是什么,它都会将接收到的消息分发给所有与自己绑定了的Queue上。

2.2.1.3 topic类型转发

        topic的意思是主题,topic类型的Exchange会根据通配符对Routing key进行匹配,只要Routing key满足某个通配符的条件,就会被路由到对应的Queue上。通配符的匹配规则如下:

  • Routing key必须是一串字符串,每个单词用“.”分隔;
  • 符号“#”表示匹配一个或多个单词;
  • 符号“*”表示匹配一个单词。

        例如:“*.123” 能够匹配到 “abc.123”,但匹配不到 “abc.def.123”;“#.123” 既能够匹配到 “abc.123”,也能匹配到 “abc.def.123”。

        比如我们现在有一个topic类型的Exchange,它下面绑定了4个Queue,Binding key分别是 *.ORDER、GOODS.*、#.STOCK、USER.#。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        然后我们向该Exchange中发送一条消息,消息的Routing key为:USER.ABC.ORDER。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        按照规则分析,USER.ABC.ORDER这个Routing key只可以匹配到 “USER.#” ,所以,这条消息应该被路由到MY_TOPIC_USER_QUEUE这个Queue中。消息发送成功之后,我们去Queues中查看,发现结果符合我们的预期。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        进入这个QUEUE,通过getMessage取出消息查看,确实是我们刚才手动发送的那条消息。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

2.2.1.4 headers类型转发

        日常工作中,以上三种类型的Exchange已经能够满足我们基本上所有的需求了,headers模式并不经常使用,我们只需要对headers Exchange有一个基本的了解就可以了。

        headers Exchange中,Exchange与Queue之间的绑定不再通过Binding key绑定,而是通过Arguments绑定。比如我们现在有一个headers类型的Exchange,下面通过不同的Arguments绑定了三个Queue:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        producer在发送消息时可以添加headers属性,Exchange接收到消息后,会解析headers属性,只要我们上面配置的Arguments中的所有属性全部被包含在Headers中并且值相等,那么这条消息就会被路由到对应的Queue中。

        比如我们向上面的Exchange中发送一条消息,消息的Headers中添加“x=1”:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        根据规则,只有queue1这个队列满足x=1的条件,queue2中的y=2条件不满足,所以,消息应该只被路由到queue1队列中。消息发送成功后,我们可以看到queue1确实收到了消息:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        并且这条消息就是我们刚才手动发送的消息:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        然后我们再发送一条消息,消息的headers中有两个属性:x=1,y=2:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        根据规则,queue1的x=1的条件满足,queue2的x=1、y=2的条件满足,queue3的y=2的条件满足,所以,这三个Queue应该都能够收到这条消息。消息发送成功后,结果符合预期:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        这条消息就是我们刚才手动发送的消息:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

3 五种工作模型示例

        springboot依赖配置:

<!-- amqp依赖,包含Rabbitmq-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

        yml配置:

spring:
  application:
    name: rabbitmq
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /

3.1 Hello World简单模型

        一对一消费,只有一个消费者能接收到:

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

消费者

@Component
public class HolloWordListener {
    // @RabbitListener(queues = ("simple.queue")) // queues需手动先创建队列
    @RabbitListener(queuesToDeclare = @Queue("simple.queue"))  // queuesToDeclare 自动声明队列
    public void holloWordListener(String message){
        System.out.println("message = " + message);
    }
}

生产者

@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSimpleQueue() {
    String queueName = "simple.queue"; // 队列名称
    String message = "heel,simple.queue"; // 要发送的消息
    rabbitTemplate.convertAndSend(queueName,message);
}

3.2 Work queues工作队列

        多个消费者,你一个我一个分配消费消息,有预取机制,默认公平消费,可配置能者多劳模式,谁完成的快,谁多做一点。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

消费者

@Component
public class WoekWordListener {
    @RabbitListener(queuesToDeclare = @Queue("workQueue")) // queuesToDeclare 自动声明队列
    public void holloWordListener(String message) throws InterruptedException {
        Thread.sleep(200);
        System.out.println("message1 = " + message);
    }

    @RabbitListener(queuesToDeclare = @Queue("workQueue")) // queuesToDeclare 自动声明队列
    public void holloWordListener1(String message) throws InterruptedException {
     Thread.sleep(400);
     System.out.println("message2 = " + message);
    }
}

生产者

@Autowired
private RabbitTemplate rabbitTemplate;

@Test
public void testWorkQueue(){
    String queueName = "workQueue";
    String message = "hello,work.queue__";
    for (int i = 0; i < 10; i++) {
     rabbitTemplate.convertAndSend(queueName,message+i);
     System.out.println("i = " + i);
    }
}

        取消预取机制,能者多劳配置:

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条,处理完成才能获取下一条

3.3 Publish/Subscribe发布订阅模型

        发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机),注意:交换机是不缓存消息的。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

        使用fanout交换机,会将接收到的消息路由到每一个跟其绑定的queue(队列)。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

消费者

// 消费者直接绑定交换机,指定类型为fanout
@Component
public class FanoutExchangeListener {
    // 不指定队列,消息过了就没了
    //  @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "fanoutTest",type = ExchangeTypes.FANOUT))})
    // 指定队列,可以接收缓存到队列里的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value ="test",durable = "true" ),exchange = @Exchange(value = "fanoutTest",type = ExchangeTypes.FANOUT))})
    public void reveivel(String message){
        System.out.println("message = " + message);
    }
    
    @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "fanoutTest",type = ExchangeTypes.FANOUT))})
    public void reveivel2(String message){
        System.out.println("message1 = " + message);
    }
}

生产者

@Autowired
private RabbitTemplate rabbitTemplate;

@Test
public void tesyPubSubQueue(){
    // 参数1:交换机名称 , 参数2routingKey,(fanout类型可不写) , 参数3,消息内容
    rabbitTemplate.convertAndSend("fanoutTest","","消息内容");
}

3.4 Routing路由模型

        routing模型也是将消息发送到交换机。使用的是Direct类型的交换机,会将接收到的消息根据规则路由到指定的Queue(队列),因此称为路由模式。

mq应用层协议,云原生进阶-PaaS专栏,云原生,paas,中间件,rabbitmq,java

消费者

// 消费者直接绑定交换机,指定类型为direct,并指定key表示能消费的key
@Component
public class RoutingExchangeListener {
    // 不指定队列,消息过了就没了
    //  @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "direstTest",type = ExchangeTypes.DIRECT),key = {"info","error"})})
    // 指定队列,可以接收缓存到队列里的消息
    // key = {"info","error"} 表示我能接收到routingKey为 info和error的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value ="test1",durable = "true" ),exchange = @Exchange(value = "direstTest",type = ExchangeTypes.DIRECT),key = {"info","error"})})
    public void receivel(String message){
    System.out.println("message = " + message);
    }

    // key = {"error"} 表示我只能接收到routingKey为 error的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "direstTest",type = ExchangeTypes.DIRECT),key = {"error"})})
    public void receivel1(String message){
    System.out.println("message1 = " + message);
    }
}

生产者

@Autowired
private RabbitTemplate rabbitTemplate;

// 路由模型
@Test
public void direstExchangeTest(){
    rabbitTemplate.convertAndSend("direstTest","info","发送info的key的路由消息");
}

// 路由模型
@Test
public void direstExchangeTest1(){
    rabbitTemplate.convertAndSend("direstTest","error","发送error的key的路由消息");
}

3.5 Topics主题模型

        topicExchange与directExchange类型,区别在于routingKey必须是多个单词的列表,并且以 . 分隔:

*(代表通配符,任意一个字段)

#(号代表一个或多个字段)

消费者

@Componentpublic class TopicsExchangeListener {
    // 不指定队列,消息过了就没了
    //  @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(name = "topicList",type = ExchangeTypes.TOPIC),key = {"user.save","user."})})
    // 指定队列,可以接收缓存到队列里的消息
    // key = {"user.save","user.*"} 表示能消费 routingkey为  user.save 和 user.任意一个字符  的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value ="test2",durable = "true" ),exchange = @Exchange(name = "topicList",type = ExchangeTypes.TOPIC),key = {"user.save","user.*"})})
    public void recevicel(String message){
        System.out.println("message = " + message);
    }

    // key = {"order.#","user.*"} 表示能消费 routingkey为  order.一个或多个字符   和  user.任意一个字符  的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(name = "topicList",type = ExchangeTypes.TOPIC),key = {"order.#","user.*"})})
    public void recevicel1(String message){
        System.out.println("message1 = " + message);
    }
}

生产者

@Autowired
private RabbitTemplate rabbitTemplate;

@Test
public void topicTest(){
    rabbitTemplate.convertAndSend("topicTest","user.save","topic路由消息,use.save");
}

@Test
public void topicTest1(){
    rabbitTemplate.convertAndSend("topicTest","order.select.getone","topic路由消息,order.select.getone");
}

3.6 消息转换器

        代码里直接发送对象,虽然接收的到消息,但是rabbitmq的界面上看到的消息会是乱码。

依赖

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.10</version>
</dependency>

配置

@Configuration
public class rabbitmqConfig {
    // 消息转换配置
    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

        再次发送就会是转换好的消息。

参考链接

rabbitmq专栏

史上最透彻的 RabbitMQ 可靠消息传输实战 - 掘金

RabbitMQ系列(四)RabbitMQ事务和Confirm发送方消息确认——深入解读 - 掘金

RabbitMQ原理及实现_rabbitmq实现-CSDN博客

RabbitMQ的工作模式及原理

RabbitMQ如何保证消息的可靠性投递与消费?

Linux安装Erlang和RabbitMQ详细步骤

rabbitmq详解-CSDN博客

RabbitMQ(一)——常见消息中间件

深入理解:RabbitMQ的前世今生

RabbitMQ技术详解-架构

透彻rabbitmq - 知乎

消息队列的使用场景是怎样的? - 知乎

RabbitMQ原理 - 知乎

RabbitMQ 原理解析

RabbitMQ原理详解_rabbitmq工作原理-CSDN博客

RabbitMQ 基本概念介绍_rabbitmq基本概念-CSDN博客

RabbitMQ系列二(构建消息队列机制)_rabbitmq系列二(构建消息队列)-CSDN博客

RabbitMQ消息队列(二)-RabbitMQ消息队列架构与基本概念

RabbitMQ基础概念详解文章来源地址https://www.toymoban.com/news/detail-833435.html

到了这里,关于【云原生进阶之PaaS中间件】第四章RabbitMQ-1-简介及工作模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【云原生进阶之PaaS中间件】第一章Redis-1.4过期策略

            除了string独有设置过期时间的方法,其他类型都需依靠expire方法设置时间,若: 未设置时间,则缓存永不过期 设置过期时间,但之后又想让缓存永不过期,使用persist         设置key的过期时间。超时后,将会自动删除该key。在Redis的术语中一个key的相关超时

    2024年02月09日
    浏览(55)
  • 【云原生进阶之PaaS中间件】第一章Redis-1.3Redis配置

            Redis支持采用其内置默认配置的方式来进行启动,而不需要提前配置任何文件,但是这种启动方式只推荐在测试和开发环境中使用,但更好的方式是通过提供一个Redis的配置文件来对Redis进行配置, 这个配置文件一般命名为’redis.conf’。         Redis的配置文件

    2024年02月09日
    浏览(56)
  • 【云原生进阶之PaaS中间件】第二章Zookeeper-3.2架构详解

    » 领导者(leader),负责进行投票的发起和决议,更新系统状态 » 学习者(learner),包括跟随者(follower)和观察者(observer),follower用于接受客户端请求并想客户端返回结果,在选主过程中参与投票 » Observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票

    2024年02月08日
    浏览(56)
  • 【云原生进阶之PaaS中间件】第一章Redis-1.5.1安装配置

            在本节中,您将了解和学习Redis的环境安装设置。         要在Ubuntu上安装Redis,打开终端并键入以下命令 -         这将在Ubuntu机器上安装Redis。 1.2.1 安装步骤 1、首先使用 sudo brew install redis 命令一键安装Redis, 默认会安装在 /usr/local/bin 路径中。 2、cd 进

    2024年02月09日
    浏览(64)
  • 【云原生进阶之PaaS中间件】第一章Redis-2.3.2哨兵模式

            由于无法进行主动恢复,因此主从模式衍生出了哨兵模式。哨兵模式基于主从复制模式,只是引入了哨兵来监控与自动处理故障。Redis Sentinel是社区版本推出的原生高可用解决方案,Redis Sentinel部署架构主要包括两部分:Redis Sentinel集群和Redis数据集群,其中Redis

    2024年02月06日
    浏览(51)
  • 【云原生进阶之PaaS中间件】第一章Redis-2.4缓存更新机制

            无论先操作db还是cache,都会有各自的问题,根本原因是cache和db的更新不是一个原子操作,因此总会有不一致的问题。想要彻底解决这种问题必须将cache和db的更新操作归在一个事务之下(例如使用一些分布式事务,或者强一致性的分布式协议)。或者采用串行化,

    2024年02月10日
    浏览(69)
  • 【云原生进阶之PaaS中间件】第一章Redis-2.3.3集群模式

            Redis集群是一个提供在多个Redis节点之间共享数据的程序集。它并不像Redis主从复制模式那样只提供一个master节点提供写服务,而是会提供多个master节点提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上

    2024年02月10日
    浏览(60)
  • 【云原生进阶之PaaS中间件】第一章Redis-1.6.1Java项目使用Redis

            redis的java客户端很多,官方推荐的有三种: Jedis Lettuce Redisson Spring 对Redis 客户端进行了整合,提供了Spring Date Redis ,在Spring Boot项目中还提供了对应的Starter,即spring-boot-starter-data-redis。         使用Jedis操作Redis的步骤: 1.获取链接; 2.执行操作; 3.关闭连接

    2024年02月09日
    浏览(54)
  • 【云原生进阶之PaaS中间件】第三章Kafka-4.4-消费者工作流程

    1.1.1 消费者群组         Kafka 里消费者从属于消费者群组,一个群组里的消费者订阅的都是同一个主题,每个消费者接收主题一部分分区的消息。         如上图,主题 T 有 4 个分区,群组中只有一个消费者,则该消费者将收到主题 T1 全部 4 个分区的消息。      

    2024年02月22日
    浏览(51)
  • 云原生中间件开源现状分析与华为中间件案例解读

    开源中间件在企业分布式架构搭建和服务治理中扮演着重要的角色,尤其是在解决我国网络高并发和业务复杂性问题方面。然而,尽管中间件市场由商业闭源厂商主导,提供了一系列基础中间件和数据类中间件以支持稳定的应用程序运行环境,开源中间件生态却相对分散和薄

    2024年02月02日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包