Spring集成 - 跨多个TCP出站网关的负载平衡

时间:2016-05-22 23:23:02

标签: spring spring-integration spring-java-config spring-dsl

我有一个具有多个进程的(传统)TCP服务。每个进程在同一主机上运行,​​但在不同的端口上运行。该服务是单线程的,因此提高吞吐量的方法是在每个端口上循环每个请求。

我正在为此遗留应用程序提供AMQP曝光。它非常简单 - 从AMQP队列中取出一个字符串,将其传递给应用程序,并将响应字符串返回给AMQP应答队列。

这在单个端口上运行良好。但是,我想在所有端口上扇出请求。

Spring Integration似乎只提供AbstractClientConnectionFactory实现,它们直接连接到单个主机/端口(TcpNetClientConnectionFactory)或维护到单个主机/端口的连接池(CachingClientConnectionFactory )。单个主机和多个端口之间没有任何池连接。

我试图编写自己的AbstractClientConnectionFactory来维护AbstractClientConnectionFactory个对象和它们之间的循环。但是,当目标服务消失或网络中断而我无法解决时,我已经解决了几个与处理TCP连接有关的问题。

此问题还采用了这种方法:Spring Integration 4 - configuring a LoadBalancingStrategy in Java DSL但解决方法是对端点数量进行硬编码。在我的例子中,端点的数量仅在运行时已知,并且是用户可配置的设置。

所以,基本上我需要在运行时动态地为每个端口创建一个TcpOutboundGateway,并以某种方式在我的IntegrationFlow中注册它。我尝试了以下方法:

@Bean
public IntegrationFlow xmlQueryWorkerIntegrationFlow() {
    SimpleMessageListenerContainer inboundQueue = getMessageListenerContainer();

    DirectChannel rabbitReplyChannel = MessageChannels.direct().get();

    IntegrationFlowBuilder builder = IntegrationFlows
            .from(Amqp.inboundGateway(inboundQueue)
                      .replyChannel(rabbitReplyChannel))    
            /* SOMEHOW DO THE ROUND ROBIN HERE */
            //I have tried:
            .channel(handlerChannel()) //doesnt work, the gateways dont get started and the message doesnt get sent to the gateway
            //and I have also tried:
            .handle(gateway1)
            .handle(gateway2) //doesnt work, it chains the handlers instead of round-robining between them
            //
            .transform(new ObjectToStringTransformer())
            .channel(rabbitReplyChannel); 

    return builder.get();

}

@Bean
//my attempt at dynamically adding handlers to the same channel and load balancing between them
public DirectChannel handlerChannel() {
    DirectChannel channel = MessageChannels.direct().loadBalancer(new RoundRobinLoadBalancingStrategy()).get();
    for (AbstractClientConnectionFactory factory : generateConnections()) {
        channel.subscribe(generateTcpOutboundGateway(factory));
    }
    return channel;
}

有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

参见dynamic ftp sample - 实质上每个出站网关都进入自己的应用程序上下文,动态路由器路由到相应的通道(必要时为其创建出站适配器)。

虽然示例使用XML,但您可以使用Java配置,甚至使用Java DSL执行相同的操作。

查看我对similar question for multiple IMAP mail adapters using Java configuration的回答,然后是follow-up question