2016-06-30 17 views
2

バネ統合に基づくMy TCP Serverは素晴らしい動作をしています。バネ統合のカスタマイズトランス

また、サービスが長時間かかると、サーバーでのreply-timeoutも処理されます。サービスがreply-timeoutより長く設定されると、エラーチャネルにメッセージが送信され、エラーメッセージがクライアントに返されます。

は、ここに私のコードです:

<int:transformer id="errorHandler" 
    input-channel="errorChannel" 
    ref="myTransformer" method="transform" /> 
<bean id="myTransformer" class="com.sample.MyTransformer" /> 

public class MyTransformer { 
    private static Logger logger = Logger.getLogger(MyTransformer.class); 

    public String transform(org.springframework.integration.handler.ReplyRequiredException e) { 
     logger.error("timeout exception is thrown"); 
     return "Error in processing request."; 
    } 
} 

上記のコードが動作し、クライアントには「処理要求でエラーが発生しました」を取得して、サーバーのログは、「タイムアウト例外がスローされる」エントリがあります。しかし、私はまた、ログに次の例外を参照してください。MyTransformerの

2016-06-30 16:25:27,827 ERROR [org.springframework.integration.handler.LoggingHandler] org.springframework.integration.handler.ReplyRequiredException: No reply produced by handler 'org.springframework.integration.config.ServiceActivatorFactoryBean#0', and its 'requiresReply' property is set to true. 
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109) 
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) 
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120) 
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:150) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:45) 
    at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:42) 
    at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97) 
    at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:422) 
    at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:390) 
    at org.springframework.integration.ip.tcp.TcpInboundGateway.doOnMessage(TcpInboundGateway.java:119) 
    at org.springframework.integration.ip.tcp.TcpInboundGateway.onMessage(TcpInboundGateway.java:97) 
    at org.springframework.integration.ip.tcp.connection.TcpNetConnection.run(TcpNetConnection.java:182) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 

実装が正しいとは思えません。

トランスをカスタマイズする方法についてお手伝いできますか? 変換メソッドでペイロードを取得して、クライアントに「リクエスト処理中のエラー」として返信できるようにする方法。 payload = '+ payload?

おかげ

UPDATE:次のようにログReplyRequiredExceptionを回避するためには、私は、TCP-インバウンド・ゲートウェイでエラーチャンネルを変更:

<int-ip:tcp-inbound-gateway id="gatewayCrLf" 
    connection-factory="crLfServer" 
    request-channel="requestChannel" 
    error-channel="tcpErrorChannel" 
    reply-timeout="10000" 
    /> 
<int:channel id="tcpErrorChannel" /> 

<int:service-activator input-channel="requestChannel" ref="gateway" requires-reply="true"/> 
<int:gateway id="gateway" default-request-channel="timeoutChannel" default-reply-timeout="10000" /> 
<int:object-to-string-transformer id="serverBytes2String" 
    input-channel="timeoutChannel" 
    output-channel="serviceChannel"/> 

<int:channel id="timeoutChannel"> 
    <int:dispatcher task-executor="timeoutExecutor"/> 
</int:channel> 

<bean id="timeoutExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="5" /> 
    <property name="maxPoolSize" value="100" /> 
    <property name="queueCapacity" value="50" /> 
</bean> 

をしかし、私はMessageDeliveryExceptionを取得しています。 tcpErrorChannelの設定が間違っているようです。あなたはお勧めできますか?ここでスタックトレースは次のとおりです。

2016-07-05 12:17:34,266 ERROR [org.springframework.integration.ip.tcp.connection.TcpNetConnection] Exception sending message: GenericMessage [payload=byte[67], headers={timestamp=1467735444239, id=30eb099e-955d-1bd3-1789-49aa9fc84b6f, ip_tcp_remotePort=64055, ip_address=127.0.0.1, ip_localInetAddress=/127.0.0.1, ip_hostname=127.0.0.1, ip_connectionId=127.0.0.1:64055:5678:908d39a1-d027-4753-b144-59b9c0390fd7}] 
org.springframework.messaging.MessagingException: failure occurred in error-handling flow; nested exception is org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.[email protected]4876db09.tcpErrorChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 
    at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:452) 
    at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:390) 
    at org.springframework.integration.ip.tcp.TcpInboundGateway.doOnMessage(TcpInboundGateway.java:119) 
    at org.springframework.integration.ip.tcp.TcpInboundGateway.onMessage(TcpInboundGateway.java:97) 
    at org.springframework.integration.ip.tcp.connection.TcpNetConnection.run(TcpNetConnection.java:182) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 
