Spring Boot整合ActiveMq集群开发测试
参考官网:https://spring.io/guides/gs/messaging-jms/
目录
Spring Boot整合ActiveMq集群开发测试
搭建ActiveMq的集群
springboot整合activemq
引入依赖
配置application.yml
编写测试代码
使用JMeter进行多线程测试
设置线程组
设置http请求
运行
搭建ActiveMq的集群
ActiveMq的安装搜索引擎上都有,所以作者就不过多阐述了
把安装好的activemq复制两份放在同一目录下命名随意
首先进入apache-activemq-a中的conf文件对activemq.xml文件做出如下更改
代码如下
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<!--<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
<!--<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>-->
</transportConnectors>
<networkConnectors>
<networkConnector name="network_a" uri="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)"/>
</networkConnectors>
更改jetty.xml文件下的端口,也就是activemq控制台的端口
同时对apache-activemq-b与apache-activemq-c做出同一操作,更改下tcp的端口与控制台的端口
修改完成后我们分别启动activemq-a,activemq-b,activemq-c
同时进入activemq的控制台http://localhost:8161/,http://localhost:8162/,http://localhost:8163/
如果能顺利运行这就代表我们搭建成功了。。。。
springboot整合activemq
引入依赖
<!-- 整合activemq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.messaginghub</groupId>
<artifactId>pooled-jms</artifactId>
</dependency>
配置application.yml
spring:
activemq:
# 设置连接的activemq服务器
broker-url: failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)
#结束等待时长
close-timeout: 10s
# 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
in-memory: true
# 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留
non-blocking-redelivery: false
# 等待消息发送响应的时间。设置为0等待永远
send-timeout: 0
user: admin
password: admin
packages:
# 是否信任所有包
trust-all: true
# 要信任的特定包的逗号分隔列表(当不信任所有包时)
trusted:
pool:
# 当连接请求和池满时是否阻塞。设置false会抛“JMSException异常”。
block-if-full: true
# 如果池仍然满,则在抛出异常前阻塞时间。
block-if-full-timeout: -1ms
# 是否在启动时创建连接。可以在启动时用于加热池
#create-connection-on-startup: true
# 是否用Pooledconnectionfactory代替普通的ConnectionFactory。
enabled: false
# 连接过期超时。
#expiry-timeout: 0ms
# 连接空闲超时
idle-timeout: 30ms
# 连接池最大连接数
max-connections: 1
# 每个连接的有效会话的最大数目。
maximum-active-session-per-connection: 500
#当有"JMSException"时尝试重新连接
#reconnect-on-exception: true
# 在空闲连接清除线程之间运行的时间。当为负数时,没有空闲连接驱逐线程运行。
time-between-expiration-check: -1ms
# 是否只使用一个MessageProducer
use-anonymous-producers: true
jms:
#默认情况下activemq提供的是queue模式,若要使用topic模式需要配置下面配置
pub-sub-domain: true
编写测试代码
生产者
/*
* 生产者队列消息控制器
*/
@RestController
@RequestMapping("message")
public class ProducerController {
@Autowired
private QueueMessageService queueMessageService;
/*
* 消息生产者
*/
@GetMapping("sendmsg")
public void sendmsg(String msg) {
// 指定消息发送的目的地及内容
queueMessageService.setQueue("queue",msg);
}
@GetMapping("send")
public void send(String msg) {
// 指定消息发送的目的地及内容
System.out.println(new Date().toString());
queueMessageService.setTopic("topic",msg);
}
}
@Component
public class QueueMessageService {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
/**
* 使用queue模式注册队列
* @param queue
* @param msg
*/
public void setQueue(String queue,String msg){
jmsMessagingTemplate.convertAndSend(new ActiveMQQueue(queue),msg);
}
/**
* 使用topic模式注册队列
* @param topic
* @param msg
*/
public void setTopic(String topic,String msg) {
jmsMessagingTemplate.convertAndSend(new ActiveMQTopic(topic),msg);
}
}
消费者
/**
* 消费者客户控制器
*/
@RestController
public class ConsumerController {
@Autowired
private HfnsTermService hfnsTermService;
/**
* 监听队列
* @param message
*/
@JmsListener(destination="queue")
public void readActiveQueue(String message) {
System.out.println("queue模式接收:" + message);
//TODO something
}
@JmsListener(destination = "queue")
public void readQueue(String message){
System.out.println("queue模式接收:"+message);
}
@JmsListener(destination = "topic")
public void receiveMessage(String message) throws InterruptedException {
Thread.sleep(4000);
System.out.println(hfnsTermService.getCount());
System.out.println(new Date().toString()+"topic接收:"+message);
}
@JmsListener(destination = "topic")
public void readResponse(String message) throws InterruptedException {
Thread.sleep(1000);
for(HfnsTerm hfnsTerm:hfnsTermService.getHfnsTerm()){
System.out.println(hfnsTerm.getId());
}
System.out.println(new Date().toString()+"topic1接收:"+message);
}
}
为了接近实际情况与便于观察,我在接收时使用了sleep来延时,在这次测试中我使用了两个项目,一个用于生产者,一个用于消费者,同时activemq-b与activemq-c承担生产者与消费者的作用,activemq-a只用于消费者不承担生产者的作用
使用JMeter进行多线程测试
设置线程组
我设置了一个为期300秒的请求,一个一百个线程请求,循环一次
设置http请求
对生产者项目进行请求,发送的消息为activemq共享集群测试
运行
分别启动生产者与消费者的项目,使用jmeter运行执行计划,在active-a控制台与idea控制台我们可以看到队列已经在接收请求了
这时我们关闭掉一台消费者服务active-a可以发现http://localhost:8161/无法访问了,此时在http://localhost:8162/中我们可以看到active-b在接收请求
消费者控制台可以看到,activemq-a的服务断开了,但是依然可以接收到请求
我们把active-b关闭,可以看到此时的请求全部都交给了activemq-c处理,消费者依然能够接收到队列中的消息