Spring整合RabbitMQ(Fanout模式)

RabbitMQ是流行的开源消息队列系统,用erlang语言开发,RabbitMQ是AMQP的标准实现。写本篇文章之前,先了解下几个关于RabbitMQ重要的概念:

1、Exchange:交换机,决定了消息路由规则;

2、Queue:消息队列,每个消息都会被投入到一个或多个队列;

3、Channel:进行消息读写的通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务;

4、Binding:绑定了Queue和Exchange,意即为符合什么样路由规则的消息,将会放置入哪一个消息对列;

5、Routing Key:路由关键字,exchange根据这个关键字进行消息投递;

6、vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离;

7、producer:消息生产者,就是投递消息的程序;
8、consumer:消息消费者,就是接受消息的程序;

RabbitMQ消息的核心思想是消息不直接发送到队列,而是发送到交换器中(exchange),实际上,一般的情况下,生产者可能不知道将消息发送到哪个队列上。交换器的作用就是将生产者发送的消息接收过来,然后推送到队列。至于交换器将接收到的消息怎么推送到对应的队列,或者按照什么规则将消息推送出去,这些规则则有交换器类型定义:交换器的类型常用有三种direct、topic,fanout。本文将讲解fanout类型的交换器,fanout 类型的交换器非常简单,它是将所有收到的消息广播到所有它所知道的队列。

下面是Spring整合RabbitMQ的示例:

一、消息发送者的application-mq.xml配置:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

    <!-- rabbitmq connection configuration -->
    <bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
        <property name="host" value="127.0.0.1" />
        <property name="port" value="5762" />
        <property name="username" value="admin" />
        <property name="password" value="admin123" />
        <property name="virtualHost" value="/" />
    </bean>

    <rabbit:admin id="rabbitAdmin" connection-factory="rabbitConnectionFactory" auto-startup="true"/>

   
    <bean id="testMessageConverter" class="com.xxx.xxx.SpringAMQPJsonMessageConverter">
        <constructor-arg name="clzName" value="com.xxx.xxx.TestMessageBO" />
    </bean>
 <!-- 消息发送 -->
    <rabbit:fanout-exchange id="fanoutChannel" name="fanout-channel" auto-declare="true" declared-by="rabbitAdmin"/>
    <rabbit:template id="testTemplate" connection-factory="rabbitConnectionFactory"
         exchange="fanout-channel" message-converter="testMessageConverter" />

</beans>

其中SpringAMQPJsonMessageConverter.java自定义用于封装消息转化,继承AbstractJsonMessageConverter:

public class SpringAMQPJsonMessageConverter extends AbstractJsonMessageConverter {
    private String clzName;

    public SpringAMQPJsonMessageConverter(String clzName) {
        this.clzName = clzName;
    }

    @Override
    protected Message createMessage(Object o, MessageProperties messageProperties) {
        try {
            String e = JSON.toJSONString(o);
            byte[] bytes = e.getBytes(this.getDefaultCharset());
            messageProperties.setContentType("application/json");
            messageProperties.setContentEncoding(this.getDefaultCharset());
            messageProperties.setContentLength((long)bytes.length);
            return new Message(bytes, messageProperties);
        } catch (Exception e) {
            throw new MessageConversionException("error happened when create json message", e);
        }
    }

    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        try {
            byte[] body = message.getBody();
            String bodyStr = new String(body, this.getDefaultCharset());
            Class<?> clz = Class.forName(clzName);
            return JSON.parseObject(bodyStr, clz);
        } catch (Exception e) {
            throw new MessageConversionException("error happened when parse json message", e);
        }
    }

}

TestMessageBO.java则封装了要发送消息的实体,内容略。

消息发送:

public class SpringAmqpTest {

    @Autowired
    private RabbitTemplate testTemplate;

    @Test
    public void testSend() {
        TestMessageBO messageBO = new TestMessageBO();
        messageBO.setXXX(id);
        messageBO.setYYY("content")
        testTemplate.convertAndSend(messageBO);//使用默认的路由键名:routingKey=""
    }

}

至此完成了消息生产者的整合。下面是消息消费者的配置:

二、消息消费者的application-mq.xml配置:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

    <!-- rabbitmq connection configuration -->
    <bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
        <property name="host" value="127.0.0.1" />
        <property name="port" value="5762" />
        <property name="username" value="admin" />
        <property name="password" value="admin123" />
        <property name="virtualHost" value="/" />
    </bean>
    <bean id="testMessageConverter" class="com.xxx.xxx.SpringAMQPJsonMessageConverter">
        <constructor-arg name="clzName" value="com.xxx.xxx.TestMessageBO" />
    </bean>
    <!--消息队列可以任意定义,fanout模式不关心队列-->
    <rabbit:queue id = "testMessageExchangeQueue" name = "test_message_exchange_queue"/>
    <!--exchange对应消息生产者的exchange定义-->
    <rabbit:fanout-exchange id = "testMessageExchange" name="fanout-channel">
        <rabbit:bindings>
            <rabbit:binding queue="test_message_exchange_queue"/>
        </rabbit:bindings>
    </rabbit:fanout-exchange>
    <bean id="testMessageConsumer" class="com.xxx.xxx.consumer.TestMessageConsumer" />
    <rabbit:listener-container id = "testMessageListenerContainer" connection-factory="rabbitConnectionFactory" concurrency="3" message-converter="testMessageConverter">
        <rabbit:listener ref="testMessageConsumer" method="onMessage" queues="testMessageExchangeQueue"/>
    </rabbit:listener-container>

</beans>

消息消费consumer类:

public class TestMessageConsumer implements MessageConsumer {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestMessageConsumer.class);

    @Override
    public void onMessage(Object msg) {
        try{
            //接收的消息处理
        } catch (Exception e) {

        }
    }
//其中MessageConsumer.java如下:
public interface MessageConsumer {

    public void onMessage(Object msg);

}

至此完成了消息消费者的整合

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值