我有一个需要持久TCP连接的应用程序。所以我在Tcp连接器上设置了一些适当的属性来支持它。我遇到的问题是如果外部应用程序出现故障并重新启动,Mule将继续尝试将消息发送到套接字而不是尝试重新建立连接。
<mule ...>
<tcp:connector name="tcpConn" doc:name="TCP connector" keepAlive="true" keepSendSocketOpen="true" reuseAddress="true" validateConnections="true">
<reconnect-forever frequency="2000" />
<tcp:direct-protocol payloadOnly="true"/>
</tcp:connector>
<flow name="ExampleFlow1" doc:name="ExampleFlow1">
<vm:inbound-endpoint exchange-pattern="one-way" path="msg.in" doc:name="VM">
<vm:transaction action="ALWAYS_BEGIN"/>
</vm:inbound-endpoint>
<tcp:outbound-endpoint exchange-pattern="one-way" host="127.0.0.1" port="50002" responseTimeout="10000" doc:name="TCP"/>
</flow>
<flow name="example1" doc:name="example1">
<tcp:inbound-endpoint exchange-pattern="one-way" host="0.0.0.0" port="50001" responseTimeout="10000" doc:name="TCP"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="msg.in" doc:name="VM">
</vm:outbound-endpoint>
</flow>
</mule>
这是我的错误日志:
ERROR 2014-04-30 17:11:35,436 [[chatroomexample].connector.VM.mule.default.receiver.04] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=tcp://127.0.0.1:50002, connector=TcpConnector
{
name=tcpConn
lifecycle=start
this=198bdbc
numberOfConcurrentTransactedReceivers=4
createMultipleTransactedReceivers=true
connected=true
supportedProtocols=[tcp]
serviceOverrides=<none>
}
, name='endpoint.tcp.127.0.0.1.50002', mep=ONE_WAY, properties={}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=10000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: byte[]
Type : org.mule.api.transport.DispatchException
Code : MULE_ERROR--2
Payload : [B@7cfbc3
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html
********************************************************************************
Exception stack is:
1. Connection reset by peer: socket write error (java.net.SocketException)
java.net.SocketOutputStream:-2 (null)
2. Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=tcp://127.0.0.1:50002, connector=TcpConnector
{
name=tcpConn
lifecycle=start
this=198bdbc
numberOfConcurrentTransactedReceivers=4
createMultipleTransactedReceivers=true
connected=true
supportedProtocols=[tcp]
serviceOverrides=<none>
}
, name='endpoint.tcp.127.0.0.1.50002', mep=ONE_WAY, properties={}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=10000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: byte[] (org.mule.api.transport.DispatchException)
org.mule.transport.AbstractMessageDispatcher:109 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)
********************************************************************************
Root Exception stack trace:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at org.mule.transport.tcp.TcpMessageDispatcher.write(TcpMessageDispatcher.java:129)
at org.mule.transport.tcp.TcpMessageDispatcher.dispatchToSocket(TcpMessageDispatcher.java:122)
at org.mule.transport.tcp.TcpMessageDispatcher.doDispatch(TcpMessageDispatcher.java:50)
at org.mule.transport.AbstractMessageDispatcher.process(AbstractMessageDispatcher.java:99)
at org.mule.transport.AbstractConnector$DispatcherMessageProcessor.process(AbstractConnector.java:2627)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.processor.AsyncInterceptingMessageProcessor.process(AsyncInterceptingMessageProcessor.java:101)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.endpoint.outbound.OutboundResponsePropertiesMessageProcessor.process(OutboundResponsePropertiesMessageProcessor.java:39)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:61)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:47)
at org.mule.processor.EndpointTransactionalInterceptingMessageProcessor$1.process(EndpointTransactionalInterceptingMessageProcessor.java:50)
at org.mule.processor.EndpointTransactionalInterceptingMessageProcessor$1.process(EndpointTransactionalInterceptingMessageProcessor.java:47)
at org.mule.execution.ExecuteCallbackInterceptor.execute(ExecuteCallbackInterceptor.java:20)
at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:58)
at org.mule.execution.ResolvePreviousTransactionInterceptor.execute(ResolvePreviousTransactionInterceptor.java:48)
at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:54)
at org.mule.execution.ValidateTransactionalStateInterceptor.execute(ValidateTransactionalStateInterceptor.java:44)
at org.mule.execution.IsolateCurrentTransactionInterceptor.execute(IsolateCurrentTransactionInterceptor.java:44)
at org.mule.execution.ExternalTransactionInterceptor.execute(ExternalTransactionInterceptor.java:52)
at org.mule.execution.TransactionalExecutionTemplate.execute(TransactionalExecutionTemplate.java:69)
at org.mule.processor.EndpointTransactionalInterceptingMessageProcessor.process(EndpointTransactionalInterceptingMessageProcessor.java:56)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
at org.mule.execution.Messa...
********************************************************************************
以下是这个想法:
以下是我的尝试:
这项功能是否支持开箱即用,或者我需要说,实施自定义的RetryPolicy&amp; RetryPolicyTemplate应用到我的TCP连接器?如果我需要实现一个自定义的套接字,我将如何保持断开的套接字并重新建立连接?
TIA!
答案 0 :(得分:0)
我解决了这个问题......有点......根据Ian Gil Ragudo's suggestion创建我自己的自定义TcpConnector,TcpMessageDispatcher和TcpMessageDispatcherFactory类
以下是我定义连接器的方法:
<spring:bean id="dispatcherFactory" class="com.mycompany.mule.tcp.MyTcpMessageDispatcherFactory"/>
<spring:bean id="protocol" class="org.mule.transport.tcp.protocols.DirectProtocol"/>
<custom-connector name="myTcpConn" class="com.mycompany.mule.tcp.MyTcpConnector" >
<spring:property name="dispatcherFactory" ref="dispatcherFactory" />
<spring:property name="tcpProtocol" ref="protocol"/>
<spring:property name="keepAlive" value="true"/>
<spring:property name="keepSendSocketOpen" value="true"/>
<spring:property name="reuseAddress" value="true"/>
</custom-connector>
<tcp:endpoint connector-ref="myTcpConn" exchange-pattern="one-way" host="0.0.0.0" port="8081" name="TcpEndpoint" responseTimeout="10000" doc:name="TCP"/>
不幸的是,由于方法和实例变量的可见性,我不得不解决复制+ pasta类,更新强制转换,并且只在MyTcpMessageDispatcher类中编辑了这个位:
@Override
protected synchronized void doDispatch(MuleEvent event) throws Exception
{
Socket socket = connector.getSocket(endpoint);
try
{
dispatchToSocket(socket, event);
}
catch (SocketException e)
{
System.err.println(e.toString());
socket.close();
throw e;
}
finally
{
connector.releaseSocket(socket, endpoint);
}
}
已知问题:当出站端点关闭的外部应用程序发生故障,然后重新启动时,即使配置了事务,我似乎也会丢失一条消息。在抛出套接字写入异常之前,它似乎仍然最后一次成功写入套接字。