您好我在这里再次询问spring integration的tcp-ip相关问题。
假设我有一个动态配置的tcp-ip连接工厂:
<int-ip:tcp-connection-factory id="chatRoomTcpIpClientFactory"
type="client"
host="${host}"
port="${port}"
single-use="false"
using-nio="false"
so-keep-alive="false"
so-timeout="${timeout}"
serializer="${seri-deseri}"
deserializer="${seri-deseri}"/>
这里,主持人&amp;端口在开始时都是未知的。有时,该计划不能授予主持人和端口有效。假设有一个ip /端口8.8.8.8:12345在目标服务器上未打开。现在Spring框架抛出:
2015-08-13 22:07:52.906 ERROR 24479 --- [nio-8080-exec-1] o.s.i.ip.tcp.TcpSendingMessageHandler : Error creating connection
java.net.ConnectException: Connection refused
假设我的业务逻辑严重依赖于tcp-ip连接,并且程序希望对此特定套接字连接错误进行一些错误处理。 (例如,将错误写入redis缓存,使用其他ip / port重新连接等等)
我已经找到了解决方案,现在我知道在这种低级异常中没有触发“errorChannel”。这同样适用于tcp-connection-event-inbound-channel-adapter。
经过一些谷歌搜索,似乎工厂bean里面的“建议”或者带有chainFactory的TcpConnectionInterceptorSupport是要走的路......但我还是很困惑。 tcp连接失败很常见。有没有更简单的方法来处理连接异常?
编辑:我深入研究了源代码,现在我在我的方法中添加了一个try-catch。它现在有效。至于tcp-connection-event-inbound-channel-adapter,它仍然不起作用。似乎套接字创建异常未发布...
当服务尝试通过套接字发送消息时,TcpSendingMessageHandler会获取异常...
编辑2: 跟踪堆栈跟踪:
2015-08-14 10:31:53.694 ERROR 2531 --- [nio-8080-exec-1] o.s.i.ip.tcp.TcpSendingMessageHandler : Error creating connection
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:271)
at org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.createSocket(TcpNetClientConnectionFactory.java:76)
at org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.buildNewConnection(TcpNetClientConnectionFactory.java:49)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.obtainNewConnection(AbstractClientConnectionFactory.java:114)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.obtainConnection(AbstractClientConnectionFactory.java:77)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.getConnection(AbstractClientConnectionFactory.java:67)
at org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory.getConnection(AbstractClientConnectionFactory.java:31)
at org.springframework.integration.ip.tcp.TcpSendingMessageHandler.obtainConnection(TcpSendingMessageHandler.java:72)
at org.springframework.integration.ip.tcp.TcpSendingMessageHandler.doWrite(TcpSendingMessageHandler.java:144)
at org.springframework.integration.ip.tcp.TcpSendingMessageHandler.handleMessageInternal(TcpSendingMessageHandler.java:120)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:287)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245)
at (My service call)
这里,在TcpNetClientConnectionFactory.buildNewConnecton()中,
写成:
protected TcpConnectionSupport buildNewConnection() throws IOException, SocketException, Exception {
Socket socket = createSocket(this.getHost(), this.getPort()); //<--- Where exception is thrown
setSocketAttributes(socket);
TcpConnectionSupport connection = new TcpNetConnection(socket, false, this.isLookupHost(),
this.getApplicationEventPublisher(), this.getComponentName());
connection = wrapConnection(connection);
initializeConnection(connection, socket);
this.getTaskExecutor().execute(connection);
this.harvestClosedConnections();
return connection;
}
因此,甚至没有达到TcpConnectionSupport。事件驱动的适配器无法处理套接字创建期间发生的异常。这就是为什么我一直在努力寻找答案的原因。
在TcpSendingMessageHandler中,
protected TcpConnection obtainConnection(Message<?> message) {
TcpConnection connection = null;
Assert.notNull(this.clientConnectionFactory, "'clientConnectionFactory' cannot be null");
try {
connection = this.clientConnectionFactory.getConnection();
}
catch (Exception e) {
logger.error("Error creating connection", e);
throw new MessageHandlingException(message, "Failed to obtain a connection", e);
}
return connection;
}
这里只记录错误,并再次抛出新的异常。
答案 0 :(得分:2)
请查看TcpConnectionEvent
层次结构,尤其是TcpConnectionExceptionEvent
。并调查TcpConnection
实现发布它的位置。
答案 1 :(得分:0)
关闭套接字后,事件TcpConnectionFailedEvent
被触发(它扩展了org.springframework.integration.ip.tcp.connection.IpIntegrationEvent
)。
这里是使用方法:
@EventListener
public void handleEvent(TcpConnectionFailedEvent event) {
// handle the event
}