最近由于项目需要,采用消息中间件来解决消息的异步处理。百度一下可以看到各种的技术。Kafka、RabbitMQ、RocketMQ网上吹嘘的是各种强大各种diao。我觉得适合自己的业务场景才是最重要的。于是我选择了activemq.轻量级、简单、易于维护。
参考博客:http://www.360doc.com/content/14/0328/08/2795334_364337432.shtml
集成要求:activemq5.14.5+spring-jms3.2.18+maven3
activemq5.14.5安装部分自行百度。也可以加本人微信JornTang 发送
maven依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>3.1</version>
</dependency>
接下来看看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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.3.1.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-3.0.xsd" default-lazy-init="false">
<description>Spring公共配置 </description>
<!-- activemq 配置 -->
<!-- ActiveMQ 连接工厂 -->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
<bean id="activemqConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.url}"/>
<property name="userName" value="${activemq.username}"/>
<property name="password" value="${activemq.password}"/>
</bean>
</property>
<!-- <property name="connectionFactory" ref="amqConnectionFactory"></property> -->
</bean>
<!-- Spring JmsTemplate 的消息生产者 start-->
<!-- 定义JmsTemplate的Queue类型 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<constructor-arg ref="activemqConnectionFactory" />
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
</property>
<!-- 非pub/sub模型(发布/订阅),即队列模式 -->
<property name="pubSubDomain" value="false" />
<property name="sessionAcknowledgeMode" value="1" />
<!-- deliveryMode, priority, timeToLive 的开关,要生效,必须配置explicitQosEnabled为true,默认false-->
<property name="explicitQosEnabled" value="true" />
<!-- 发送模式 DeliveryMode.NON_PERSISTENT=1:非持久 ; DeliveryMode.PERSISTENT=2:持久-->
<property name="deliveryMode" value="2"/>
</bean>
<!-- 定义JmsTemplate的Topic类型 -->
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<constructor-arg ref="activemqConnectionFactory" />
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
</property>
<!-- pub/sub模型(发布/订阅) -->
<property name="pubSubDomain" value="true" />
<property name="sessionAcknowledgeMode" value="1" />
<!-- deliveryMode, priority, timeToLive 的开关,要生效,必须配置explicitQosEnabled为true,默认false-->
<property name="explicitQosEnabled" value="true" />
<!-- 发送模式 DeliveryMode.NON_PERSISTENT=1:非持久 ; DeliveryMode.PERSISTENT=2:持久-->
<property name="deliveryMode" value="2"/>
</bean>
<!--Spring JmsTemplate 的消息生产者 end-->
<!-- activemq工具类 -->
<bean id="activemqUtil" class="com.minstone.statisplatform.util.ActivemqUtil">
<property name="jmsQueueTemplate" ref="jmsQueueTemplate"></property>
<property name="jmsTopicTemplate" ref="jmsTopicTemplate"></property>
</bean>
<!-- 消息消费者 start-->
<bean id="StatisTaskReceiver" class="com.minstone.statisplatform.manager.activemq.StatisTaskReceiver"></bean>
<jms:listener-container destination-type="queue" container-type="default" connection-factory="activemqConnectionFactory" acknowledge="auto" >
<jms:listener destination="archive.statis.queue" ref="StatisTaskReceiver"/>
</jms:listener-container>
<bean id="logTaskReceiver" class="com.minstone.statisplatform.manager.activemq.LogTaskReceiver"></bean>
<jms:listener-container destination-type="topic" container-type="default" connection-factory="activemqConnectionFactory" acknowledge="auto" >
<jms:listener destination="archive.log.topic" ref="logTaskReceiver"/>
</jms:listener-container>
<!-- 消息消费者 end -->
</beans>
ActivemqUtil.java
package com.minstone.statisplatform.util;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import com.minstone.statisplatform.common.exception.ActivemqUtilException;
/**
* ClassName: ActivemqUtil
* @Description: activemq工具类
* @author JornTang
* @date 2017年9月26日
*/
public class ActivemqUtil {
private static Logger logger = LoggerFactory.getLogger(ActivemqUtil.class);
//注入Spring JmsTemplate queue
private static JmsTemplate jmsQueueTemplate;
private static JmsTemplate jmsTopicTemplate;
public void setJmsQueueTemplate(JmsTemplate jmsQueueTemplate) {
ActivemqUtil.jmsQueueTemplate = jmsQueueTemplate;
}
public void setJmsTopicTemplate(JmsTemplate jmsTopicTemplate) {
ActivemqUtil.jmsTopicTemplate = jmsTopicTemplate;
}
/**
* 发送一条消息到指定的Queue队列(目标)
* @param queueName 队列名称
* @param message 消息内容
* @throws ActivemqUtilException
*/
public static void sendQueue(String queueName,final String message) throws ActivemqUtilException{
logger.info("发送一条消息:【"+message+"】至Queue队列【"+queueName+"】");
try {
jmsQueueTemplate.send(queueName, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
} catch (Exception e) {
throw new ActivemqUtilException("发送消息至PTP队列【"+queueName+"】异常",e);
}
}
/**
* 发送一条消息到指定的队列(目标)
* @param queueName 队列名称
* @param message 消息内容
* @throws ActivemqUtilException
*/
public static void sendTopic(String topicName,final String message) throws ActivemqUtilException{
logger.info("发送一条消息:【"+message+"】至Topic队列【"+topicName+"】");
try {
jmsTopicTemplate.send(topicName, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
} catch (Exception e) {
throw new ActivemqUtilException("发送消息至Topic队列【"+topicName+"】异常",e);
}
}
}
消费者StatisTaskReceiver.java
package com.minstone.statisplatform.manager.activemq;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StatisTaskReceiver implements MessageListener{
private static Logger log = LoggerFactory.getLogger(StatisTaskReceiver.class);
@Override
public void onMessage(Message message) {
try {
log.info("接收到消息:{}",((TextMessage)message).getText());
} catch (Exception e) {
e.printStackTrace();
}
}
}
启动之后看下效果图
发送一条接收一条是不是非常简单
注意:activemq5.14.5默认情况下是采用kahadb进行持久化,所以不必担心active宕机发生数据丢失的情况
有需要在线指导的朋友可以加我微信JornTang
这个时候开始思考,队列里面数据都不一样。如何才能控制什么样的队列给什么用户进行访问处理。这样就能提升数据的安全性。
没有错,activemq是采用jass认证插件
看下认证步骤
在conf/activemq.xml systemUsage标签前面添加以下配置
<plugins>
<!--Configureauthentication;Username,passwordsandgroups-->
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="manager" groups="admins"/>
<authenticationUser username="admin" password="zaq12wsx" groups="admins"/>
<authenticationUser username="lzwyadmin" password="lzwyadmin" groups="users"/>
<authenticationUser username="guest" password="password" groups="guests"/>
<authenticationUser username="testUser" password="123456" groups="testGroup"/>
</users>
</simpleAuthenticationPlugin>
<!-- Letsconfigureadestinationbasedauthorizationmechanism-->
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry queue=">" read="admins" write="admins" admin="admins"/>
<authorizationEntry queue="users.>" read="users" write="admins" admin="admins"/>
<authorizationEntry queue="guest.>" read="guests" write="guests,users" admin="guests,users"/>
<authorizationEntry queue="test" read="testGroup" write=" testGroup "/>
<authorizationEntry topic=">" read="admins" write="admins" admin="admins"/>
<authorizationEntry topic="user.>" read="users" write="admins" admin="admins"/>
<authorizationEntry topic="guest.>" read="guests" write="guests,users" admin="guests,users"/>
<authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users ,testGroup" write="guests,users ,testGroup" admin="guests,users ,testGroup"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
read:可以从queue或者topic里面接收消息
write:可以向queue或者topic发送消息
admin:可以创建queue或者topic(可能还有别的功能)
<p>
simpleAuthenticationPlugin中设置用户名、密码和群组,
authorizationPlugin设置主题和队列的访问群组,“>”表示所有的主题或者队列。上面的配置中添加了一个testUser,属于群组testGroup,同时设置test这个队列的访问读写权限为testGroup,当然admins也可以访问的,因为admins是对所有的队列都有访问权限。
将第三部分代码中的设置用户名和密码改成刚刚添加的用户testUser,如果密码不正确,将会抛出User name or passwordis invalid.异常,
如果testUser所属的群组不能访问test队列,那么会抛出User guest is not authorized to write to: queue://test异常。需要注意的是所有的群组都需要对以ActiveMQ.Advisory为前缀的主题具有访问权限。</p>
已经配置Ok了,自己按照设定的权限配置测试把。。。。。。。。