工作中刚接触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的消息队列,只要有消息来就会取数据库里配置的接口一一调用!

ActiveMQ监听消息并进行转发,监听不同的mq服务器和不同的队列的更多相关文章

  1. Android监听消息通知栏点击事件

    Android监听消息通知栏点击事件 使用BroadCastReceiver 1 新建一个NotificationClickReceiver 类,并且在清单文件中注册!! public class N ...

  2. 问题1:Oracle数据库监听启动失败(重启监听,提示The listener supports no services)

    编辑监听文件:/home/DB/oracle/11gR2/db/network/admin/listener.ora 在文件内添加静态监听实例,如下内容: SID_LIST_LISTENER =(SI ...

  3. 监听程序未启动或数据库服务未注册到该监听程序。启动该监听程序并注册数据库服务 然后重新运行 em configuration assistant。

    在WIN 7/64Bit上安装ORACLE 11gR2后,管理网页Database Control(如:https://localhost:1158/em)始终登录不进去,总是说密码错误,使用配置工具 ...

  4. ActiveMQ点对点的消息发送案例

    公司最近会用MQ对某些业务进行处理,所以,这次我下载了apache-activemq-5.12.0-bin把玩下. 基于练习方便需要,使用Windows的版本. 参考的优秀文章: activemq的几 ...

  5. ActiveMQ发布-订阅消息模式(同点对点模式的区别)

    点对点与发布订阅最初是由JMS定义的.这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅) 点对点: 消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费 ...

  6. 实战Spring4+ActiveMQ整合实现消息队列(生产者+消费者)

    引言: 最近公司做了一个以信息安全为主的项目,其中有一个业务需求就是,项目定时监控操作用户的行为,对于一些违规操作严重的行为,以发送邮件(ForMail)的形式进行邮件告警,可能是多人,也可能是一个人 ...

  7. (二)ActiveMQ之点对点消息实现

    一.点对点消息实现概念 在点对点或队列模型下,一个生产者向一个特定的队列发布消息,一个消费者从该队列中读取消息.这里,生产者知道消费者的队列,并直接将消息发送到消费者的队列.这种模式被概括为:只有一个 ...

  8. 使用ActiveMQ实现JMS消息通信服务

    PTP(点对点的消息模型) 在点对点模型中,相当于两个人打电话,两个人独享一条通信线路.一方发送消息,一方接收消息. 在p2p的模型中,双方通过队列交流,一个队列只有一个生产者和一个消费者. 1.建立 ...

  9. 【ActiveMQ】持久化消息队列的三种方式

    1.ActiveMQ消息持久化方式,分别是:文件.mysql数据库.oracle数据库 2.修改方式: a.文件持久化: ActiveMQ默认的消息保存方式,一般如果没有修改过其他持久化方式的话可以不 ...

随机推荐

  1. c语言宏定义#define

    1. 利用define来定义 数值宏常量 #define 宏定义是个演技非常高超的替身演员,但也会经常耍大牌的,所以我们用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码就就都认 ...

  2. 【洛谷P4706】取石子

    Description ​ 现在 Yopilla 和 yww 要开始玩游戏! ​ 他们在一条直线上标记了 \(n\) 个点,从左往右依次标号为 \(1, 2, ..., n\) .然后在每个点上放置一 ...

  3. 洛谷 P2048 [NOI2010]超级钢琴 解题报告

    P2048 [NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为 ...

  4. bzoj 4451 : [Cerc2015]Frightful Formula FFT

    4451: [Cerc2015]Frightful Formula Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 177  Solved: 57[Sub ...

  5. 在前台jsp页面中取得并使用后台放入域中变量的方法

    定义成 js变量后,在js中也可以自由使用.

  6. Chapter 3(线性表)

    1.单链表 //单链表代码,手打纯手工 //***********************************link.h*********************************** # ...

  7. UVAL 7902 2016ECfinal F - Mr. Panda and Fantastic Beasts

    题意: 给出n个串,求一个最短的第一个串的子串使它不在其他的n-1个串中出现,若有多个求字典序最小的. Limits: • 1 ≤ T ≤ 42. • 2 ≤ N ≤ 50000. • N ≤ S1 ...

  8. Ansible9:条件语句

    目录 一.when 1.基本用法 2.在when中使用jinja2的语法 3.使用bool值作为when的判断条件 4.在when中使用defined关键字 5.when在循环语句中的使用方法 6.在 ...

  9. 数据分析与展示---Matplotlib入门

    简介: 一:Matplotlib库的介绍 (一)简单使用 二:区域划分subplot 三:plot函数 四:pyplot的中文显示 (一)方法一:修改rcParams参数 (二)方法二(推荐),在有中 ...

  10. snprintf()解析

    snprintf(ssid_mac,sizeof(ssid_mac),"%s_%02X%02X",ssid,macval[4],macval[5]); ssid_mac = ssi ...