Spring 集成:同一池中连接的单独超时设置
Spring Integration: individual timeouts settings for connections in the same pool
我们有一个用 Java 编写的应用程序,它使用 Spring 集成。应用程序向 3d 方服务发送请求,每个请求都表示为字节数组并通过纯 TCP 发送。与 3d 方的连接存储在池中(使用 CachingClientConnectionFactory)。
我们可以向3d方发送多种类型的请求,现在需要为每种类型的请求设置不同的超时值。但是,就目前而言,这看起来有问题,因为为 Gateway 和 ConnectionFactory 组件设置了连接超时设置,并且无法为特定的单个请求设置连接超时。
我们希望避免仅仅为了支持不同的连接超时而引入多个网关和连接工厂。
通道和网关配置
<int:channel id="myInput" />
<int:gateway id="myGateway"
service-interface="com.mypackage.TcpGateway"
default-request-channel="myInput"/>
<int-ip:tcp-outbound-gateway id="myOutGateway"
request-channel="mybInput"
reply-channel="clientBytesChannel"
connection-factory="myConnectionFactory"
request-timeout="${conn.timeout}"
remote-timeout="${conn.timeout}"/>
TcpGateway.java
package com.mypackage.TcpGateway;
public interface TcpGateway {
byte[] send(byte[] message);
}
RequestProcessor.java
public class RequestProcessors {
@Autowired
private TcpGateway myGateway;
public MyResponse process(MyRequest requestMessage) {
byte[] binaryMessage = transformRequest(requestMessage);
byte[] response = myGateway.send(binaryMessage);
return transformResponse(response);
}
// rest of business logic here
}
查看上面的源代码,似乎最简单的方法是扩展本机组件 TcpOutboundGateway 并用一个将超时设置保存为 [=15] 的单例 bean 替换 属性 remoteTimeout
=] 变量。然后就可以在将请求传递给 myGateway.send()
之前,在 RequestProcessors.process()
方法中根据请求类型设置必要的值。
但是,我无法找到一种优雅的方式来使用我的自定义 class 重新定义 TcpOutboundGateway 组件。在分析了Spring Integration 的源代码后,似乎TcpOutboundGateway 对输入请求一无所知,而是注册在消息处理器链中,并在需要时调用。所以,现在这看起来不像是一个简单的解决方案。
如果您对如何更改标记 <int-ip:tcp-outbound-gateway>
使用的 class 有任何想法,或者如果您对如何以完全不同的方式解决主要超时问题有任何想法,请指教。
谢谢。
有趣的问题。
您是正确的,(当前)AsyncReply
对象不知道原始出站消息。
我们可以做的一件事是添加一个 remote-timeout-expression
并根据消息计算超时...
AsyncReply reply = new AsyncReply(calculateReplyTimeout(requestMessage));
随意开一个JIRA Improvement Issue。
同时如果你想定制网关,你可以很容易地做到。
虽然命名空间 (<int-ip:...
) 不支持自定义 类,但您始终可以使用 <bean/>
s 连接网关。
您需要一个 ConsumerEndpointFactoryBean
,它会在其 handler
属性 中获取您的自定义网关。
我们有一个用 Java 编写的应用程序,它使用 Spring 集成。应用程序向 3d 方服务发送请求,每个请求都表示为字节数组并通过纯 TCP 发送。与 3d 方的连接存储在池中(使用 CachingClientConnectionFactory)。
我们可以向3d方发送多种类型的请求,现在需要为每种类型的请求设置不同的超时值。但是,就目前而言,这看起来有问题,因为为 Gateway 和 ConnectionFactory 组件设置了连接超时设置,并且无法为特定的单个请求设置连接超时。
我们希望避免仅仅为了支持不同的连接超时而引入多个网关和连接工厂。
通道和网关配置
<int:channel id="myInput" />
<int:gateway id="myGateway"
service-interface="com.mypackage.TcpGateway"
default-request-channel="myInput"/>
<int-ip:tcp-outbound-gateway id="myOutGateway"
request-channel="mybInput"
reply-channel="clientBytesChannel"
connection-factory="myConnectionFactory"
request-timeout="${conn.timeout}"
remote-timeout="${conn.timeout}"/>
TcpGateway.java
package com.mypackage.TcpGateway;
public interface TcpGateway {
byte[] send(byte[] message);
}
RequestProcessor.java
public class RequestProcessors {
@Autowired
private TcpGateway myGateway;
public MyResponse process(MyRequest requestMessage) {
byte[] binaryMessage = transformRequest(requestMessage);
byte[] response = myGateway.send(binaryMessage);
return transformResponse(response);
}
// rest of business logic here
}
查看上面的源代码,似乎最简单的方法是扩展本机组件 TcpOutboundGateway 并用一个将超时设置保存为 [=15] 的单例 bean 替换 属性 remoteTimeout
=] 变量。然后就可以在将请求传递给 myGateway.send()
之前,在 RequestProcessors.process()
方法中根据请求类型设置必要的值。
但是,我无法找到一种优雅的方式来使用我的自定义 class 重新定义 TcpOutboundGateway 组件。在分析了Spring Integration 的源代码后,似乎TcpOutboundGateway 对输入请求一无所知,而是注册在消息处理器链中,并在需要时调用。所以,现在这看起来不像是一个简单的解决方案。
如果您对如何更改标记 <int-ip:tcp-outbound-gateway>
使用的 class 有任何想法,或者如果您对如何以完全不同的方式解决主要超时问题有任何想法,请指教。
谢谢。
有趣的问题。
您是正确的,(当前)AsyncReply
对象不知道原始出站消息。
我们可以做的一件事是添加一个 remote-timeout-expression
并根据消息计算超时...
AsyncReply reply = new AsyncReply(calculateReplyTimeout(requestMessage));
随意开一个JIRA Improvement Issue。
同时如果你想定制网关,你可以很容易地做到。
虽然命名空间 (<int-ip:...
) 不支持自定义 类,但您始终可以使用 <bean/>
s 连接网关。
您需要一个 ConsumerEndpointFactoryBean
,它会在其 handler
属性 中获取您的自定义网关。