我有两个应用程序在ActiveMQ代理的任一侧运行;应用程序1向应用程序2发送同步请求,应用程序2将响应返回给应用程序1.
申请1
@MessagingGateway
public interface OrderGateway {
@Gateway(requestChannel = "requestChannel", replyChannel = "responseChannel")
public OrderDto fetchOrder(OrderRequest orderRequest);
}
@Bean
public IntegrationFlow outgoingRequestFlow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from("requestChannel")
.handle(Jms.outboundGateway(connectionFactory).requestDestination("order.queue"))
.get();
}
申请2
@Bean
public IntegrationFlow incomingRequestFlow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Jms.inboundGateway(connectionFactory).destination("order.queue"))
.channel("requestChannel")
.handle("orderServiceActivator", "fetchOrder")
.channel("responseChannel")
.get();
}
@Component
public class OrderServiceActivator {
@Autowired
OrderService orderService;
@ServiceActivator
public OrderDto fetchOrder(OrderRequest orderRequest) {
return orderService.getById(orderRequest.getId());
}
}
两个应用程序都包含以下代理连接工厂配置:
@Bean(destroyMethod = "stop")
public PooledConnectionFactory activeMQConnectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL("tcp://broker.local:61616");
return new PooledConnectionFactory(activeMQConnectionFactory);
}
我在应用程序1 /myapp/order/{id}
中创建了一个REST控制器,它向orderGateway.fetchOrder
提交了一个正常工作的请求。然后我通过在命令行运行while true; do curl http://localhost:8080/myapp/order/1; done
并让它运行几分钟来测试它,它通过应用程序发送了数百个请求,没有错误,一切都很好。我可以看到request.queue
在ActiveMQ管理工具中将消息入队并出列,ActiveMQ.Advisory.TempQueue
也有很高的入队/出队计数。
存在并发请求时会出现问题;如果我打开两个终端窗口并在两个窗口中运行curl-loop,我很快就会看到以下错误:
Sep 21, 2015 4:35:25 PM org.springframework.jms.listener.DefaultMessageListenerContainer invokeErrorHandler
WARNING: Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.InvalidDestinationException: Cannot publish to a deleted Destination: temp-queue://ID:Stans-MacBook-Pro.local-64816-1442849675850-1:1:559
我的SI配置错了吗?我需要应用其他一些配置参数吗?感谢您提供任何指导。
答案 0 :(得分:1)
我需要从双方看到一个调试日志来弄清楚发生了什么 - 这意味着客户端已超时;但是,默认超时为5秒。您可以增加出站网关上的receiveTimeout
。
也就是说,使用命名的回复目的地通常更好,以避免为每个请求创建临时回复队列。请记住,同样的超时也适用于此。