CMS项目集成ActiveMq,此项目采用的为Queue点对点模式。
此项目采用的的tomcat,内嵌时启动activemq 61616 端口
Win:
查看占用的端口号:
netstat -aon|findstr “61616”
PS:注意weblogic服务是不能一次启动两个端口的。所以不能使用内嵌式的方式
求留言一些好的技术文档学一学
一、Mq+Spring的配置(内嵌式)
1.1 POM文件中添加
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
1.2 新建activeMq.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<context:property-placeholder location="classpath:config/activeMqConfig.properties"/>
<bean id="broker" class="org.apache.activemq.broker.BrokerService" init-method="start" destroy-method="stop">
<property name="brokerName" value="myBroker"/>
<property name="persistent" value="false"/>
<property name="transportConnectorURIs">
<list>
<value>${DEFAULT_BROKER_URL_TWO}</value>
</list>
</property>
</bean>
</beans>
1.3 加载xml文件,启动ActiveMq
ApplicationContext ac = new ClassPathXmlApplicationContext("activeMq.xml");
1.4 消息发送
/**
* 内嵌式发送消息
* @throws JMSException
*/
@SneakyThrows
public void CreateandSendNewsTemp(long siteId, int str, long channelId, long docId, long recId, long publishId, String canPubStatus, String recIds, String method, int strCh){
Connection connection = null;
Session session = null;
ResourceBundle resource = ResourceBundle.getBundle("config/activeMqConfig");
try {
String mqConnUrl =resource.getString("DEFAULT_BROKER_URL_TWO");
String connUrl = "failover:(" + mqConnUrl.trim()+ ")?initialReconnectDelay=1000&maxReconnectDelay=30000";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(resource.getString("DEFAULT_USER"), resource.getString("DEFAULT_PASSWORD"), connUrl);
//如果 ActiveMQ 连不上,则抛异常:java.net.ConnectException: Connection refused: connect
connection = connectionFactory.createConnection();//通过连接工厂获取连接 javax.jms.Connection
connection.start();//启动连接,同理还有 stop、close
/**Session createSession(boolean transacted, int acknowledgeMode) 创建会话*/
session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
/**
* createQueue(String queueName):创建消息队列,指定队列名称,消费者可以根据队列名称获取消息
* Destination 目的地,重点,interface Queue extends Destination
*/
Destination destination = session.createQueue(resource.getString("DESTINATION"));
//createProducer(Destination destination):根据目的地创建消息生产者
MessageProducer producer = session.createProducer(destination);
HashMap<String,Object> map=new HashMap<String, Object>();
map.put("siteId", siteId);
map.put("str", str);
map.put("channelId", channelId);
map.put("docId", docId);
map.put("recId", recId);
map.put("publishId", publishId);
map.put("canPubStatus", canPubStatus);
map.put("recIds", recIds);
map.put("type", method);
map.put("strCh", strCh);
//发送一个对象
ObjectMessage message=session.createObjectMessage(map);
// 通过消息生产者发出消息
producer.send(message);
} catch (JMSException e) {
e.printStackTrace();
} finally {
session.close();//关闭会话
connection.close();//关闭连接
}
}
1.5 消息监听
public static void Listener(){
ResourceBundle resource = ResourceBundle.getBundle("config/activeMqConfig");
String mqConnUrl = resource.getString("DEFAULT_BROKER_URL_TWO");
String connUrl = "failover:(" + mqConnUrl.trim()+ ")?initialReconnectDelay=1000&maxReconnectDelay=30000";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(resource.getString("DEFAULT_USER"), resource.getString("DEFAULT_PASSWORD"), connUrl);
Connection connection = null;
try {
connection = connectionFactory.createConnection();
connection.start();
// Session.CLIENT_ACKNOWLEDGE 采用手动调用消息确认
Session session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
Destination destination = session.createQueue(resource.getString("DESTINATION"));
MessageConsumer messageConsumer = session.createConsumer(destination);
logger.info("消息监听中....");
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(javax.jms.Message message) {
try {
ObjectMessage om = (ObjectMessage)message;
HashMap<String,Object> map=(HashMap<String,Object>) om.getObject();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date().getTime());
System.out.println(time+":"+"接收的参数---------------------------#" + map);
<!--
这边这一段为调用的业务逻辑处理,此项目为启动一个多线程的发布任务
TaskThread taskThread = new TaskThread();
taskThread.setChannelId(CMSUtil.longFormat(map.get("channelId").toString()));
Thread thread = new Thread(taskThread);
thread.run();
-->
//采用手动确认消息发送成功需要调用此方法
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read();
} catch (JMSException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
1.6 activeMqConfig.properties 文件
#ActiveMq链接配置
#链接用户名 默认的
DEFAULT_USER=admin
#链接密码
DEFAULT_PASSWORD=admin
#启动地址
DEFAULT_BROKER_URL_TWO=tcp://127.0.0.1:61616
#消息队列名称
DESTINATION=Docmentpublish
#javaconsole监控其中的名称
BROKERNAME=Docmentpublish
#消息持久化数据储存位置
MQDATAPATH=/activemq
#消息监控
BORKERURL=service:jmx:rmi:///jndi/rmi://127.0.0.1:1099/jmxrmi
BORKER=org.apache.activemq:brokerName=127.0.0.1,type=Broker
二、Mq+Tomcat的配置(内嵌式)
启动ActiveMq
此种方法和第一种方式一样,共用同样的方法,可以手动控制启动。
public void EmbedActiveMQStart(){
ResourceBundle resource = ResourceBundle.getBundle("config/activeMqConfig");
try {
BrokerService broker = new BrokerService();
broker.setUseJmx(true); // 开启监控
broker.setPersistent(true); // 持久化
broker.setBrokerName(resource.getString("BROKERNAME"));
SimpleAuthenticationPlugin sap = new SimpleAuthenticationPlugin();
AuthenticationUser au = new AuthenticationUser(resource.getString("DEFAULT_USER"), resource.getString("DEFAULT_PASSWORD"),"users");
ArrayList<AuthenticationUser> d = new ArrayList<AuthenticationUser>();
d.add(au);
sap.setUsers(d); // 用户验证
broker.setPlugins(new BrokerPlugin[] { sap });
String mqDataPath = resource.getString("MQDATAPATH"); // 存储位置
broker.getPersistenceAdapter().setDirectory(new File(mqDataPath));
broker.addConnector(resource.getString("DEFAULT_BROKER_URL_TWO")); // 连接地址
broker.start();
logger.info("启动 ActiveMQ BrokerService 成功");
} catch (Exception e) {
e.printStackTrace();
logger.error("启动 ActiveMQ BrokerService 失败,cause by:" + e.getMessage());
}
}
三、Mq单独部署服务
Liunx参考地址:https://www.jianshu.com/p/72f6aaf7b305
win参考地址:https://www.cnblogs.com/hushaojun/p/6016709.html
去官网下载http://activemq.apache.org/ apache-activemq-5.16.2(我目前部署的版本)。
启动 apache-activemq-5.16.2\bin\win64\wrapper.exe
启动成功后访问 ,http://127.0.0.1:8161/admin 会出现默认的管理界面。
修改端口:jetty.xml 文件
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="172.25.42.64"/>
<property name="port" value="8161"/>
</bean>
启用jmx :activemq.xml 文件
只需要修改2出即可 useJmx=“true” 和开启 1099
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="172.25.42.64" dataDirectory="${activemq.data}" useJmx="true">
<!--
The managementContext is used to configure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses the MBean server that is started by
the JVM. For more information, see:
http://activemq.apache.org/jmx.html
配置端口connectorPort=1099
-->
<managementContext>
<managementContext connectorPort="1099" createConnector="true"/>
</managementContext>
</broker>
3.1 pom.文件中添加
直接添加activemq-all 会报错日志冲突,采用pom文件剔除jar包的方式,也不行。
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
<version>5.14.3</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.14.3</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-ra</artifactId>
<version>5.3.2</version>
</dependency>
3.2 消息发送
/**
* 根据ActiveMq 创建并发送一条消息
* @throws JMSException
*/
public void CreateandSendNews(long siteId,int str,long channelId,long docId,long recId,long publishId,String canPubStatus,String recIds,String method,int strCh) throws JMSException {
ResourceBundle resource = ResourceBundle.getBundle("config/activeMqConfig");
// ConnectionFactory :连接工厂,JMS 用它创建连接
connectionFactory = new ActiveMQConnectionFactory(resource.getString("DEFAULT_USER"),resource.getString("DEFAULT_PASSWORD"), resource.getString("DEFAULT_BROKER_URL"));
// JMS 客户端到JMS Provider 的连接
connection = connectionFactory.createConnection();
//启动连接
connection.start();
// Session: 一个发送或接收消息的线程 false:代表不带事务的session CLIENT_ACKNOWLEDGE:代表客户端确认接收
session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
// 获取session注意参数值my-queue是Query的名字
queue = session.createQueue(resource.getString("DESTINATION"));
// MessageProducer:创建消息生产者
producer = session.createProducer(queue);
// 设置不持久化 PERSISTENT:代表持久化 NON_PERSISTENT:代表不持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
try {
HashMap<String,Object> map=new HashMap<String, Object>();
map.put("siteId", siteId);
map.put("str", str);
map.put("channelId", channelId);
map.put("docId", docId);
map.put("recId", recId);
map.put("publishId", publishId);
map.put("canPubStatus", canPubStatus);
map.put("recIds", recIds);
map.put("type", method);
map.put("strCh", strCh);
sendMsg(session, producer, map);
} catch (Exception e) {
logger.info("发布送消息Exception:" + e.getMessage());
}finally {
session.close();
connection.close();
}
}
3.3 消息监听接收
//启动监听器
public void ActiveMQReceiveListenerstart(){
try {
ResourceBundle resource = ResourceBundle.getBundle("config/activeMqConfig");
//根据用户名,密码,url创建一个连接工厂
factory = new ActiveMQConnectionFactory(resource.getString("DEFAULT_USER"),resource.getString("DEFAULT_PASSWORD"), resource.getString("DEFAULT_BROKER_URL"));
//从工厂中获取一个连接
connection = factory.createQueueConnection();
//连接启动
connection.start();
//创建一个session
//第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
//第二个参数 ,客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息
session = connection.createQueueSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE );
//创建一个到达的目的地,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"Alarm"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
// 5、创建一个消息队列
destination = session.createQueue(resource.getString("DESTINATION"));
//根据session,创建一个接收者对象
consumer = session.createConsumer(destination);
//实现一个消息的监听器
//实现这个监听器后,以后只要有消息,就会通过这个监听器接收到
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
try {
//获取到接收的数据
ObjectMessage om = (ObjectMessage)message;
HashMap<String,Object> map=(HashMap<String,Object>) om.getObject();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date().getTime());
System.out.println(time+":"+"接收的参数---------------------------#" + map);
<!-- 自己的业务逻辑
TaskThread taskThread = new TaskThread();
taskThread.setChannelId(CMSUtil.longFormat(map.get("channelId").toString()));
Thread thread = new Thread(taskThread);
thread.run();
-->
//确认消息发送成功
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
//关闭接收端,也不会终止程序哦
// consumer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
四、Mq+Spring+JmsTemplate的配置(单独部署ActiveMq服务)
参考地址:https://blog.csdn.net/mgsky1/article/details/80024876
4.1 配置Maven的pom.xml
这里我只贴出关键的依赖选项:
4.1.1 JMS依赖
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
4.1.2 ActiveMQ核心依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.7.0</version>
</dependency>
4.1.3 Spring依赖(${spring.version}的值为4.3.7.RELEASE)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
4.1.4 日志依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
其中,slf4j一定要有,不然的话运行会报错,如下图,提示找不到包。
4.2 配置Spring的spring-activemq.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd"> <context:property-placeholder location="classpath:config/activeMqConfig.properties"/> <context:component-scan base-package="com.zkjw.cms.publish.Listener"></context:component-scan> <!--连接到ActiveMQ,创建一个ConnectionFactory--> <bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://127.0.0.1:61616"></bean> <!-- 对上步创建的ConnectionFactory进行缓存包装,这样做的目的是提升性能,对sessions, connections 和 producers进行缓存复用,减少开销。--> <bean id="cachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory" p:targetConnectionFactory-ref="amqConnectionFactory" p:sessionCacheSize="10"></bean> <!--创建消息目的地,constructor-arg是目的地名称--> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <!--消息队列名称--> <constructor-arg value="${DESTINATION}"/> </bean> <!--构建JmsTemplate--> <bean id="producerTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="cachedConnectionFactory" p:defaultDestination-ref="destination"></bean> <!--对于消息的消费者,Spring官方提供了一个叫 DMLS(DefaultMessageListenerContainer)的容器,它能有效克制MDB(Message Driven Beans)的缺点。 要使用这个容器,我们需要创建自己的监听器(下面会提及),并且注册进容器中,这样一旦目的地有消息,就会自动触发监听事件。--> <!--其中,connection-factory与前面用org.apache.activemq.ActiveMQConnectionFactory包创建的bean的id对应, listener标签中destination填前面创建的目的地名称,ref填listener的bean id。--> <jms:listener-container container-type="default" connection-factory="amqConnectionFactory" acknowledge="auto"> <jms:listener destination="${DESTINATION}" ref="simpleMsgListener" method="onMessage"></jms:listener> </jms:listener-container> </beans>
4.3 创建监听器SimpleMsgListener
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
/**
* Created by trs on 2021/8/24.
*/
@Component(value = "simpleMsgListener")
public class SimpleMsgListener implements MessageListener {
@Override
public void onMessage(Message message) {
try {
ObjectMessage om = (ObjectMessage)message;
HashMap<String,Object> map=(HashMap<String,Object>) om.getObject();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date().getTime());
System.out.println(time+":"+"接收的参数---------------------------#" + map);
TaskThread taskThread = new TaskThread();
taskThread.setChannelId(CMSUtil.longFormat(map.get("channelId").toString()));
taskThread.setDocId(CMSUtil.longFormat(map.get("docId").toString()));
taskThread.setRecId(CMSUtil.longFormat(map.get("recId").toString()));
taskThread.setMethod(CMSUtil.stringFormat(map.get("type")));
taskThread.setSiteId(CMSUtil.longFormat(map.get("siteId").toString()));
taskThread.setStr(CMSUtil.intFormat(map.get("str").toString()));
taskThread.setStrCh(CMSUtil.intFormat(map.get("strCh").toString()));
taskThread.setTaskStatus(0);
taskThread.setRecIds(CMSUtil.stringFormat(map.get("recIds")));
taskThread.setPublishId(CMSUtil.longFormat(map.get("publishId").toString()));
taskThread.setCanPubStatus(CMSUtil.stringFormat(map.get("canPubStatus")));
Thread thread = new Thread(taskThread);
thread.run();
//确认消息发送成功
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
4.4 创建信息生成器 MyMessageCreator
-
import org.springframework.jms.core.MessageCreator; import javax.jms.*; import java.util.HashMap; /** * Created by Martin Huang on 2018/4/20. */ public class MyMessageCreator implements MessageCreator { private HashMap<String,Object> map; public MyMessageCreator(HashMap<String,Object> map) { this.map = map; } @Override public Message createMessage(Session session) throws JMSException { //发送一个对象 ObjectMessage message=session.createObjectMessage(map); // TextMessage message = session.createTextMessage("Spring-ActiveMQ发送的第【"+id+"】条消息"); System.out.println("发送消息:"+map); return message; } }
4.5 创建生产者
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import javax.jms.*; @Autowired private JmsTemplate jmsTemplate; HashMap<String,Object> map=new HashMap<String, Object>(); map.put("siteId", siteId); map.put("str", str); map.put("channelId", channelId); map.put("docId", docId); map.put("recId", recId); map.put("publishId", publishId); map.put("canPubStatus", canPubStatus); map.put("recIds", recIds); map.put("type", method); map.put("strCh", strCh); //这里填入创建好的信息生成器 jmsTemplate.send(new MyMessageCreator(map));
五、SpringMVC 项目ActiveMq 自启动服务和监听(单独部署服务)
1.配置 application-activeMq.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:property-placeholder location="classpath:config/activeMqConfig.properties"/>
<bean id="broker" class="org.apache.activemq.broker.BrokerService" init-method="start" destroy-method="stop">
<property name="brokerName" value="myBroker"/>
<property name="persistent" value="false"/>
<property name="transportConnectorURIs">
<list>
<value>tcp://127.0.0.1:61616</value>
</list>
</property>
</bean>
<bean id="InitDemo" class="com.zkjw.cms.publish.Listener.SimpleMsgListener" scope="singleton" init-method="init">
</bean>
</beans>
2.新建监听器 SimpleMsgListener
import com.zkjw.cms.publish.task.TaskThread;
import com.zkjw.core.util.CMSUtil;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.jms.*;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.ResourceBundle;
/**
* Created by trs on 2021/8/24.
*/
public class SimpleMsgListener {
private static Logger logger= LoggerFactory.getLogger(SimpleMsgListener.class);
@PostConstruct
public void init(){
//项目启动就会执行这个方法
Listener();
}
public static void Listener(){
ResourceBundle resource = ResourceBundle.getBundle("config/activeMqConfig");
String mqConnUrl = resource.getString("DEFAULT_BROKER_URL_TWO");
String connUrl = "failover:(" + mqConnUrl.trim()+ ")?initialReconnectDelay=1000&maxReconnectDelay=30000";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(resource.getString("DEFAULT_USER"), resource.getString("DEFAULT_PASSWORD"), connUrl);
Connection connection = null;
try {
connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
Destination destination = session.createQueue(resource.getString("DESTINATION"));
MessageConsumer messageConsumer = session.createConsumer(destination);
logger.info("消息监听中....");
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(javax.jms.Message message) {
try {
ObjectMessage om = (ObjectMessage)message;
HashMap<String,Object> map=(HashMap<String,Object>) om.getObject();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date().getTime());
System.out.println(time+":"+"接收的参数---------------------------#" + map);
TaskThread taskThread = new TaskThread();
taskThread.setChannelId(CMSUtil.longFormat(map.get("channelId").toString()));
taskThread.setDocId(CMSUtil.longFormat(map.get("docId").toString()));
taskThread.setRecId(CMSUtil.longFormat(map.get("recId").toString()));
taskThread.setMethod(CMSUtil.stringFormat(map.get("type")));
taskThread.setSiteId(CMSUtil.longFormat(map.get("siteId").toString()));
taskThread.setStr(CMSUtil.intFormat(map.get("str").toString()));
taskThread.setStrCh(CMSUtil.intFormat(map.get("strCh").toString()));
taskThread.setTaskStatus(0);
taskThread.setRecIds(CMSUtil.stringFormat(map.get("recIds")));
taskThread.setPublishId(CMSUtil.longFormat(map.get("publishId").toString()));
taskThread.setCanPubStatus(CMSUtil.stringFormat(map.get("canPubStatus")));
Thread thread = new Thread(taskThread);
thread.run();
//确认消息发送成功
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read();
} catch (JMSException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.编辑web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
启动。。。。。。。MVC
<!--启动ActiveMq-->
classpath:spring/application-activeMq.xml
</param-value>
</context-param>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/application-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
<!--<url-pattern>*.shtml</url-pattern>-->
</servlet-mapping>
<!-- spring mvc servlet -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
六、注意事项
- 采用第一种和第二种方式,切记pom.xml文件 不能引用其他的activemq 包,
- 例如activemq-all会有log日志冲突,引用多个其他的activemq 包,会导致监听失效。
- activeMq自带持久化,无需要链接任何数据库
- activeMq垃圾消息(处理积压的消息)处理。
- kill 杀死进程会导致持久化的信息读取失败,会报错IO异常。暴力解决办法删除本地的文件
- 采用内嵌式启动ActiveMq 没有web 8161管理界面
- 采用开启事务发送消息,监听器接收消息会导致消息不能确认。(待研究。。)
七、BrokerService 参数详解
参考地址:https://activemq.apache.org/maven/apidocs/org/apache/activemq/broker/BrokerService.html
<bean id="broker" class="org.apache.activemq.broker.BrokerService" init-method="start" destroy-method="stop">
<!--名称-->
<property name="brokerName" value="Docmentpublish"/>
<!--持久化-->
<property name="persistent" value="true"/>
<!--开启监控-->
<property name="UseJmx" value="true"/>
<!-- 设置默认情况下将为 JDBC 和日志持久性适配器存储数据文件的目录。-->
<property name="DataDirectory" value="\activeMq"/>
<!--链接地址-->
<property name="transportConnectorURIs">
<list>
<value>tcp://127.0.0.1:61616</value>
</list>
</property>
</bean>