javaweb项目中使用ActiveMq

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>

六、注意事项

  1. 采用第一种和第二种方式,切记pom.xml文件 不能引用其他的activemq 包,
  2. 例如activemq-all会有log日志冲突,引用多个其他的activemq 包,会导致监听失效。
  3. activeMq自带持久化,无需要链接任何数据库
  4. activeMq垃圾消息(处理积压的消息)处理。
  5. kill 杀死进程会导致持久化的信息读取失败,会报错IO异常。暴力解决办法删除本地的文件
  6. 采用内嵌式启动ActiveMq 没有web 8161管理界面
  7. 采用开启事务发送消息,监听器接收消息会导致消息不能确认。(待研究。。)

七、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>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值