RabbitMQ項目使用配置

生產者配置:

<?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.xsd
            http://www.springframework.org/schema/rabbit
          http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">


   <rabbit:connection-factory id="connectionFactory"
host="10.153.25.15" username="insurance" password="insurance" port="5672" />

   <rabbit:admin connection-factory="connectionFactory" />

   <rabbit:queue id="queue_insurance" durable="true" auto-delete="false"
exclusive="false" name="queue_insurance">正常隊列當中指向死信
      <rabbit:queue-arguments>
         <entry key="x-message-ttl">設置超時
            <value type="java.lang.Long">30000</value>
         </entry>
         <entry key="x-dead-letter-exchange">指定交換機
            <value type="java.lang.String">alter</value>
         </entry>
      </rabbit:queue-arguments>
   </rabbit:queue>

   <rabbit:queue id="alter_queue" durable="true" auto-delete="false" exclusive="false" name="alter_queue"/>死信隊列

   <rabbit:direct-exchange name="alter"
durable="true" auto-delete="false" id="alter">死信交換機
      <rabbit:bindings>
         <rabbit:binding queue="alter_queue" key="queue_key_insurance"/>
      </rabbit:bindings>
   </rabbit:direct-exchange>
   <rabbit:direct-exchange name="exchange_insurance"
durable="true" auto-delete="false" id="exchange_insurance">正常交換機
      <rabbit:bindings>
         <rabbit:binding queue="queue_insurance" key="queue_key_insurance" />
      </rabbit:bindings>
   </rabbit:direct-exchange>

<!-- (5)客戶端投遞消息到exchange。 -->
<rabbit:template id="amqpTemplate" exchange="exchange_insurance"
connection-factory="connectionFactory" />
</beans>

消費者配置:

<?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.xsd
            http://www.springframework.org/schema/rabbit
          http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

<!-- 連接服務配置 -->
<rabbit:connection-factory id="connectionFactory2" host="10.153.25.15"
username="insurance" password="insurance" port="5672"  />
   <rabbit:admin connection-factory="connectionFactory2" />

<!-- queue 隊列聲明 -->
   <!-- queue 隊列聲明  name 隊裏的額name 是關聯生產表和消費表的爲唯一線索  -->
<rabbit:queue id="queue_insurance" name="queue_insurance" >
      <rabbit:queue-arguments value-type="java.lang.Long">
         <entry key="x-message-ttl" value="30000"/>
      </rabbit:queue-arguments>
   </rabbit:queue>

<!-- 定義消費者監聽器 -->
   <!-- 創建一個bean實例,bean實例中聲明處理請求的類 -->
<bean id="consumerLitener2" class="com.insurance.mq.CommissionController"></bean>

   <rabbit:listener-container
connection-factory="connectionFactory2" acknowledge="auto" concurrency="8">
<!-- queues屬性從那個隊列中接收消息,ref屬性是當存在消息是使用哪個類去處理 -->
<rabbit:listener queues="queue_insurance" ref="consumerLitener2" />
   </rabbit:listener-container>
</beans>

 

rabbitMq三種模式

一. Fanout Exchange  廣播

所有發送到Fanout Exchange的消息都會被轉發到與該Exchange 綁定(Binding)的所有Queue上。

Fanout Exchange  不需要處理RouteKey 。只需要簡單的將隊列綁定到exchange 上。這樣發送到exchange的消息都會被轉發到與該交換機綁定的所有隊列上。類似子網廣播,每臺子網內的主機都獲得了一份複製的消息。

所以,Fanout Exchange 轉發消息是最快的。

二. Direct Exchange  點對點

所有發送到Direct Exchange的消息被轉發到RouteKey中指定的Queue。

Direct模式,可以使用rabbitMQ自帶的Exchange:default Exchange 。所以不需要將Exchange進行任何綁定(binding)操作 。消息傳遞時,RouteKey必須完全匹配,纔會被隊列接收,否則該消息會被拋棄。

