一、ActiveMQ
- ActiveMQ是ASF(Apache Software Foundation)的一款消息中间件(middle-ware),消息中间件主要完成的是消息的接收、存储和转发。主要实现的模式是生产消费模式、订阅发布模式。其主要区别是,生产消费模式中,生产完消息,消息一经消费,便不再存在。发布订阅模式中,一条消息可以有多个订阅者,即一条消息的消费者可以有多个。
- 消息中间件的主要作用:流量削峰、异步处理、应用解耦、日志处理。合理利用消息中间件,可以大大提升网站的并发量,增强网站的稳定性。类似于ActiveMQ这样的消息中间件产品还有很多:RocketMQ、RabbitMQ和Kafka。其中Kafka是构建微服务系统首选的产品。
二、ActiveMQ服务端开启
- 在本地下载好ActiveMQ,进入bin目录,执行
./activemq start
即可。这一步需要本机上有可用的JRE环境。 - 可以通过ActiveMQ可视化管理界面进行队列创建和消息管理,同时也可以验证我们的ActiveMQ是否正常工作。(访问地址:localhost:8161,初始用户名和密码都为admin)。
- ActiveMQ管理端界面如图所示。
三、ActiveMQ的基本使用
- 首先需要在项目中导入相应的jar包。
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<version>${jms.version}</version>
</dependency>
- 完成spring配置。
<?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:amq="http://activemq.apache.org/schema/core"
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.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<context:component-scan base-package="com.lanou"></context:component-scan>
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://localhost:61616"
userName="admin"
password="admin">
</amq:connectionFactory>
<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory"></constructor-arg>
<property name="sessionCacheSize" value="100"></property>
</bean>
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue1"></constructor-arg>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory"></property>
<property name="defaultDestination" ref="queue"></property>
<property name="receiveTimeout" value="10000"></property>
<property name="pubSubDomain" value="false"></property>
</bean>
</beans>
- 编写提供服务代码。
import javax.jms.Destination;
public interface IMsgProviderService {
void sendMsg(Destination destination, final String message);
void sendMsg(final String message);
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
@Service
public class MsgProviderService implements IMsgProviderService {
@Autowired
private JmsTemplate jmsTemplate;
@Override
public void sendMsg(Destination destination, String message) {
jmsTemplate.send(destination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}
@Override
public void sendMsg(String message) {
jmsTemplate.send(new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}
}
- 编写消费服务代码。
import javax.jms.TextMessage;
public interface IMsgConsumerService {
TextMessage receive();
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.TextMessage;
@Service
public class MsgConsumerService implements IMsgConsumerService {
@Autowired
private JmsTemplate jmsTemplate;
@Resource(name = "queue")
private Destination queue;
@Override
public TextMessage receive() {
return (TextMessage) jmsTemplate.receive(queue);
}
}
- 编写Controller实现消息发送和接收。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.jms.JMSException;
@Controller
public class MessageController {
@Autowired
private IMsgProviderService provider;
@Autowired
private IMsgConsumerService consumer;
@RequestMapping(value = "/msg/send", method = RequestMethod.GET)
public @ResponseBody Result sendMsg(String message) {
provider.sendMsg(message);
return ResultGenerator.genSuccessResult("消息发送成功");
}
@RequestMapping(value = "/msg/receive", method = RequestMethod.GET)
public @ResponseBody Result receiveMsg() {
String message = "";
try {
message = consumer.receive().getText();
} catch (JMSException e) {
return ResultGenerator.genFailResult("消息接受失败:当前队列中消息为空");
}
return ResultGenerator.genSuccessResult("消息接收成功:" + message);
}
}
- 实现效果。
四、 自主监听消息
- MQ在使用时,我们通常会对队列中的消息进行监听,一旦监听到了队列中存在消息,就会对消息进行消费。下面实现监听类,监听消息发送。
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class MsgQueueListener implements MessageListener {
@Override
public void onMessage(Message message) {
TextMessage msg = (TextMessage) message;
System.out.println("当前存在消息: " + message);
}
}
- 配置监听类,实现消息的监听。
<bean id="messageListener" class="com.lanou.web.controller.msgqueue.MsgQueueListener"></bean>
<bean id="messageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"></property>
<property name="destination" ref="queue"></property>
<property name="messageListener" ref="messageListener"></property>
</bean>
- 实现效果。