Caused by: org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.[email protected]4876db09.tcpErrorChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81) 
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:150) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:45) 
    at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:42) 
    at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97) 
    at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:449) 
    ... 7 more 
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:153) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120) 
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
    ... 14 more 

上記の例外がでtcpErrorChannelにerrorChennelを変更することで、離れて行くだろう。彼の完璧なソリューションのためにたくさんアルテムへ

感謝。

答えて

1

他の質問reply-timeout meaning in tcp-inbound-gateway in spring integrationの続きです。

まあ、ReplyRequiredException<int:service-activator input-channel="requestChannel" ref="gateway" requires-reply="true"/>の結果です。

requires-reply="true" - その説明をお読みください。あなたはそれを再生してfalse(デフォルトのもの)とすることができますが、 "タイムアウト"のロジックは機能しません。それで生き続けるない限り、あなたは選択肢を持っていない:http://docs.spring.io/spring-integration/reference/html/configuration.html#namespace-errorhandler

ERROR [org.springframework.integration.handler.LoggingHandler] org.springframework.integration.handler.ReplyRequiredException 

が、それは単にデフォルトerrorChannelのための加入者の1の影響です。

あなたの最後の質問についてです。すべての例外はErrorMessageにラップされ、そのerrorChannelに送られます。通常、例外はMessagingExceptionにラップされます。それはまさに私たちのシナリオでは、返信なしですrequestMessageであることmessage CTOR引数に

else if (this.requiresReply && !isAsync()) { 
    throw new ReplyRequiredException(message, "No reply produced by handler '" + 
      getComponentName() + "', and its 'requiresReply' property is set to true."); 
} 

ご注意:この私たちの場合、それは次のようです。そしてあなたはそれから所望の​​を抽出することができます。

だから、今、あなたのtransform()ReplyRequiredExceptionからfailedMessageを取得し、あなたの目標のためにその​​を抽出することができます。

UPDATE

このReplyRequiredExceptionは、既知の例外であるので、エラーとして、それを参照してくださいする必要はありません。

よく知られている例外ですが、それが適切でない可能性がある場合は、他のコンポーネントやシナリオで重要なものです。返信を受け取りません。 ReplyRequiredExceptionはFrameworkコンポーネントを介して非常に一般的です。したがって、別のカテゴリに移動することは、アプリケーションにとって大きなアーキテクチャーエラーになる可能性があります。

これらのログを回避するには、デフォルトのerrorChannelを使用するのではなく、TCP受信ゲートウェイの他のログを使用してください。 error-channel="tcpErrorChannel"のようなものです。それだけです。デフォルトのerrorChannelにはまだサブスクライバーとしてLoggingHandlerが含まれていますが、そのチャンネルにエラーメッセージは送信されません。

+0

私の最初の質問については、エラー例外を記録して監視します。このReplyRequiredExceptionは既知の例外であるため、Errorとして見なす必要はありません。エラー例外としてReplyRequiredExceptionを記録することを避ける方法はありますか? 私は以下が好きかもしれませんが、他のいくつかの重要な例外を逃すかもしれません。あなたは他のアイデアをお勧めしますか? \t <ロガー名= "org.springframework.integration.handler.ReplyRequiredException"> \t \t <レベル値= "致命的" /> \t \t <アペンダ-REF REF = "ファイル" /> \t – kevin

+0

してください、私の答えにUPDATEを見てください。 –

+0

Artem、私の質問の更新をご覧ください。ありがとう。 – kevin

関連する問題