一、ActiveMQ

  • ActiveMQ是ASF(Apache Software Foundation)的一款消息中间件(middle-ware),消息中间件主要完成的是消息的接收、存储和转发。主要实现的模式是生产消费模式、订阅发布模式。其主要区别是,生产消费模式中,生产完消息,消息一经消费,便不再存在。发布订阅模式中,一条消息可以有多个订阅者,即一条消息的消费者可以有多个。
  • 消息中间件的主要作用:流量削峰、异步处理、应用解耦、日志处理。合理利用消息中间件,可以大大提升网站的并发量,增强网站的稳定性。类似于ActiveMQ这样的消息中间件产品还有很多:RocketMQ、RabbitMQ和Kafka。其中Kafka是构建微服务系统首选的产品。

二、ActiveMQ服务端开启

  1. 在本地下载好ActiveMQ,进入bin目录,执行./activemq start即可。这一步需要本机上有可用的JRE环境。
  2. 可以通过ActiveMQ可视化管理界面进行队列创建和消息管理,同时也可以验证我们的ActiveMQ是否正常工作。(访问地址:localhost:8161,初始用户名和密码都为admin)。
  3. ActiveMQ管理端界面如图所示。

三、ActiveMQ的基本使用

  1. 首先需要在项目中导入相应的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>
  1. 完成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>

    <!--ActiveMQ连接工厂-->
    <amq:connectionFactory id="amqConnectionFactory"
                           brokerURL="tcp://localhost:61616"
                           userName="admin"
                           password="admin">
    </amq:connectionFactory>

    <!--JMS连接工厂-->
    <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>

    <!--配置JMS模板,用于发送、接收消息-->
    <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>
        <!--true->topics  false->queue[default]-->
        <property name="pubSubDomain" value="false"></property>
    </bean>

    <!--用于消息监听:需要自定义消息监听类-->
<!--    <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>-->

</beans>
  1. 编写提供服务代码。
//IMsgProviderService.java
import javax.jms.Destination;

public interface IMsgProviderService {

    void sendMsg(Destination destination, final String message);

    void sendMsg(final String message);

}

//MsgProviderService.java
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);
            }
        });
    }

}
  1. 编写消费服务代码。
//IMsgConsumerService.java
import javax.jms.TextMessage;

public interface IMsgConsumerService {

    TextMessage receive();

}

//MsgConsumerService.java
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);
    }

}
  1. 编写Controller实现消息发送和接收。
//MessageController.java
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);
    }

}
  1. 实现效果。

四、 自主监听消息

  1. MQ在使用时,我们通常会对队列中的消息进行监听,一旦监听到了队列中存在消息,就会对消息进行消费。下面实现监听类,监听消息发送。
//MessageListener.java
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);
    }

}
  1. 配置监听类,实现消息的监听。
<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>
  1. 实现效果。

java限流中间件 java中间件mq_java

java限流中间件 java中间件mq_spring_02