工作中刚接触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. BAT等公司必问的8道Java经典面试题,你都会了吗?

    工作多年以及在面试中,我经常能体会到,有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因: 1.“知其然不知其所以然”.做了多年技术,开发了很多业务应用,但似乎并 ...

  2. 使用docker部署项目

    一.Dockerfile编写 FROM hub.c.163.com/library/java:8-alpine ADD target/*.jar app.jar EXPOSE 8761 ENTRYPO ...

  3. 使用 OpenGL API 播放 BIK 视频

    BIK作为在游戏中广泛使用的视频格式,这里就非常有必要普及一下了 直接贴代码,看注释吧.有不懂的地方就留言提问吧 /** * * 解码BIK视频文件为像素数据,使用PBO更新OpenGL纹理,绘制纹理 ...

  4. java并发编程中CountDownLatch和CyclicBarrier的使用

    在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景,遇到这样的场景应该如何解决? 如果是一个线程等待一个线程,则可以通过await()和notify()来实现: 如果是一个线程等待多个线程 ...

  5. cmake 常用变量和常用环境变量查表手册

    cmake 常用变量和常用环境变量查表手册 一,cmake 变量引用的方式: 前面我们已经提到了,使用${}进行变量的引用.在 IF 等语句中,是直接使用变量名而不通过${}取值 二,cmake 自定 ...

  6. BZOJ 2527 Meteors | 整体二分

    BZOJ 2527 Meteors 题意 一个圆环上有m个位置,编号为1~m,分别属于n个国家. 有k个时刻,每个时刻都会给圆环上的一个区间中每个位置的值加上一个数. 每个国家有一个目标,问对于每个国 ...

  7. hdu6057 Kanade's convolution 【FWT】

    题目链接 hdu6057 题意 给出序列\(A[0...2^{m} - 1]\)和\(B[0...2^{m} - 1]\),求所有 \[C[k] = \sum\limits_{i \; and \; ...

  8. BZOJ2159 Crash 的文明世界 【第二类斯特林数 + 树形dp】

    题目链接 BZOJ2159 题解 显然不能直接做点分之类的,观察式子中存在式子\(n^k\) 可以考虑到 \[n^k = \sum\limits_{i = 0} \begin{Bmatrix} k \ ...

  9. 【bzoj1031】 JSOI2007—字符加密Cipher

    http://www.lydsy.com/JudgeOnline/problem.php?id=1031 (题目链接) 题意 给出一个字符串,求它的加密串. Solution 很显然,将串倍长后求它的 ...

  10. Codeforces Educational Round 57

    这场出题人好像特别喜欢998244353,每个题里都放一个 A.Find Divisible 考察选手对输入输出的掌握 输出l 2*l即可(为啥你要放这个题,凑字数吗 #include<cstd ...