結合Spring,運行RabbitMQ

RabbitMQ是用erlang實現的消息隊列系統,遵循AMQP(高級消息隊列協議)協議。性能還有可擴展性優於其他相似的框架,當然,新星kafka也不錯,大家可以上網查一下各種MQ框架的優缺點。

參考一下其他文章:http://blog.csdn.net/linsongbin1/article/details/47781187


RabbitMQ主要有三種交換器:direct、fanout、topic

direct就是一對一傳輸

fanout就是匹配傳輸

topic就是主題分發傳輸

還是看代碼吧

maven構建:pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xin</groupId>
    <artifactId>com.xin.rabbitmq</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- spring版本號 -->
        <spring.version>3.2.8.RELEASE</spring.version>
        <!-- log4j日誌文件管理包版本 -->
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <!-- junit版本號 -->
        <junit.version>4.10</junit.version>
    </properties>

    <dependencies>
        <!-- 添加Spring依賴 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--單元測試依賴 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- 日誌文件管理包 -->
        <!-- log start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- log end -->

        <!--spring單元測試依賴 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

        <!--rabbitmq依賴 -->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.0.1.Final</version>
        </dependency>

    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <targetPath>${basedir}/target/classes</targetPath>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <targetPath>${basedir}/target/resources</targetPath>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <warSourceExcludes>${warExcludes}</warSourceExcludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4.3</version>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
            <plugin>
                <inherited>true</inherited>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

log4j的配置文件:log4j.properties

log4j.rootLogger=DEBUG,Console,Stdout

#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

log4j.appender.Stdout = org.apache.log4j.DailyRollingFileAppender
log4j.appender.Stdout.File = E://logs/log.log
log4j.appender.Stdout.Append = true
log4j.appender.Stdout.Threshold = DEBUG
log4j.appender.Stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

spring的配置文件:application.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:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">


    <import resource="classpath*:rabbitMq.xml" />


    <!-- 掃描指定package下所有帶有如@controller,@services,@resource,@ods並把所註釋的註冊爲Spring Beans -->
    <context:component-scan base-package="com.xin.consumer,com.xin.producer" />


    <!-- 激活annotation功能 -->
    <context:annotation-config />
    <!-- 激活annotation功能 -->
    <context:spring-configured />

</beans>