三. Topic Exchange  模糊匹配

所有發送到Topic Exchange的消息被轉發到所有關心RouteKey中指定Topic的Queue上,

Exchange 將RouteKey 和某Topic 進行模糊匹配。此時隊列需要綁定一個Topic。可以使用通配符進行模糊匹配,符號“#”匹配一個或多個詞,符號“*”匹配不多不少一個詞。因此“log.#”能夠匹配到“log.info.oa”,但是“log.*” 只會匹配到“log.error”。

所以,Topic Exchange 使用非常靈活。

 

mq也支持重發機制:

    rabbitmq的消息確認機制分兩部分

    一部分是生產端,一部分是消費端

    生產端

        有兩種選擇,transaction   和   confirm。confirm  的性能要好於transaction

                   //transaction 機制    
channel.txSelect();  
  
String msg = "msg  test !!!";  
for(int i=0;i<10000;i++){  
    msg = i+" : msg  test !!!";  
    channel.basicPublish(EXCHAGE, QUEUE_NAME,null,msg.getBytes());  
     System.out.println("publish msg "+msg);  
     if (i>0&&i%100==0){  
         //批量提交  
        channel.txCommit();  
     }  
           
} // 若出現異常 進行 channel.txRollback(),對相應批次的msg進行重發或記錄  
                    channel.txCommit();  

延遲隊列

AMQP和RabbitMQ本身沒有直接支持延遲隊列功能,但是可以通過以下特性模擬出延遲隊列的功能。 

但是我們可以通過RabbitMQ的兩個特性來曲線實現延遲隊列:

RabbitMQ可以針對Queue和Message設置 x-message-tt,來控制消息的生存時間,如果超時,則消息變爲dead letter

RabbitMQ針對隊列中的消息過期時間有兩種方法可以設置。

  • A: 通過隊列屬性設置,隊列中所有消息都有相同的過期時間。
  • B: 對消息進行單獨設置,每條消息TTL可以不同。

如果同時使用,則消息的過期時間以兩者之間TTL較小的那個數值爲準。消息在隊列的生存時間一旦超過設置的TTL值,就成爲dead letter

RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可選)兩個參數,如果隊列內出現了dead letter,則按照這兩個參數重新路由。

  • x-dead-letter-exchange:出現dead letter之後將dead letter重新發送到指定exchange
  • x-dead-letter-routing-key:指定routing-key發送

隊列出現dead letter的情況有:

  • 消息或者隊列的TTL過期
  • 隊列達到最大長度
  • 消息被消費端拒絕(basic.reject or basic.nack)並且requeue=false

利用DLX,當消息在一個隊列中變成死信後,它能被重新publish到另一個Exchange。這時候消息就可以重新被消費。

設置方法:

java client發送一條只能駐留60秒的消息到隊列:

byte[] messageBodyBytes = "Hello, world!".getBytes();AMQP.BasicProperties properties = new AMQP.BasicProperties();properties.setExpiration("60000");channel.basicPublish("my-exchange", "routing-key", properties, messageBodyBytes);

  • Queue TTL

創建一個隊列,隊列的消息過期時間爲30分鐘

java client方式:Map<String, Object> args = new HashMap<String, Object>();args.put("x-expires", 1800000);channel.queueDeclare("myqueue", false, false, false, args);rabbitmqctl命令方式rabbitmqctl set_policy expiry ".*" '{"expires":1800000}' --apply-to queuesrabbitmqctl (Windows) rabbitmqctl set_policy expiry ".*" "{""expires"":1800000}" --apply-to queues11

channel.exchangeDeclare("some.exchange.name", "direct");Map<String, Object> args = new HashMap<String, Object>();args.put("x-dead-letter-exchange", "some.exchange.name");args.put("x-dead-letter-routing-key", "some-routing-key");channel.queueDeclare("myqueue", false, false, false, args);

 

 

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