SpringMVC中配置RabbitMQ

        RabbitMQ是工作在amqp协议(advanced message queue protocal,高级消息队列协议)上的一个消息中间件。它通过一个生产者消费者模型来处理应用中产生的消息。

        除了生产者和消费者,此模型中另外一个重要的概念叫“工作队列”,也称为“任务队列”(Task Queue),任务队列背后的核心想法是避免立即执行资源密集型的任务并不得不等待它完成,而是将任务封装成消息发送到一个队列中,然后由“消费者”来获取任务并依次执行,当有多个“消费者”的时候,它们会均匀的分配这些任务。默认情况下,RabbitMQ会轮流的将消息发送给“消费者”,这种分发消息的方式被称为“round-robin”。

        RabbitMQ支持“消息确认反馈”来确保消息不会因为“消费者”挂了而丢失——在消息被接收并处理之后,会给RabbitMQ发送一条确认,这样RabbitMQ就能将该消息删掉。如果没有收到确认,RabbitMQ会重发这条消息。RabbitMQ还支持消息持久化,来保证当RabbitMQ服务停止时消息不会丢失,这种情况下,RabbitMQ会将消息写到硬盘。

        发布/订阅模式——消息会被发送到所有它的“订阅者”

        **Exchange,**完整的RabbitMQ模型中还包含一个消息交换机。消息生产者先将消息发送给交换机,然后交换机再将消息发送给队列。交换机有一个属性叫exchange type能决定如何处理消息,比如是否该把一条消息推送给某一个队列或是某多个队列,还是应该把它丢弃掉。其属性值有:direct,topic,headers,fanout。

        exchange和队列之间的关系称为“binding”(它们之间有个binging key),消息会被路由到由其"routingKey"属性指定名称的队列中,如果没有队列绑定到exchange上,消息将会丢失。

        fanout exchange会把它接收到的消息广播到所有的队列,而direct exchange会匹配消息的routing key和队列的bingding key,然后将消息发送到与之匹配成功的队列上。没有匹配的消息将被丢弃。

        topic exchange,被发送到topic exchange的消息不能被指定一个随意的routing key,它必须是一个由"."分隔的单词的清单,这些单词通常指定了消息的某些特征,如"quick.orange.rabbit",单词数量的上限是255个字节。bingding key必须也是同样的形式,和direct exchange一样,带有特定routing key的消息会被发送到带有匹配bingding key的队列上,但是bingding key有两个重要的特点,"*"号可以代替一个单词,"#"可以代替0个或者多个单词,例如,"*.orange.*"的binding key会匹配所有routing key中第二个单词为orange的消息,而bingding key:"#"会匹配所有的消息。

        结合实际项目中的代码,看看如何在SpringMVC中配置RabbitMQ。

        通常会从Spring的配置文件中单独引出一个RabbitMQ的配置文件application-rabbit-context.xml,并将该配置文件中需要用到的一些参数值通过rabbit.properties配置文件单独配置。

        在pom中,会引入一个将Spring与RabbitMQ整合的依赖:

1<dependency> 2    <groupId>org.springframework.amqp</groupId> 3    <artifactId>spring-rabbit</artifactId> 4</dependency>

它会提供一个RabbitMQ Java Client来提供服务。然后我们要配置一个connect-factory,它里面定义了连接的主机、端口、用户名和密码等信息。(连接工厂创建连接,连接创建channel,channel声明队列,队列接收/发送消息)

1<rabbit:connection-factory  2    id="connectionFactory" 3    host="${rabbit.connect.host}"  4    port="${rabbit.connect.port}" 5    username="${rabbit.connect.username}"  6    password="${rabbit.connect.password}" 7    channel-cache-size="${rabbit.connect.channelCacheSize}" 8    publisher-returns="true"  9    publisher-confirms="true" />

        接下来是配置一个消息转换器,用来将消息转换为Json,方便消息在生产者和消费者之间传输。

1<bean id="messageConverter" 2    class="org.springframework.amqp.support.converter.SimpleMessageConverter" />

        然后会定义一个<rabbit:admin />,它的作用是在系统启动时自动得到exchange和queue的bean,并将它们在容器中注册。

        然后是生产者和消费者的定义,生产者会通过一个template发送消息,配置如下:

1<rabbit:template id="rabbitTemplate" 2    connection-factory="connectionFactory" message-converter="messageConverter" />

        配置消费者通常是配置一个queue,一个listener和一个listener container:

1<rabbit:queue id="TagRequestQueue" name="optag.request.queue" /> 2   3<bean id="TagRequestListener" class="com.ximalaya.tagging.backend.listener.TagRequestListener" /> 4   5<rabbit:listener-container 6    connection-factory="connectionFactory" message-converter="messageConverter"> 7    <rabbit:listener ref="TagRequestListener" queues="TagRequestQueue" /> 8</rabbit:listener-container>

        以上就完成了Spring中RabbitMQ的配置,在发送和接受消息的代码实现上,发送消息的类方法中会通过template的convertAndSend方法将消息对象发送出去,而消息接收类则通过实现MessageListener接口并重写其onMessage方法接收消息并做相应的处理。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )