ActiveMQ的配置以及使用方法

ActiveMQ的配置以及使用方法

2017年03月29日 13:46:37

阅读数:4303

 

ActiveMQ的简单使用

ActiveMQ是一种开源的,实现了JMS规范的,面向消息(MOM)的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信

ActiveMQ接发送消息流程图:

Spring结合ActiveMQ使用

1.pom文件引入依赖,引入jar包

 
  1. <!--active mq start-->

  2. <dependency>

  3. <groupId>org.apache.activemq</groupId>

  4. <artifactId>activemq-core</artifactId>

  5. <version>5.7.0</version>

  6. </dependency>

  7. <dependency>

  8. <groupId>org.apache.activemq</groupId>

  9. <artifactId>activemq-pool</artifactId>

  10. <version>5.13.3</version>

  11. </dependency>

  12. <!--active mq end-->

 2 .spring-mq.xml 配置文件

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"

  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  4. xsi:schemaLocation="

  5. http://www.springframework.org/schema/beans

  6. http://www.springframework.org/schema/beans/spring-beans.xsd">

  7.  
  8. <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->

  9. <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

  10. <!-- ActiveMQ服务地址 -->

  11. <property name="brokerURL" value="${mq.brokerURL}"/>

  12. <property name="userName" value="${mq.userName}"></property>

  13. <property name="password" value="${mq.password}"></property>

  14. <!-- 这里定义重试策略,注意:只有持久化的才会重试-->

  15. <property name="redeliveryPolicyMap" ref="redeliveryPolicyMap"/>

  16. </bean>

  17.  
  18.  
  19. <!--这里设置各个消息队列的重发机制-->

  20. <bean id="redeliveryPolicyMap" class="org.apache.activemq.broker.region.policy.RedeliveryPolicyMap">

  21. <property name="redeliveryPolicyEntries">

  22. <list>

  23. <ref bean="smsRedeliveryPolicy"/>

  24. <ref bean="mailRedeliveryPolicy"/>

  25. </list>

  26. </property>

  27. </bean>

  28. <bean id="smsRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">

  29. <!--重发次数 延时、延时系数、延时指数开关、目标(重发等待时间1s, 2s, 4s, 8s)-->

  30. <property name="maximumRedeliveries" value="3"/>

  31. <property name="redeliveryDelay" value="1000"/>

  32. <property name="backOffMultiplier" value="2"/>

  33. <property name="useExponentialBackOff" value="true"/>

  34. <property name="destination" ref="smsQueue"/>

  35. </bean>

  36. <bean id="mailRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">

  37. <!--重发次数 延时、延时系数、延时指数开关-->

  38. <property name="maximumRedeliveries" value="2"/>

  39. <property name="redeliveryDelay" value="5000"/>

  40. <property name="destination" ref="mailQueue"/>

  41. </bean>

  42.  
  43. <!--

  44. ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory

  45. 可以用来将Connection、Session和MessageProducer池化,这样可以大大的减少我们的资源消耗。

  46. 要依赖于 activemq-pool包

  47. -->

  48. <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">

  49. <property name="connectionFactory" ref="targetConnectionFactory"/>

  50. <property name="maxConnections" value="${mq.pool.maxConnections}"/>

  51. </bean>

  52.  
  53. <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->

  54. <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">

  55. <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->

  56. <property name="targetConnectionFactory" ref="pooledConnectionFactory"/>

  57. <property name="reconnectOnException" value="true"/>

  58. </bean>

  59.  
  60. <!-- 队列目的地-->

  61. <bean id="smsQueue" class="org.apache.activemq.command.ActiveMQQueue">

  62. <constructor-arg index="0" value="${sms.queueName}"/>

  63. </bean>

  64. <bean id="mailQueue" class="org.apache.activemq.command.ActiveMQQueue">

  65. <constructor-arg index="0" value="${mail.queueName}"/>

  66. </bean>

  67.  
  68.  
  69. <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->

  70. <!-- 队列模板 这里配置2个,一个用于分布式业务,一个用于发送邮件-->

  71. <bean id="smsMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate">

  72. <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->

  73. <property name="connectionFactory" ref="connectionFactory"/>

  74. <property name="defaultDestination" ref="smsQueue"/>

  75. <!-- 使 deliveryMode, priority, timeToLive设置生效-->

  76. <property name="explicitQosEnabled" value="true" />

  77. <!-- 持久化 如果设置为非持久化MQ服务器重启后MQ中的数据会丢失-->

  78. <property name="deliveryPersistent" value="true"/>

  79. <!--这里注意:如果不开启事务,消息在异常的情况下是不会重试的-->

  80. <property name="sessionTransacted" value="false"/>

  81. </bean>

  82.  
  83. <bean id="mailMqJmsTemplate" class="org.springframework.jms.core.JmsTemplate">

  84. <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->

  85. <property name="connectionFactory" ref="connectionFactory"/>

  86. <property name="defaultDestination" ref="mailQueue"/>

  87. <!-- 使 deliveryMode, priority, timeToLive设置生效-->

  88. <property name="explicitQosEnabled" value="true" />

  89. <!-- 持久化 如果设置为非持久化MQ服务器重启后MQ中的数据会丢失-->

  90. <property name="deliveryPersistent" value="true"/>

  91. <!--这里注意:如果不开启事务,消息在异常的情况下是不会重试的-->

  92. <property name="sessionTransacted" value="true"/>

  93. </bean>

  94.  
  95. <!-- 消息监听实现方法一 -->

  96. <bean id="smsListener" class="com.cn.ssm.mq.listener.SmsMessageListener"/>

  97. <bean id="mailListener" class="com.cn.ssm.mq.listener.MailMessageListener"/>

  98.  
  99.  
  100. <!-- 消息接收监听器用于异步接收消息-->

  101. <bean id="smsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">

  102. <property name="connectionFactory" ref="connectionFactory"/>

  103. <property name="destination" ref="smsQueue"/>

  104. <property name="messageListener" ref="smsListener"/>

  105. <!--这里注意:如果不开启事务,消息在异常的情况下是不会重试的-->

  106. <property name="sessionTransacted" value="true"/>

  107. <!-- 同时启动几个listener消费消息 或者可使用

  108. <property name="concurrency" value="4-8"/>

  109. 可以根据消息队列中的消息规模自动调整并行数量,最小4, 最大8个。 -->

  110. <property name="concurrentConsumers" value="1"/>

  111. </bean>

  112.  
  113.  
  114.  
  115. <!- 可定义多个消息监听容器,监听不同队列内容 -->

  116. <bean id="mailContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">

  117. <property name="connectionFactory" ref="connectionFactory"/>

  118. <property name="destination" ref="mailQueue"/>

  119. <property name="messageListener" ref="mailListener"/>

  120. <!--这里注意:如果不开启事务,消息在异常的情况下是不会重试的-->

  121. <property name="sessionTransacted" value="true"/>

  122. <property name="concurrentConsumers" value="1"/>

  123. </bean>

  124. </beans>

 
 
  1.  
  2.  
  3.  
  4.  
  5. 发送端代码:

  6. @RunWith(SpringJUnit4ClassRunner.class)

  7. @ContextConfiguration("classpath:application.xml")

  8. public class ActiveMqProducer {

  9.  
  10. private final Logger log = LoggerFactory.getLogger(ActiveMqProducer.class);

  11.  
  12. @Autowired

  13. private JmsTemplate smsMqJmsTemplate;

  14.  
  15. @Test

  16. public void smsSend() throws Exception {

  17. bizMqJmsTemplate.setSessionTransacted(true);

  18. for (int i = 0; i < 1; i++) {

  19. log.info("==>send message" + i);

  20. bizMqJmsTemplate.send(new MessageCreator() {

  21. @Override

  22. public Message createMessage(Session session)

  23. throws JMSException {

  24. log.info("getTransacted:" + session.getTransacted());

  25. Sms sms = new Sms("你好,你的验证码是", 365986);

  26. return session.createTextMessage(JSONObject

  27. .toJSONString(sms));

  28. }

  29. });

  30. log.info("==>finish send message" + i);

  31. }

  32.  
  33. }

  34.  
  35. }

  36.  
  37. 接收端代码:

  38. @Component

  39. public class SmsMessageListener implements SessionAwareMessageListener<Message> {

  40.  
  41. private static final Logger log = LoggerFactory.getLogger(TransactionBizMessageListener.class);

  42. private final String transactionBiz = "testDistributedTransaction";

  43.  
  44. @Autowired

  45. private TransactionBizService transactionBizService;

  46.  
  47. /**

  48. * @param message

  49. * @param session

  50. */

  51. public void onMessage(Message message, Session session) throws JMSException{

  52. //这里建议不要try catch,让异常抛出,通过redeliveryPolicy去重试,达到重试次数进入死信DLQ(Dead Letter Queue)

  53. ActiveMQTextMessage msg = (ActiveMQTextMessage) message;

  54. String ms = ms = msg.getText();

  55. log.info("==>receive message:" + ms);

  56. // 转换成相应的对象

  57. Sms sms = JSONObject.parseObject(ms, Sms.class);

  58. if (sms != null ) {

  59. // do something

  60. //throw new RuntimeException("throw runtimeExcetpion");

  61. } else {

  62. log.info("==>message:" + ms + " sms is null!");

  63. }

  64. }

  65. }

  66.  
  67.  
  68.  
  69.  
  70.  
  71. //普通java 代码类实现

  72. //发送端

  73. public static void main(String[] args) {

  74. ConnectionFactory connectionFactory;

  75. Connection connection;

  76. Session session;

  77. Destination destination;

  78. MessageProducer producer;

  79. connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.1.100:61616");

  80. try {

  81. connection = connectionFactory.createConnection();

  82. connection.start();

  83. //第一个参数是是否是事务型消息,设置为true,第二个参数无效

  84. //第二个参数是

  85. //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。异常也会确认消息,应该是在执行之前确认的

  86. //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会删除消息。可以在失败的

  87. //时候不确认消息,不确认的话不会移出队列,一直存在,下次启动继续接受。接收消息的连接不断开,其他的消费者也不会接受(正常情况下队列模式不存在其他消费者)

  88. //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。在需要考虑资源使用时,这种模式非常有效。

  89. //待测试

  90. session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

  91. destination = session.createQueue("test-queue");

  92. producer = session.createProducer(destination);

  93. producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);//是否持久化,不持久化,一旦服务挂掉 重启,消息会丢失

  94. //优先级不能影响先进先出。。。那这个用处究竟是什么呢呢呢呢

  95.  
  96. for(int i=0;i<100;i++){

  97.  
  98. producer.send(session.createTextMessage("send:"+i));

  99. }

  100. producer.close();

  101.  
  102. } catch (JMSException e) {

  103. e.printStackTrace();

  104. }

  105. }

  106.  
  107.  
  108.  
  109. // 接收端

  110. public static void main(String[] args) {

  111. ConnectionFactory connectionFactory;

  112. // Connection :JMS 客户端到JMS Provider 的连接

  113. Connection connection = null;

  114. // Session: 一个发送或接收消息的线程

  115. Session session;

  116. // Destination :消息的目的地;消息发送给谁.

  117. Destination destination;

  118. // 消费者,消息接收者

  119. MessageConsumer consumer;

  120. connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://192.168.1.100:61616");

  121. try {

  122. // 构造从工厂得到连接对象

  123. connection = connectionFactory.createConnection();

  124. // 启动

  125. connection.start();

  126. // 获取操作连接

  127. //这个最好还是有事务

  128. session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

  129. // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置

  130. destination = session.createQueue("test-queue");

  131. consumer = session.createConsumer(destination);

  132. consumer.setMessageListener(new MessageListener() {

  133. @Override

  134. public void onMessage(Message message) {

  135. try {

  136. if (null != message) {

  137. System.out.println("收到消息" +((TextMessage)message).getText());

  138. }

  139. } catch (Exception e) {

  140. // TODO: handle exception

  141. }

  142. }

  143. });

  144. } catch (Exception e) {

  145. e.printStackTrace();

  146. }

  147. }

猜你喜欢

转载自blog.csdn.net/wangshuminjava/article/details/81660240
今日推荐