Java 仅当线程池中的线程可用于处理JMS队列中的消息时,才将其从JMS队列中解列
需求是侦听JMS队列,以异步方式处理请求,并在不同的JMS队列上发送响应。系统只允许在一个时刻处理固定数量的请求。除非有线程可用于处理请求,否则不能将其退出队列Java 仅当线程池中的线程可用于处理JMS队列中的消息时,才将其从JMS队列中解列,java,spring,spring-jms,spring-async,Java,Spring,Spring Jms,Spring Async,需求是侦听JMS队列,以异步方式处理请求,并在不同的JMS队列上发送响应。系统只允许在一个时刻处理固定数量的请求。除非有线程可用于处理请求,否则不能将其退出队列 使用@JMSListener注释的方法从请求队列中取出请求 递增全局计数器 侦听器通过调用@Async注释的方法来执行请求 如果计数器==线程池的最大大小,则停止侦听。否则,侦听器就可以自由地侦听新请求 Async方法处理该请求,并调用生产者服务中的sendResponse()方法在响应队列上发送响应 生产者方法在响应队列上发送响应,并
@Service
public class ActiveMQListener{
@Autowired
ApplicationContext applicationContext;
@Autowired
AsyncService aSyncService;
@Autowired
ThreadPoolCounter threadPoolCounter;
@JmsListener(id = "req1", destination = "RequestQueue1", containerFactory = "jmsFactory")
public void receiveRequest(ActiveMQTextMessage message) throws JMSException {
String requestMsg = messget.getText()
//some validation
aSyncService.executeRequest(requestMsg);
if(threadPoolCounter.incrementCounter() == 10){
JmsListenerEndpointRegistry customRegistry = applicationContext.getBean(JmsListenerEndpointRegistry.class);
MessageListenerContainer listenerContainer = customRegistry.getListenerContainer("req1");
listenerContainer.stop();
}
}
}
制作人:
@Service
public class ActiveMQProducer {
@Autowired
JmsTemplate jmsTemplate;
@Autowired
ThreadPoolCounter threadPoolCounter;
@Autowired
ApplicationContext applicationContext;
public void sendResponse(ActiveMQTextMessage responseMsg) throws JMSException {
jmsTemplate.convertAndSend("res1" , responseMsg);
threadPoolCounter.decrement();
JmsListenerEndpointRegistry customRegistry = applicationContext.getBean(JmsListenerEndpointRegistry.class);
MessageListenerContainer listenerContainer = customRegistry.getListenerContainer("req1");
if(!listenerContainer.isRunning()){
listenerContainer.start();
}
}
}
异步方法:
@Service
public class AsyncService{
@Autowired
ActiveMQProducer activeMQProducer;
@Async("RequestExecutor")
public void executeRequest(String requestMsg) {
String resposeMsg = "";
//Some Async Processing
ActiveMQTextMessage message = new ActiveMQTextMessage();
message.setText(responseMsg);
activeMQProducer.sendResponse(message);
}
}
我的想法:将侦听器be=的并发性增加到线程池大小。将异步方法的返回类型更改为返回Future。这应该可以解决这样一个问题,即确保只有当线程可以处理请求时,请求才会被出列。但是,在这种情况下,线程的数量增加了一倍。例如,如果线程池大小为10,那么我将有10个侦听器线程等待将来。get()。如果将来必须增加要处理的请求数,那么它可能会受到侦听器线程数的影响
@Service
public class ActiveMQListener{
@Autowired
AsyncService aSyncService;
@Autowired
ActiveMQProducer activeMQProducer;
@JmsListener(id = "req1", destination = "RequestQueue1", containerFactory = "jmsFactory")
public void receiveRequest(ActiveMQTextMessage message) throws JMSException {
String requestMsg = messget.getText()
//some validation
Future<String> future = aSyncService.executeRequest(requestMsg);
String responseMsg = future.get();
activeMQProducer.sendResponse(responseMsg);
}
}
@服务
公共类ActiveMQListener{
@自动连线
异步服务异步服务;
@自动连线
ActiveMQProducer-ActiveMQProducer;
@JmsListener(id=“req1”,destination=“RequestQueue1”,containerFactory=“jmsFactory”)
public void receiveRequest(ActiveMQTextMessage消息)引发JMSException{
String requestMsg=messget.getText()
//一些验证
Future=aSyncService.executeRequest(requestMsg);
字符串responseMsg=future.get();
activeMQProducer.sendResponse(responseMsg);
}
}
您不是在试图超越框架吗?只需删除@Async
,并将侦听器设置为多线程。这应该能满足你的需要,而不是像这样把它塞住。我还建议使用JmsTemplate
来发送响应,而不是直接绑定到ActiveMQ.@M.Deinum当我有多个侦听器但应该一次处理10个请求时如何。如果我在两个侦听器(每个侦听器5个)之间拆分并发,并且其中一个侦听器上没有请求,那么我一次只能处理5个请求。您可以使用包含10个线程的ThreadPoolTaskExecutor
配置DefaultJMSlinerContainerFactory
。然后,这些线程将在不同的DefaultJmsListenerContainer
实例之间共享。我强烈建议阅读文档(参考和java文档),其中解释了所有这些。