记录下修复ActiveMQ Artemis使用jms的时候阻塞的问题。
我在我的本地机器上安装了Artemis,根据说明创建了一个新的代理,并将其设置为Windows服务. Windows服务启动和停止就好了.我没有对broker.xml文件进行任何更改.
对于我的第一次测试,我正在尝试从独立的Java程序执行JMS Queue生成/使用.我正在使用“使用JMS”部分中的Artemis用户手册中的代码:
yml配置文件
spring:
activemq:
broker-url: tcp://xxxxxxxx:6100
user: xxx
password: xxxx
配置类
public class ActiveMQConfig {
@Value("${spring.activemq.broker-url}")
private String brokerUrl;
@Value("${spring.activemq.user}")
private String username;
@Value("${spring.activemq.password}")
private String password;
@Bean
public ActiveMQQueue queue() {
return new ActiveMQQueue("queue1");
}
@Bean
public ActiveMQTopic topicDestination() {
return new ActiveMQTopic("topic1");
}
@Bean
public ConnectionFactory connectionFactory() {
return new ActiveMQConnectionFactory(username, password, brokerUrl);
}
@Bean
public JmsMessagingTemplate jmsMessageTemplate() {
return new JmsMessagingTemplate(connectionFactory());
}
// 在Queue模式中,对消息的监听需要对containerFactory进行配置
@Bean("queueListener")
public JmsListenerContainerFactory<?> queueJmsListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(false);
return factory;
}
//在Topic模式中,对消息的监听需要对containerFactory进行配置
@Bean("topicListener")
public JmsListenerContainerFactory<?> topicJmsListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(true);
return factory;
}
}
消费者监听类
@Component
public class QueueConsumerListener {
@JmsListener(destination="queue1", containerFactory="queueListener")
public void readActiveQueue(String message) {
System.out.println("queue接受到:" + message);
}
}
controller类
@RestController
@RequestMapping("api")
public class apiController {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Queue queue;
@PostMapping("/queue/test")
public String sendQueue(String str) {
this.sendMessage(this.queue, str);
return "success";
}
// 发送消息,destination是发送到的队列,message是待发送的消息
private void sendMessage(Destination destination, final String message){
jmsMessagingTemplate.convertAndSend(destination, message);
}
}
当我运行postman调api/queue/test时,我收到以下错误:
程序运行在convertAndSend这里就没然后了,postman也还在转圈圈,证明当前请求是没有执行完的,但是debug的确实又是执行完了,因为下一步啥的按钮,全是灰色的,说明是代码运行了。
然后去服务器里面查看日志,看到
WARN: AMQ212054:Disk Full! Blocking message production on address ‘queue2’. Clients will report blocked.
磁盘已满!阻止地址’queue2’上的消息生成。客户端将报告阻塞
如果这是服务器端设置,或者生产者发送没有阻塞,我的研究还没有定论.我一直无法找到一个具有阻塞布尔值的生成器发送方法,只有持久性.关于在哪里集中注意力的想法?
编辑:添加到专用于此队列的broker.xml的新地址设置元素:
<address-setting match="jms.queue.OrderQueue">
<max-size-bytes>104857600</max-size-bytes>
<page-size-bytes>10485760</page-size-bytes>
<address-full-policy>PAGE</address-full-policy>
</address-setting>
我在用户手册的进一步研究中找到了这个:
max-disk-usage The max percentage of data we should use from disks.
The System will block while the disk is full. Default=100
并且在服务启动后的日志中尚未发布消息:
WARN [org.apache.activemq.artemis.core.server] AMQ222210: Storage usage is beyond max-disk-usage. System will start blocking producers.
所以我认为无论我的地址设置如何,它都会开始阻止.查看broker.xml中的max-disk-usage设置,它被设置为90.文档默认设置为100,我设置为,没有启动日志警告,我的测试api/queue/test代码现在可以工作.