工作中剛接觸mq消息業務,其實也就是監聽一下別的項目發送的消息然后進行對應的轉發,但是監聽的mq會有多個,而且轉發的地址也可能有多個,這里就使用spring集成的方式!記錄一下實現方式:
監聽多個mq配置,主要還是在xml或者配置類里進行配置多個,這里以兩個為例:
properties文件中配置好多個mq的tcp地址,
<!-- mq配置 --> <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="${amq.tpl.server}" /> </bean> <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <property name="targetConnectionFactory" ref="targetConnectionFactory" /> </bean> <!-- <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> </bean> --> <!-- 監聽的消息隊列 --> <bean id="wechatQueueDestination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>templateQueue</value> </constructor-arg> <!--可繼續配置多個隊列 --> </bean> <!-- 消息監聽器配置,引用制定的mq服務器與監聽隊列-> <bean id="templateMessageListener" class="com.zhuzher.amq.listener.TemplateMessageListener"/> <bean id="templateMessageContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="destination" ref="wechatQueueDestination" /> <property name="messageListener" ref="templateMessageListener" /> </bean>
多個,mq就切換不同的地址,配置不同的連接工廠就可以了,然后再配置監聽器!
然后就是消息轉發了,這里采用httpclient調用接口方式實現,然后將地址配置在數據庫中,達到高可擴展的目的,為了提高性能還可以在項目啟動的時候把地址加載的內存中,取地址就從內存中獲取,並提供一個刷新的接口即可!
這里直接貼上內存類的代碼:
//存儲轉發地址 public class ForwardAddressHelper { private static Logger log=Logger.getLogger(ForwardAddressHelper.class); @Autowired PmsForwardService pmsForwardService; //存儲轉發地址 private static List<PmsForwardAddress> address = new ArrayList<>(); private static ForwardAddressHelper forwardAddressHelper=null;//單例 //私有化構造函數 private ForwardAddressHelper(){} public static ForwardAddressHelper getInstance() { if (forwardAddressHelper == null) { synchronized (ForwardAddressHelper.class) { if (forwardAddressHelper == null) { forwardAddressHelper = new ForwardAddressHelper(); } } } return forwardAddressHelper; } /** * 初始化轉發地址 */ public void init(){ if(ForwardAddressHelper.address.size()==0){ System.out.println("----------------初始化成功----------------"); initAddress(); } } /** * 重載轉發地址 */ public void reLoad() { ForwardAddressHelper.address.clear(); init(); } /** * 初始化轉發地址數據 */ private void initAddress(){ log.info("--------------轉發地址初始化-----------"); ForwardAddressHelper.address.addAll(pmsForwardService.queryAddress()); } /** * 獲取所有轉發地址 */ public static List<PmsForwardAddress> getAddress(){ return ForwardAddressHelper.address; } }
,然后只需要在spring容器啟動的時候調用這個init方法就可以了,這里有兩種,一種是監聽器方式,還有一種是xml配置,這里我就直接使用xml了:
lazy-init="false" :表示容器加載立即執行
<bean id="forwardAddressHelper" lazy-init="false" class="com.helper.ForwardAddressHelper" init-method="init"/>
,然后就是寫消息監聽類了,實現具體業務,由於已經配置了監聽器,所以直接寫就行,這里直接上代碼,具體業務就是用httpclient調一遍接口,消息內容是接口的參數:
public class PmsMessageListener implements MessageListener { static Logger log=Logger.getLogger(PmsMessageListener.class); static final Gson GSON = new Gson(); @Autowired ForwardAddressHelper forwardAddressHelper; @Override public void onMessage(Message message) { log.debug("監聽器接收到消息:"+message); if(null == message || !(message instanceof TextMessage))return; TextMessage textMessage = (TextMessage) message; String text = null; try { text = textMessage.getText();log.debug("message:"+textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } if(StringUtil.isBlank(text))return; Map<String, String> messageMap = GSON.fromJson(text, new TypeToken<Map<String, String>>(){}.getType()); pmsForward(messageMap); } //消息轉發-獲取參數中對應參數調用對應接口 public void pmsForward(Map<String, String> map){ List<PmsForwardAddress> address = forwardAddressHelper.getAddress();//從內存獲取轉發地址 //封裝參數 List<NameValuePair> params = new ArrayList<NameValuePair>(); Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator(); while(iterator.hasNext()){ params.add(new BasicNameValuePair(iterator.next().getKey(),iterator.next().getValue())); } address.forEach(x->{ CloseableHttpResponse response = null; CloseableHttpClient httpClient = HttpClients.createDefault(); try { URIBuilder builder = new URIBuilder(x.getAddress()); builder.setParameters(params); HttpGet get = new HttpGet(builder.build()); response = httpClient.execute(get); if(response != null && response.getStatusLine().getStatusCode() == 200)log.info("消息轉發成功"); } catch (Exception e) {e.printStackTrace();log.error("消息轉發失敗"); } finally { try { httpClient.close();if(response != null)response.close(); } catch (IOException e) {e.printStackTrace();} } }); } }
PmsMessageListener 這個類配置在了xml文件中,會監聽我們指定的mq的消息隊列,只要有消息來就會取數據庫里配置的接口一一調用!