简介
系统与系统之间的通信,
即:发送者无须等待消息接受者的处理及返回。
消息代理:message broker
目的地:destination
当消息发送者发送后,消息将有消息代理接管,消息代理保证消息传送到 指定的目的地。
异步消息:有两种形式,队列(queue) 和 主题 (topic)
队列用于 点对点式 (point to point)
常用的
主题用于 发布/订阅式 (public / subscribe )
消息发送者 发送消息到主题 topic ,而多个消息接收者 监听这个主题。
JMS:
java message service 即 java消息服务,基于jvm消息代理的规范。
ActiveMQ , HornetQ 是 JMS代理的实现
spring-jms
AMQP,
Advanced Message Queuing Protocol 。也是一个消息代理的规范,
不仅兼容JMS,还支持跨语言平台。 主要实现 RabbitMQ
spring-rabbit
需要ConnectionFactory 的实现,提供了 JMSTemplate 和 RabbitTemplate
@JmsListener @RabbitListener 监听消息代理发布的消息。
通过@EnableJms @EnableRabbit开启支持
spring Boot支持
在 org.springframework.boot.autoconfigure.jms下
ActiveMQ,HornetQ,Artemis(HornetQ捐赠 ActiveMQ的代码库形成ActiveMQ的子项目)
ActiveMQConnectionFactory 通过 spring.activemq配置
spring.activemq.broker-url=tcp//localhost:61616
spring.activemq.user=
spring.activemq.password=
spring.activemq.in-memory=true
spring.activemq.pooled=false
JmsAutoConfiguration为我们配置好了,JmsTemplate。且自动开启了 @EnableJms
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret
ConnectionFactory和RabbitTemplate。自动开启了 @EnableRabbit
Activemq实战
docker run -d -p 61616:61616 -p 8161:8161 cloudesire/activemq
61616 是消息代理的端口
8161 是ActiveMQ的管理界面端口: http://192.168.31.183:8161/
默认的用户名密码是 admin
pom.xml 和配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
spring.activemq.broker-url=tcp://localhost:61616
消息定义 实现MessageCreate
public class Msg implements MessageCreator{
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("测试消息");
}
}
消息发送及目的地
@SpringBootApplication
public class Ch934Application implements CommandLineRunner{ //1
@Autowired
JmsTemplate jmsTemplate; //2 注入配置好的模板
public static void main(String[] args) {
SpringApplication.run(Ch934Application.class, args);
}
@Override
public void run(String... args) throws Exception {
jmsTemplate.send("my-destination", new Msg()); //3 向这个目的地发消息。也定义了这个目的地
}
}
实现CommandLineRunner 接口,程序启动后执行的代码。
重写其Run方法
消息监听
@Component
public class Receiver {
@JmsListener(destination = "my-destination") //1
public void receiveMessage(String message) {
System.out.println("接受到: <" + message + ">");
}
}
RabbitMQ
RabbitMq 基于 erlang开发。 安装mq需要先安装erlang
docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:3-management 启动的带管理界面的
5672 消息代理的端口
15672 是 web管理界面的端口 guest/guest
<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>
</dependency>
spring.rabbitmq.host=192.168.31.183
提供者
@SpringBootApplication
public class Ch935Application implements CommandLineRunner{
@Autowired
RabbitTemplate rabbitTemplate; //1
public static void main(String[] args) {
SpringApplication.run(Ch935Application.class, args);
}
@Bean //2
public Queue wiselyQueue(){
return new Queue("my-queue");
}
@Override
public void run(String... args) throws Exception {
rabbitTemplate.convertAndSend("my-queue", "来自RabbitMQ的问候"); //3
}
}
消费者 消息监听
@Component
public class Receiver {
@RabbitListener(queues = "my-queue")
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
}
}