Spring Integration RabbitMq

Spring Integration RabbitMq 

First, the basic configuration

1, pom add the following jar

     <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.amqp/spring-rabbit -->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>2.1.7.RELEASE</version>
        </dependency>

2, spring configuration file to add the following configuration springContext.xml

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

    <!-- 激活spring的注解. -->
    <context:annotation-config />
    <context:component-scan base-package="com.pinghengxing..*">
    </context:component-scan>
    <!-- rabbitmq producer配置 -->
   <import resource="classpath*:com/config/rabbitmq_producer.xml" />
   
       <!-- rabbitmq consumer配置 -->
   <import resource="classpath*:com/config/rabbitmq_consumer.xml" />
    
</beans>

 

3, rabbitmq_producer.xml producer configured as follows (wherein the configuration of the three types of exchange: fanout, direct, topic)

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    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/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/rabbit
            http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
    
    
    <!-- 引入rabbitmq配置文件 -->
    <context:property-placeholder  location="classpath:/com/config/rabbitmq.properties" />
    
    <!--连接工厂 publisher-confirms,publisher-returns等参数,用于消息确认-->
    <rabbit:connection-factory id="rabbitConnectionFactory"
    host="140.143.xx.xx" username="ww" password="ww" port="5672"
    virtual-host="ww" channel-cache-size="25" cache-mode="CHANNEL"
    publisher-confirms="true" publisher-returns="true" connection-timeout="200" />
    
    <!--定义admin,producer of the exchange, queue automatically generated automatically by the admin in the mq ->
    <rabbit:admin id="rabbitAdmin" connection-factory="rabbitConnectionFactory"/>
    
    <bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
        <property name="backOffPolicy">
            <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                <property name="initialInterval" value="200" />
                <property name="maxInterval" value="30000" />
            </bean>
        </property>
        <property name="retryPolicy">
            <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
                <property name="maxAttempts" value="5"/>
            </bean>
        </property>
    </bean>
    

    <! - rabbitmq defined template may specify connection factory, exchange, queue, etc. ->
    <rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" retry-template="retryTemplate" 
     message-converter="jsonMessageConverter" confirm-callback="confirmCallback" return-callback="returnCallback" mandatory="true" 
    />
    
