【RabbitMQ】RabbitMQ與Spring整合

00潤物無聲00發表於2017-03-19

  這裡我們使用RabbitMQ訊息通訊,後臺新增商品,通知前臺,刪除與商品相關的快取內容。在後臺系統中,我們定義交換器和模板。在前臺系統中定義佇列,監聽和模板。在Web的管理工具中繫結交換器和佇列;

後臺系統

1.在Pom.xml檔案中引入依賴

		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit</artifactId>
			<version>1.4.0.RELEASE</version>
		</dependency>


2.把RabbitMQ加入到Spring的管理中。

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

    <!-- 定義RabbitMQ的連線工廠 -->
    <rabbit:connection-factory id="connectionFactory"
                               host="${rabbitmq.ip}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.vhost}" />

	<!--  MQ的管理,包括佇列、交換器等,宣告交換器 -->
	<rabbit:admin connection-factory="connectionFactory"/>
                               
     <!-- 定義交換機,durable效能更高 -->
    <rabbit:topic-exchange name="TAOTAO-ITEM-EXCHANGE" auto-declare="true" durable="false"/>
    	
	<!-- 定義一個模板 -->
     <rabbit:template id="taotaoItemTemplate" connection-factory="connectionFactory" exchange="TAOTAO-ITEM-EXCHANGE"></rabbit:template>
                               
</beans>

3.屬性配置

rabbitmq.ip=127.0.0.1
rabbitmq.port=5672
rabbitmq.username=taotao
rabbitmq.password=taotao
rabbitmq.vhost=/taotao

4.後臺系統在新增商品的時候,向交換器中傳送訊息

@Service
public class ItemServiceImpl implements ItemService {

	@Autowired
	private TbItemMapper itemMapper;
	@Autowired
	private TbItemDescMapper itemDescMapper;
	@Autowired
	private TbItemParamItemMapper itemParamItemMapper;
	//****************************************************
	@Autowired
	private RabbitTemplate rabbitTemplate;

	private final static ObjectMapper MAPPER=new ObjectMapper();
	//****************************************************
	 * 新增商品資訊;
	 * itemParam商品規格引數
	 */
	@Override
	public TaotaoResult createItem(TbItem item, String desc,String itemParam) {
		//生成商品id
		long itemId = IDUtils.genItemId();
		//補全TbItem屬性
		item.setId(itemId);
		//商品狀態:1-正常,2-下架,3-刪除
		item.setStatus((byte)1);
		//建立時間和更新時間
		Date date = new Date();
		item.setCreated(date);
		item.setUpdated(date);
		//插入商品表
		itemMapper.insert(item);
		//商品描述
		TbItemDesc itemDesc = new TbItemDesc();
		itemDesc.setItemId(itemId);
		itemDesc.setItemDesc(desc);
		itemDesc.setCreated(date);
		itemDesc.setUpdated(date);
		//插入商品描述資料;
		itemDescMapper.insert(itemDesc);
		
		//商品規格引數
		TbItemParamItem itemParamItem = new TbItemParamItem();
		itemParamItem.setItemId(itemId);
		itemParamItem.setParamData(itemParam);
		itemParamItem.setCreated(date);
		itemParamItem.setUpdated(date);
		//插入商品規格引數;
		itemParamItemMapper.insert(itemParamItem);

		
		//***************************************************
		//傳送訊息給其他系統
		sendMsg(item.getId(), "insert");
		
		//****************************************************
		
		return TaotaoResult.ok();
	}
		
	//後臺系統關於RabbitMQ訊息通訊的配置;
	private void sendMsg(long itemId,String type)
	{
		//處理異常,不能影響正常的業務邏輯,所以應該抓取;
		try {
			//傳送訊息通知其他系統
			Map<String, Object> msg= new HashMap<String, Object>();
			msg.put("itemId", itemId);
			msg.put("type",type);
			msg.put("date", System.currentTimeMillis());
			//指定路由鍵和訊息
			//訊息中包含,商品Id;	
			this.rabbitTemplate.convertAndSend("item." + type,MAPPER.writeValueAsString(msg));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}

前臺系統


1和3拷貝到前臺系統相關位置

RabbitMQ的配置如下

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

	<!-- 前臺配置 -->
    <!-- 定義RabbitMQ的連線工廠 -->
    <rabbit:connection-factory id="connectionFactory"
                               host="${rabbitmq.ip}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.vhost}" />

	<!--  MQ的管理,包括佇列、交換器等 -->
	<rabbit:admin connection-factory="connectionFactory" />
	
	<!-- 定義佇列 -->
	<rabbit:queue name="TOATAO-WEB-ITEM-QUEUE"  auto-declare="true" durable="false"></rabbit:queue>

	<bean id="itemMQController" class="com.taotao.rest.mq.ItemMQController"></bean>                               
	<!-- 定義消費者監聽佇列-->
	<rabbit:listener-container connection-factory="connectionFactory">
		<rabbit:listener ref="itemMQController" method="execute" queue-names="TOATAO-WEB-ITEM-QUEUE"/>
	</rabbit:listener-container>
	<!-- 定義一個模板 -->
     <rabbit:template id="taotaoItemTemplate" connection-factory="connectionFactory" exchange="TAOTAO-ITEM-EXCHANGE"></rabbit:template>
                               
</beans>

  建立一個消費者,當新增商品的時候,刪除快取中商品字首的內容。

package com.taotao.rest.mq;

import java.util.Iterator;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taotao.rest.component.JedisClient;

	/**
	 * 商品訊息的處理
	 * @author fxq
	 *
	 */
	public class ItemMQController {

		private static final ObjectMapper MAPPER = new ObjectMapper();
		@Autowired
		private JedisClient jedisClient;
		@Value("${REDIS_ITEM_KEY}")
		private String REDIS_ITEM_KEY;
		@Value("${ITEM_BASE_INFO_KEY}")
		private String ITEM_BASE_INFO_KEY;
		
		public void execute(String msg)
		{
			//解析資料
			JsonNode jsonNode;
			try {
				jsonNode = MAPPER.readTree(msg);
				Long itemId = jsonNode.get("itemId").asLong();
				//刪除Redis中的快取資料;
				//jedisClient.del(REDIS_ITEM_KEY + ":" + itemId + ":"+ITEM_BASE_INFO_KEY);
				Set<String> keys = jedisClient.keys(REDIS_ITEM_KEY);
				Iterator<String> iterator = keys.iterator();
				while (iterator.hasNext()) {
					String key = (String) iterator.next();
					System.out.println(key);
					jedisClient.del(key);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 	
		}
	}

交換器和佇列繫結

  


  前臺系統和後臺系統,不直接呼叫,使用訊息進行通訊,實現解耦合與非同步通訊。


相關文章