ActiveMQ基本使用
Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。
消息中间件对比
优点
ActiveMQ 采用消息推送方式,所以最适合的场景是默认消息都可在短时间内被消费
。
数据量越大,查找和消费消息就越慢,消息积压程度与消息速度成反比。
缺点
1.吞吐量低。由于ActiveMQ需要建立索引,导致吞吐量下降。这是无法克服的缺点,只要使用完全符合JMS规范的消息中间件,就要接受这个级别的TPS。
2.无分片功能。这是一个功能缺失,JMS并没有规定消息中间件的集群、分片机制。而由于ActiveMQ是为企业级开发设计的消息中间件,初衷并不是为了处理海量消息和高并发请求。如果一台服务器不能承受更多消息,则需要横向拆分。ActiveMQ官方不提供分片机制,需要自己实现。
适用场景
对TPS要求比较低的系统,可以使用ActiveMQ来实现,一方面比较简单,能够快速上手开发,另一方面可控性也比较好,还有比较好的监控机制和界面
TPS:是TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
不适用场景
消息量巨大的场景。ActiveMQ不支持消息自动分片机制,如果消息量巨大,导致一台服务器不能处理全部消息,就需要自己开发消息分片功能(消息量巨大,Kafka就是为大数据量而生的)
SpringBoot整合ActiveMQ
安装
安装非常简单,官网下载,选择适合的版本,解压,安装启动即可。
需开启8161和61616端口,8161是用于后台管理的端口,61616是Java连接使用。
后台登录地址http://ip:8161/admin,用户名密码都是admin。
SpringBoot配置
1.引入pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
2.配置文件(yml文件)
spring:
activemq:
broker-url: tcp://127.0.0.1:61616
user: admin
password: admin
#这里简单对这个配置说明下:如果为True,则是Topic;如果是false或者默认,则是queue。
jms:
pub-sub-domain: true
pool:
enabled: false
maxConnections: 2
expiryTimeout: 0
idleTimeout: 30000
packages:
trust-all: true
导入pom文件后可以使用如下配置,无效安装,在本地内存中使用。
# 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
spring.activemq.in-memory=true
测试
ActiveMQ,有两种形式,分别为Queue(生产消费),Topic(发布订阅)。
Queue为点对点模式,即有一个消息,才能有一个消费,多个消费者不会重复对应一个消息。
Topic为一对多形式,当订阅者订阅后,发布者发布消息所有订阅者都会接受到消息。
Queue
Queue 配置
@Configuration
public class QueueConfig {
@Bean
public Queue queue() {
return new ActiveMQQueue("mytest.queue");
}
}
生产者
@Component
public class Producer {
@Autowired // 也可以注入JmsTemplate,JmsMessagingTemplate对JmsTemplate进行了封装
private JmsMessagingTemplate jmsTemplate;
@Autowired
private Queue queue;
// 发送消息,destination是发送到的队列,message是待发送的消息
public void sendMessage(final String message) {
this.jmsTemplate.convertAndSend(this.queue, message);
}
}
消费者
@Component
public class Consumer {
// 使用JmsListener配置消费者监听的队列,其中text是接收到的消息
@JmsListener(destination = "mytest.queue")
public void receiveQueue(String text) {
System.out.println("Consumer收到的报文为:" + text);
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class JmsTest {
@Autowired
private Producer producer;
@Test
public void contextLoads() throws InterruptedException {
for (int i = 0; i < 100; i++) {
this.producer.sendMessage("myname is chhliu!!!" + i);
}
}
}
运行之后登陆ActiveMQ后台管理界面如下:
Topic
Topic配置
@Configuration
public class TopicConfig {
@Bean
public Topic topic() {
return new ActiveMQTopic("neo.topic");
}
}
发布者
@Component
public class TopicProducer {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Topic topic;
public void sendTopic(String msg) {
this.jmsMessagingTemplate.convertAndSend(this.topic, msg);
}
}
订阅者
@Component
public class TopicConsumer {
@JmsListener(destination = "neo.topic")
public void receiveTopic(String text) {
System.out.println(text);
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class TopicTest {
@Autowired
private TopicProducer producer;
@Test
public void contextLoads() throws InterruptedException {
for (int i = 0; i < 100; i++) {
this.producer.sendTopic("Topic!!!" + i);
}
}
}
一切不以业务为基础的技术堆叠都是耍流氓!!!一定要根据自己系统需求使用中间件,否则反而是增加项目复杂度!!!