<!--     <rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" retry-template="retryTemplate"  -->
<!--      message-converter="jsonMessageConverter" confirm-callback="confirmCallback" return-callback="returnCallback" mandatory="true"  -->
<!--      exchange="myTopicExchange"= Key-routing "error.1" /> -> to trueto false,to true
    
    
    <- Queue statement:! Durable:  : when the server is restarted, can survive exclusive: whether private queue, if private, other channels can not access this queue 
    autodelete: when there is no consumer use, automatically delete the queue, if the queue is automatically deleted when the connection is closed ; -> 
    <! - for publish / subscribe model queue -> 
    <Rabbit: queue name = "myFanoutQueue" Durable = "to true" exclusive = "to false" Auto-Delete = "to false" /> 
    <Rabbit: name = queue "myFanoutQueue2" Durable = "to true" exclusive = "to false" Auto-Delete = "to false" /> 
    ! <- queues for routing mode -> 
    <Rabbit: queue name = "myDirectQueue" Durable = " to true "exclusive =" to false "Auto-Delete =" to false "/> 
    <- queue for the theme ->! 
    <Rabbit: queue name =" myTopicQueue_error "Durable ="true" exclusive="false" auto-delete="false"/>
    <rabbit:queue name="myTopicQueue_warn" durable="true" exclusive="false" auto-delete="false"/>false "/> 
    ! <- defined Switches publish / subscribe model -> 
    <The Rabbit: fanout the Exchange-name =" myFanoutExchange "Durable =" to true "Auto-the Delete =" false ">
        <rabbit:bindings>
            <rabbit:binding queue="myFanoutQueue"></rabbit:binding>
            <rabbit:binding queue="myFanoutQueue2"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:fanout-exchange>
    
    
    <!-- 定义交换机 路由模式(需要routing-key-->
    <rabbit:direct-exchange name="myDirectExchange" durable="true" auto-delete="false">
        <rabbit:bindings>
            <rabbit:binding queue="myDirectQueue" key="direct"></rabbit:binding>
    <- Switch defined theme! ->
    </ Rabbit: Direct-Exchange>
        </ Rabbit: Bindings>
    <rabbit:topic-exchange  name="myTopicExchange" durable="true" auto-delete="false">
        <rabbit:bindings>
            <rabbit:binding queue="myTopicQueue_error"  pattern="error.#"></rabbit:binding>
            <rabbit:binding queue="myTopicQueue_error" pattern="warn.#"></rabbit:binding>
            <rabbit:binding queue="myTopicQueue_warn" pattern="warn.*"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>
    
    <!--消息转换器,转成json格式-->
    <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter"></bean>class
<! - <bean the above mentioned id = "confirmCallback"
    <-! ConfirmCallback callback ->
    
    
    <-! You can also annotate way ->="com.pinghengxing.callback.ConfirmCallBack"/> -->
    <!--returnCallback回调 -->
<!--     <bean id="returnCallback" class="com.pinghengxing.callback.ReturnCallBack"/> -->
        

    
    
</beans>

 

. 3, rabbitmq_consumer.xml consumer configured as follows :( defines the consumer queue corresponding to the type of three kinds of exchange,)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    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/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/rabbit
            HTTP: // www.springframework.org/schema/rabbit/spring-rabbit.xsd ">
    
     
    <- introduced rabbitmq Profiles ->! 
    <context: Property-placeholder LOCATION =" the CLASSPATH: / COM / config / rabbitmq. Properties "/> 
    
    ! <- connection factory publisher-confirms, publisher-returns and other parameters, a message acknowledgment -> 
    <Rabbit: connection factory-ID =" rabbitConnectionFactory " 
    Host =" 140.143.xx.xx "username =" WW "password =" WW "Port =" 5672 " 
    Virtual -host =" WW "Cache-Channel-size =" 25 "Cache-MODE =" the CHANNEL " 
     Connection -timeout =" 200 is "/> 

    
    <-! defined listener -> 
    <!- - Concurrency is the number of concurrent provided consumers each listener in the initialization setting, prefetch is the number of each message to be taken from the disposable consumer broker from the inside
        Each consumer has a corresponding listener Exclusive parameter, the default is false, if set to true, concurrency must be set to 1, that is, only a single message queue consumer spending,
        Applies to the message queue must be strictly implemented consumer order (First In First Out). -> 
    <The Rabbit: Connection-listener-Container Factory's = "rabbitConnectionFactory" Acknowledge = "Manual" 
    prefetch = "1" Concurrency = "1"> 
        ! <- Publish-Subscribe listening mode -> 
        <The Rabbit: listener ref = " fanOutReceiver "Queue-names =" myFanoutQueue "/> 
        <Rabbit: REF = listener" fanOutReceiver2 "Queue-names =" myFanoutQueue2 "/> 
        
        ! <- routing mode listener -> 
        <Rabbit: REF = listener" directReceiver "queue- = names "myDirectQueue" /> 
        <Rabbit: REF = listener "directReceiver2" Queue-names = "myDirectQueue" /> 
        <Rabbit:
        <rabbit:listener ref="topicWarnReceiver" queue-names="myTopicQueue_warn"/>
    </rabbit:listener-container>
    
    <!--消费者实现类,也可以使用注解方式 -->
<!--     <bean id="directReceiver" class="com.pinghengxing.direct.DirectReceiver"/> -->
<!--     <bean id="fanOutReceiver" class="com.pinghengxing.fanout.FanOutReceiver"/> -->
<!--     <bean id="fanOutReceiver2" class="com.pinghengxing.fanout.FanOutReceiver2"/> -->
<!--     <bean id="topicErrorReceiver" class="com.pinghengxing.topic.TopicErrorReceiver"/> -->
<!--     <bean id="topicWarnReceiver" class="com.pinghengxing.topic.TopicWarnReceiver"/> -->

</beans>

Second, the test code write (Direct table here only test code write switch type, other types can be modeled in this example)

1, the definition of a message producer (DirectProducer)

package com.pinghengxing.direct;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/** 
 * @author ww
 */

public class DirectProducer {
    
    
    private static ApplicationContext ac;

    public static void sendMessage(String exchange,String routingKey,Object message){
        ac = new ClassPathXmlApplicationContext("classpath:com/config/springContext.xml");
        RabbitTemplate rt = ac.getBean(RabbitTemplate.class);
        
        for(int i=0;i<10;i++){
            rt.convertAndSend(exchange, routingKey, message+""+i);
        }
    }
     
    public static void main(String[] args) {
        DirectProducer.sendMessage("myDirectExchange","direct","路由模式");
    }

    
    
}  

2, the definition of message consumers (DirectReceiver1, DirectReceiver1) - a plurality of consumers

Consumer 1

package com.pinghengxing.direct;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;
@Component("directReceiver")
public class DirectReceiver implements ChannelAwareMessageListener{
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        System.out.println("************************direct111********************************"); 
        System.out.println ( "Routing mode direct111 receive information:" + new new String (message.getBody ())); 
        System.out.println ( "*************** ***************************************** " );
         // set manually answer
 / /         IF (to true) {
 //             the throw new new Exception ();
 //         } 
        channel.basicAck (. message.getMessageProperties () getDeliveryTag (), to false ); 
                    
    } 

    
}

Consumer 2

package com.pinghengxing.direct;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;
@Component("directReceiver2")
public class DirectReceiver2 implements ChannelAwareMessageListener{
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        System.out.println("************************direct222********************************"); 
        System.out.println ( "Routing mode direct222 receive information:" + new new String (message.getBody ())); 
        System.out.println ( "*************** ***************************************** " );
         // set manually answer
 / /         IF (to true) {
 //             the throw new new Exception ();
 //         } 
        channel.basicAck (. message.getMessageProperties () getDeliveryTag (), to false ); 
                    
    } 

    
}

 

Third, the test

1, the test results are as follows :( two consumers can take the data from the queue, and the data will not be repeated)

 

Four, confirm-callback monitor (monitor exchange for whether reception was successful)

1, when connected to the plant configuration is provided publisher-confirms = "true"

<rabbit:connection-factory id="rabbitConnectionFactory"
    host="140.143.xx.xx" username="ww" password="ww" port="5672"
    virtual-host="ww" channel-cache-size="25" cache-mode="CHANNEL"
    publisher-confirms="true" publisher-returns="true" connection-timeout="200" />

2, when defining rabbitmq template, confirm-callback specified implementation class

<rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" retry-template="retryTemplate" 
     message-converter="jsonMessageConverter" confirm-callback="confirmCallback" return-callback="returnCallback" mandatory="true" 
    />

3. Create the implementation class ConfirmCallback, implement the interface RabbitTemplate.ConfirmCallback

 

Package com.pinghengxing.callback; 

Import org.springframework.amqp.rabbit.connection.CorrelationData;
 Import org.springframework.amqp.rabbit.core.RabbitTemplate;
 Import org.springframework.stereotype.Component; 

/ ** 
 * Confirm the callback listener- (for monitoring whether reception was successful exchange) 
 * @author WW 
 * 
 * / 
@Component ( "confirmCallback" )
 public  class ConfirmCallBack the implements   RabbitTemplate.ConfirmCallback { 

    / ** 
    * CorrelationData parameter is passed to the callback method when sending the message, can be used to distinguish the message object. CorrelationData object has only one property String id. 
    * With this parameter, we can distinguish between what is currently a callback when a message is sent, and the failure to carry out retransmission function parameters by ack
    * @Param data correlationData callback. 
    * @Param ACK to true for ACK, NACK for false 
    * @param the cause is devoted to an optional reason NACK prepared, otherwise, it is null.
    * / 
    Public  void Confirm (CorrelationData correlationData, Boolean ACK, the cause is String) { 
        System.out.println ( "*************************** **************************************************************** " ); 
        System.out.println ( " confirm Exchange "ACK + +" "+ the cause is) ; 
        System.out.println ( "****************************************** ************** " ); 
    } 
    
}

4, the test

Five, returnCallback monitor (basicpublish push message to the callback failure queue)

1、在配置工厂连接的时候,设置publisher-returns="true"

<rabbit:connection-factory id="rabbitConnectionFactory"
host="140.143.xx.xx" username="ww" password="ww" port="5672"
virtual-host="ww" channel-cache-size="25" cache-mode="CHANNEL"
publisher-confirms="true" publisher-returns="true" connection-timeout="200" />

2、在定义rabbitmq模板时,指定return-callback的实现类,并且设置mandatory="true"

    <rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" retry-template="retryTemplate" 
     message-converter="jsonMessageConverter" confirm-callback="confirmCallback" return-callback="returnCallback" mandatory="true" 
    />

3、创建实现类ReturnCallBack,实现RabbitTemplate.ReturnCallback接口

package com.pinghengxing.callback;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

/**
 * 推送消息到queue失败时回调
 * @author ww
 *
 */
@Component("returnCallback")
public class ReturnCallBack implements RabbitTemplate.ReturnCallback {
    
    
        @Override
        public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
            System.out.println("********************************************************");
            System.out.println("失败确认:"+message+" | "+replyCode+" | "+replyText+" | "+exchange+" | "+routingKey);
            System.out.println("********************************************************");
        }


}

 4、测试(更改routing_key的值为direct123,由于找不到对应的队列,报以下错误)

六、json转换(可以将map等自动转换成json格式)

1、pom.xml添加以下maven依赖

      <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.5</version>
        </dependency>

 2、定义消息转换器,转成json格式

<!--消息转换器,转成json格式-->
    <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter"></bean>

 

3、在定义rabbitmq模板时,指定转换器message-converter="jsonMessageConverter"

    <rabbit:template id="amqpTemplate" connection-factory="rabbitConnectionFactory" retry-template="retryTemplate" 
     message-converter="jsonMessageConverter" confirm-callback="confirmCallback" return-callback="returnCallback" mandatory="true" 
    />

 

 4、测试,创建map,进行生产,消费者接收到的信息如下:为json格式

 

友情链接:

完整的项目配置下载地址如下:可下载参考

https://files.cnblogs.com/files/pinghengxing/spring_rabbitmq_test.zip

 

Guess you like

Origin www.cnblogs.com/pinghengxing/p/11210295.html
Recommended