工作中刚接触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. iOS 企业账号申请证书和打包ipa

    准备: 299美元的企业账号. 1.登陆苹果开发者中心: https://developer.apple.com .点击Menber Center.输入企业账号和密码登陆. 2.登陆后选择“Certi ...

  2. DPDK环境搭建

    一.环境要求  1.内核版本 >= 2.6.34:  2.glibc版本 >= 2.7 (ldd --version 查看glibc版本):  3.gcc版本 >= 4.9,一些gc ...

  3. CentOS6.7的安装

    VMware9的安装请阅读:  http://www.cnblogs.com/duanji/p/yueding.html CentOS6.7在VMware9中安装 1.启动VMware的画面 2.点击 ...

  4. BZOJ5389 比例查询 【离线】

    题目链接 BZOJ5389 题解 太\(sb\)了,这种题都想不出来 发现复杂度允许\(n\sqrt{n}\),我们可以对于每个位置\(\sqrt{n}\)枚举约数,然后维护比例的最晚出现的位置,维护 ...

  5. Java EE之表达式语言EL(下)

    1.在EL表达式中使用作用域变量 表达式语言对作用域变量的支持,以及它解析变量的方式都使它变得非常有用. 1.1 EL表达式的隐式变量 EL表达式的作用域中定义了11个隐式变量. 当EL表达式引用了一 ...

  6. 书架 bookshelf

    书架 bookshelf 题目描述 当Farmer John闲下来的时候,他喜欢坐下来读一本好书. 多年来,他已经收集了N本书 (1 <= N <= 100,000). 他想要建立一个多层 ...

  7. CentOS 6.5下Squid代理服务器的安装与配置

    1.1   缓存代理概述 作为应用层的代理服务器软件,squid主要提供缓存加速,应用层过滤控制的功能. 1.  代理的工作机制 当客户机通过代理来请求web页面时,指定的代理服务器会先检查自己的缓存 ...

  8. web页面的绝对路径

    在JavaWeb开发中,常使用绝对路径的方式来引入JavaScript和CSS文件,这样可以避免因为目录变动导致引入文件找不到的情况,常用的做法如下:一.使用${pageContext.request ...

  9. Chapter5 (语句) --C++Prime笔记

    1.指用是一个只含有一个单独的分号的语句. 什么时候用到:语法上需要一条语句但是逻辑上不需要. 2.复合语句是指用花括号括起来的语句和声明的序列,又被称为块. 3.悬垂else :规定else与离它最 ...

  10. 报错laravel/horizon v1.4.3 requires ext-pcntl * -> the requested PHP extension pcntl is missing from your system.的解决办法

    执行composer install后报以下错误: Problem 1 - laravel/horizon v1.4.3 requires ext-pcntl * -> the requeste ...