rabbitMq的配置文件:rabbitMq.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:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/rabbit
     http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd">
    <!--配置connection-factory,指定連接rabbit server參數 -->
    <rabbit:connection-factory id="connectionFactory"
                               username="guest" password="guest" host="localhost" port="5672" />


    <!--direct 一對一傳輸-->
    <!--定義rabbit template用於數據的接收和發送 -->
    <rabbit:template id="amqpTemplate"  connection-factory="connectionFactory"
                     exchange="exchangeTest" />

    <!--通過指定下面的admin信息,當前producer中的exchange和queue會在rabbitmq服務器上自動生成 -->
    <rabbit:admin connection-factory="connectionFactory" />

    <!--定義queue -->
    <rabbit:queue name="queueTest" durable="true" auto-delete="false" exclusive="false" />

    <!-- 定義direct exchange,綁定queueTest -->
    <rabbit:direct-exchange name="exchangeTest" durable="true" auto-delete="false">
        <rabbit:bindings>
            <rabbit:binding queue="queueTest" key="queueTestKey"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>


    <!-- 消息接收者 -->
    <bean id="messageReceiver" class="com.xin.consumer.MessageConsumer"></bean>

    <!-- queue litener  觀察 監聽模式 當有消息到達時會通知監聽在對應的隊列上的監聽對象-->
    <rabbit:listener-container connection-factory="connectionFactory">
        <rabbit:listener queues="queueTest" ref="messageReceiver"/>
    </rabbit:listener-container>











    <!--topic 匹配傳輸-->
    <rabbit:template id="topicTemplate"  connection-factory="connectionFactory"
                     exchange="topicExchange"/>

    <!--定義queue -->
    <rabbit:queue name="topicQueue" durable="true" auto-delete="false" exclusive="false" />

    <!--topic交換器 pattern與topicTemplate.convertAndSend("foo.bar",message);第一個參數匹配-->
    <rabbit:topic-exchange name="topicExchange">
        <rabbit:bindings>
            <rabbit:binding queue="topicQueue" pattern="info.*" />
        </rabbit:bindings>
    </rabbit:topic-exchange>

    <rabbit:listener-container connection-factory="connectionFactory">
        <rabbit:listener ref="topic1" queues="topicQueue"/>
    </rabbit:listener-container>

    <bean id="topic1" class="com.xin.consumer.TopicConsumer"/>








    <!--fanout 把一條消息通過多條隊列傳輸出去-->

    <rabbit:template id="fanoutTemplate"  connection-factory="connectionFactory"
                     exchange="fanoutExchange"/>

    <!--定義queue -->
    <rabbit:queue name="fanoutQueue" durable="true" auto-delete="false" exclusive="false" />
    <rabbit:queue name="fanoutQueue2" durable="true" auto-delete="false" exclusive="false" />

    <!--topic交換器-->
    <rabbit:fanout-exchange name="fanoutExchange">
        <rabbit:bindings>
            <rabbit:binding queue="fanoutQueue"></rabbit:binding>
            <rabbit:binding queue="fanoutQueue2"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:fanout-exchange>

    <rabbit:listener-container connection-factory="connectionFactory">
        <rabbit:listener ref="fanoutConsumer" queues="fanoutQueue"/>
        <rabbit:listener ref="fanoutConsumer2" method="foo" queues="fanoutQueue2"/>
    </rabbit:listener-container>

    <bean id="fanoutConsumer" class="com.xin.consumer.FanoutConsumer"/>
    <bean id="fanoutConsumer2" class="com.xin.consumer.FanoutConsumer2"/>

</beans>

實現direct交換器的傳輸:

生產端:MessageProducer

package com.xin.producer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Created by lhx on 2016/9/5 9:56
 *
 * @Description
 */
@Service
public class MessageProducer {

    private Logger logger = LoggerFactory.getLogger(MessageProducer.class);

    @Resource
    private AmqpTemplate amqpTemplate;

    public void sendMessage(Object message){
        logger.info("to send message:{}",message);
        amqpTemplate.convertAndSend("queueTestKey",message);
    }
}

消費端:MessageConsumer

package com.xin.consumer;

import com.xin.producer.MessageProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by lhx on 2016/9/5 9:57
 *
 * @Description 消費接收
 */
public class MessageConsumer implements MessageListener {

    private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);

    @Override
    public void onMessage(Message message) {
        logger.info("receive message:{}",message);
        System.out.println(new String(message.getBody()));
    }

    public static void main(final String... args) throws Exception {
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
        MessageProducer messageProducer = (MessageProducer) ctx.getBean("messageProducer");
        messageProducer.sendMessage("-------------hello,xin3453465465467456456456^^^^^^66666!");
        Thread.sleep(1000);
        ctx.destroy();
    }

}

運行main函數,服務端推消息到客戶端,客戶端就會收到message,打印出來。

2016-09-06 10:29:27,659 [main] INFO  [com.xin.producer.TopicProducer] - to send message:++++++++++++++++++hello,xin3453465465467456456456^^^^^^66666!hello,xin
2016-09-06 10:29:27,676 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Received message: (Body:'++++++++++++++++++hello,xin3453465465467456456456^^^^^^66666!hello,xin'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=topicExchange, receivedRoutingKey=info.debug, deliveryTag=1, messageCount=0])
(Body:'++++++++++++++++++hello,xin3453465465467456456456^^^^^^66666!hello,xin'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=topicExchange, receivedRoutingKey=info.debug, deliveryTag=1, messageCount=0])
++++++++++++++++++hello,xin3453465465467456456456^^^^^^66666!hello,xin
 

其他交換器的實現類似,請參考我的git項目:https://github.com/888xin/rabbitmq

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章