Spring集成tcp网关可以按如下方式设置:
<!-- Server side -->
<int-ip:tcp-connection-factory id="crLfServer"
type="server"
port="${availableServerSocket}"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="crLfServer"
request-channel="serverBytes2StringChannel"
error-channel="errorChannel"
reply-timeout="10000" />
<int:channel id="toSA" />
<int:service-activator input-channel="toSA"
ref="echoService"
method="test"/>
<bean id="echoService"
class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<int:object-to-string-transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
<int:transformer id="errorHandler"
input-channel="errorChannel"
expression="Error processing payload"/>
注意reply-timeout设置为10秒。
这是否意味着TCP服务器将调用该服务并且可以等待最多10秒?如果服务在10秒内没有回复,TCP服务器是否会将消息发送到errorChannel,而errorChannel又会发送客户端错误消息“Error processing payload”?
当我使用需要20秒的服务测试TCP服务器时,客户端需要20秒才能获得响应。我没有看到错误消息。
请帮助理解TCP入站网关中的回复超时?
由于
更新: 感谢Artem帮助解决这个问题。 解决此问题的最佳方法是使用以下配置:
<beans>
<int-ip:tcp-connection-factory id="crLfServer" type="server" port="${availableServerSocket}"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf" connection-factory="crLfServer" request-channel="requestChannel" error-channel="errorChannel" reply-timeout="5000" />
<int:service-activator input-channel="requestChannel" ref="gateway" requires-reply="true"/>
<int:gateway id="gateway" default-request-channel="timeoutChannel" default-reply-timeout="5000" />
<int:object-to-string-transformer id="serverBytes2String" input-channel="timeoutChannel" output-channel="serviceChannel"/>
<int:channel id="timeoutChannel">
<int:dispatcher task-executor="executor"/>
</int:channel>
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
<int:service-activator input-channel="serviceChannel" ref="echoService" method="test"/>
<bean id="echoService" class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<int:transformer id="errorHandler" input-channel="errorChannel" expression="payload.failedMessage.payload + ' errorHandleMsg: may be timeout error'"/>
</beans>
由于
答案 0 :(得分:1)
嗯,实际上我们应该在该属性上描述我们在其他类似地方的描述,例如: HTTP入站网关:
<xsd:attribute name="reply-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Used to set the receiveTimeout on the underlying MessagingTemplate instance
(org.springframework.integration.core.MessagingTemplate) for receiving messages
from the reply channel. If not specified this property will default to "1000"
(1 second).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
该超时意味着等待下游流的回复多少。但!如果你将flow转移到某个地方的另一个线程,这是可能的。否则一切都在调用者的线程中执行,因此等待时间不确定。
无论如何,我们在超时后返回null
而没有回复。它反映在TcpInboundGateway
:
Message<?> reply = this.sendAndReceiveMessage(message);
if (reply == null) {
if (logger.isDebugEnabled()) {
logger.debug("null reply received for " + message + " nothing to send");
}
return false;
}
我们可以重新考虑TcpInboundGateway
中的逻辑:
if (reply == null && this.errorOnTimeout) {
if (object instanceof Message) {
error = new MessageTimeoutException((Message<?>) object, "No reply received within timeout");
}
else {
error = new MessageTimeoutException("No reply received within timeout");
}
}
但对我来说,依靠客户端的超时确实会更好。
<强>更新强>
我认为我们可以通过midflow <gateway>
:
<gateway id="gateway" default-request-channel="timeoutChannel" default-reply-timeout="10000"/>
<channel id="timeoutChannel">
<dispatcher task-executor="executor"/>
</channel>
<service-activator input-channel="requestChannel"
ref="gateway"
requires-reply="true"/>
因此,<service-activator>
调用<gateway>
并等待来自那里的回复。当然,要求最后一个最终得到ReplyRequiredException
,您可以在MessageTimeoutException
的错误流程中将其转换为所需的error-channel="errorChannel"
。
timeoutChannel
是执行者之一,使我们的default-reply-timeout="10000"
非常有用,因为我们立即将网关上的消息转移到单独的线程中并从那里直接移动到回复等待进程中CountDonwLatch
。
希望很清楚。