ActiveMQ 和 RabbitMQ
- ActiveMQ 和 RabbitMQ 是两种进行企业级消息代理的常用容器。
一、简介
1、ActiveMQ
- Java Message Service,即 Java 消息服务,简称 JMS。
- JMS 是一套基于 JVM 消息代理的规范,而以这种规范进行编程实现的有 ActiveMQ、HornetMQ。
- Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。——百度百科
2、RabbitMQ
- 除了 JMS,比较常用的消息代理规范还有 Advance Message Queuing Protocol,简称 AMQP,进行实现的主要有 RabbitMQ 。
- RabbitMQ是一套开源(MPL)的消息队列服务软件,是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang 写成。
二、Spring Boot 对 ActiveMQ 和 RabbitMQ 的支持
- Spring 或者说 Spring Boot 都对 ActiveMQ 和 Rabbit 进行了支持,通过提供 spring-jms 和 spring-rabbit,并且还提供了各自的 template 来发送消息。
- spring 使用 @JmsListener 和 @RabbitListener 两者注解来分别支持某个方法体监听 JMS 或 AMQP 消息代理发布的消息;编辑有这种监听方法的类上要用 @EnableJms 或 @ EnableRabbit 开启支持。
- 对于 ActiveMQ,可以用 spring.activemq 为前缀的属性来设置 ActiveMQ 的连接属性,如下:
spring.activemq.broker-url=tcp://localhost:61616 # 消息代理路径 spring.activemq.user= spring.activemq.password= spring.activemq.in-memory=true spring.activemq.pooled=false
- 同样的,对于 RabbitMQ 可以用以 spring.rabbitmq 为前缀的属性配置 RabbitMQ,如下:
spring.rabbitmq.host=localhost # 服务器地址,默认是 localhost spring.rabbitmq.port=5672 # 端口,默认是 5672 spring.rabbitmq.username=admin spring.rabbitmq.password=secret
二、项目示例
- 分别对 ActiveMQ 和 RabbitMQ 两种消息代理容器,用简单的项目进行测试。
1、ActiveMQ 示例
- 首先用 ActiveMQ 进行测试。
1.1、启动 ActiveMQ 容器
- 在 Docker 中先用如下命令拉取 ActiveMQ 的容器镜像:
docker pull cloudesire/activemq
- 下载好镜像后,使用命令:
docker run -d -p 61616:61616 -p 8161:8161 cloudesire/activemq
启动容器;其中 61616 是消息代理端口,8161 是管理界面的端口,在用 VirtualBOX 做好端口映射后,可以用浏览器打开 localhost:8161 登录管理界面,默认账号密码为 admin。
1.2、新建 Spring Boot 项目
- 新建一个 Spring Boot 项目,不用选择任何初始依赖,后面手动添加依赖。在编辑器加载好初始项目的框架后,打开 POM 文件添加如下依赖:
<!-- JMS 依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency> <!-- activeMQ 依赖--> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-client</artifactId> </dependency>
- 再在 application.properties 文件中编辑如下属性设置。
logging.file=log.log spring.activemq.broker-url=tcp://localhost:61616
1.3、自定义消息发送类
- 新建一个类并实现 MessageCreator 接口,重写 createMessage 方法,从而自定义 JMS 消息发送
package com.pyc.activemq; import org.springframework.jms.core.MessageCreator; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; public class Msg implements MessageCreator { @Override public Message createMessage(Session session) throws JMSException { return session.createTextMessage("A message of testing"); } }
1.4、设置消息目的端
- 设置消息发送目的地,直接在入口类增加代码
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.jms.core.JmsTemplate; @SpringBootApplication public class ActivemqApplication implements CommandLineRunner { // implement CommandLinerRunner and overwrite Run method //so that can execute our code when program start @Autowired JmsTemplate jmsTemplate; @Override public void run(String... args) throws Exception { // 向一个叫 my-destination 的目的端发送消息。 jmsTemplate.send("my-destination", new Msg()); } public static void main(String[] args) { SpringApplication.run(ActivemqApplication.class, args); } }
1.5、Receiver
- 为了测试能否收到消息,编辑一个 Receiver
package com.pyc.activemq; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class Receiver { @JmsListener(destination = "my-destination") public void receiverMessage(String message){ System.out.println("接收到:<" + message + ">"); } }
1.6、测试
- 运行项目,查看控制台,可以看到有如下关键信息:
- 再打开 ActiveMQ 的管理界面,选择 queues 查看消息队列如下:
2、RabbitMQ 示例
- 用一个简单的项目测试 RabbitMQ 消息代理。
2.1、启动 RabbitMQ 容器
- 同样的,在 Docker 命令窗口敲下命令:
docker pull rabbitmq:3-management
将 RabbitMQ 镜像下载到本地。 - 镜像下载好后,用命令
docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:3-management
启动容器,两个端口中 5672 是消息代理端口,15672 是 Web 管理界面的端口,用 VirtualBox 做好端口映射后,用浏览器访问 localhost:15672 打开管理界面的登录界面,默认账户和密码是 guest,登录成功后在还未进行消息代理时的界面如下:
2.2、新建 Spring Boot 项目
- 新建一个 Spring Boot 项目,初始依赖选择 RabbitMQ(AMQP)
- pom 文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.0.M2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.pyc</groupId> <artifactId>rabbitmq</artifactId> <version>0.0.1-SNAPSHOT</version> <name>rabbitmq</name> <description>RabbitMQ Project</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </pluginRepository> </pluginRepositories> </project>
2.3、消息编辑
- 在入口类中进行修改,编辑消息内容以及消息目的端,代码如下:
package com.pyc.rabbitmq; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class RabbitmqApplication implements CommandLineRunner { // using rabbit template @Autowired RabbitTemplate template; // define destination also called queue, named my-queue @Bean public Queue pycQueue(){ return new Queue("my-queue"); } @Override public void run(String... args) throws Exception { // using convertAndSend method to send message template.convertAndSend("my-queue", "A greet message come from RabbitMQ"); } public static void main(String[] args) { SpringApplication.run(RabbitmqApplication.class, args); } }
2.4、Receiver
- 编辑一个 Receiver 用于测试消息接收
package com.pyc.rabbitmq; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class Receiver { @RabbitListener(queues = "my-queue") public void receiverMessage(String message){ System.out.println("Received: <" + message + ">"); } }
2.5、测试
- 运行项目,打开管理界面,如下:
- 查看队列
- 查看控制台窗口