Spring boot 接收消息MessageDeliveryException时:Dispatcher没有订户

Spring boot 接收消息MessageDeliveryException时:Dispatcher没有订户,spring-boot,spring-integration,spring-integration-dsl,Spring Boot,Spring Integration,Spring Integration Dsl,更新: 在将TCP()从holder类移动到endpoint类之后,它又恢复了良好的工作状态,现在我对它为什么还能工作感到困惑,因为对我来说,它为什么能工作没有任何意义 经过一些headhaches和在所有stackoverflow中搜索之后,当我收到来自服务器的消息时,我有一个调度器没有支持,但当我发送一个响应返回到一切正常时,就没有了 连接生成器: @Service @EnableIntegration public class TcpConnectionsHolder { @Autow

更新: 在将TCP()从holder类移动到endpoint类之后,它又恢复了良好的工作状态,现在我对它为什么还能工作感到困惑,因为对我来说,它为什么能工作没有任何意义

经过一些headhaches和在所有stackoverflow中搜索之后,当我收到来自服务器的消息时,我有一个调度器没有支持,但当我发送一个响应返回到一切正常时,就没有了

连接生成器:

@Service
@EnableIntegration
public class TcpConnectionsHolder {


@Autowired
private IntegrationFlowContext flowContext;


/**
 * Definition of flow channels
 * 
 * @return MessageChannel
 */
@Bean
public MessageChannel fromTcp() {
    final DirectChannel channel = new DirectChannel();
    channel.addInterceptor(new ChannelInterceptorAdapter() {
        @Override
        public Message<?> preSend(final Message<?> message, final MessageChannel channel) {
            // Parse Message byte[] to StringHex
            final byte[] bMessagePayload = (byte[]) message.getPayload();
            return MessageBuilder.withPayload(Hex.encodeHexString(bMessagePayload))
                    .copyHeaders(message.getHeaders()).build();
        }
    });
    return channel;
}

private final LinkedHashMap<String, TcpNetClientConnectionFactory> clientConnect =
        new LinkedHashMap<String, TcpNetClientConnectionFactory>();

private final LinkedHashMap<String, TcpReceivingChannelAdapter> reciverAdapter =
        new LinkedHashMap<String, TcpReceivingChannelAdapter>();

private final LinkedHashMap<String, MessageChannel> sendingAdpater =
        new LinkedHashMap<String, MessageChannel>();

public MessageChannel getMessageChannel(String host, int port) {
    return sendingAdpater.get(host+port);
}


public TcpReceivingChannelAdapter getReceiverChannel(String host, int port) {
    return reciverAdapter.get(host+port);
}

private TcpNetClientConnectionFactory getclientConnectionFactory(String host, int port,int headBytes) {

    TcpNetClientConnectionFactory cf = clientConnect.get(host+port);
    if(cf==null) {
        cf = new TcpNetClientConnectionFactory(host, port);
        final ByteArrayLengthHeaderSerializer by = new ByteArrayLengthHeaderSerializer(headBytes);
        cf.setSingleUse(false);
        cf.setSoKeepAlive(true);
        cf.setSerializer(by);
        cf.setDeserializer(by);
        clientConnect.put(host+port,cf);
    }
    return cf;
}
public TcpReceivingChannelAdapter addReceiverChannel(String host, int port) {
    return addReceiverChannel(host,port,2,2000);
}
public TcpReceivingChannelAdapter addReceiverChannel(String host, int port,int headBytes,int retryInterval) {
    TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
    TcpNetClientConnectionFactory cf = getclientConnectionFactory(host,port,headBytes);
    adapter.setConnectionFactory(cf);
    adapter.setClientMode(true);
    adapter.setErrorChannelName("errorChannel");
    adapter.setRetryInterval(retryInterval);
    adapter.setOutputChannel(fromTcp());

    IntegrationFlow flow = IntegrationFlows.from(adapter).get();

    this.flowContext.registration(flow).id(host+port + ".in").addBean(cf).register();

    this.reciverAdapter.put(host+port, adapter);

    return adapter;
}

public MessageChannel addSendingChannel(String host, int port) {
    return addSendingChannel(host,port,2);
}

public MessageChannel addSendingChannel(String host, int port,int headBytes) {
       TcpSendingMessageHandler sender = new TcpSendingMessageHandler();
       sender.setConnectionFactory(getclientConnectionFactory(host,port,headBytes));

        IntegrationFlow flow = f -> f.handle(sender);

        IntegrationFlowRegistration flowRegistration =
                this.flowContext.registration(flow).id(host+port + ".out").register();

        MessageChannel inputChannel = flowRegistration.getInputChannel();
        this.sendingAdpater.put(host+port, inputChannel);
        return inputChannel;
}

public void removeReceiverChannel(String host, int port) {
    this.reciverAdapter.remove(host+port);
    this.flowContext.remove(host+port + ".in");
}

public void removeSendingChannel(String host, int port) {
    this.sendingAdpater.remove(host+port);
    this.flowContext.remove(host+port + ".out");
}

}
我知道问题出在fromTcp()中,但在我搜索的过程中,我无法看到问题或错误所在

编辑 完整堆栈跟踪:

[INFO  ] (DefaultLifecycleProcessor.java:343) org.springframework.context.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2018/06/22 13:56:47,454 [INFO  ] (DocumentationPluginsBootstrapper.java:151) springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper : Context refreshed
2018/06/22 13:56:47,504 [INFO  ] (DocumentationPluginsBootstrapper.java:154) springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)
2018/06/22 13:56:47,555 [INFO  ] (ApiListingReferenceScanner.java:41) springfox.documentation.spring.web.scanners.ApiListingReferenceScanner : Scanning for api listing references
2018/06/22 13:56:47,826 [INFO  ] (DirectJDKLog.java:180) org.apache.coyote.http11.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-8080"]
2018/06/22 13:56:47,827 [INFO  ] (DirectJDKLog.java:180) org.apache.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"]
2018/06/22 13:56:47,829 [INFO  ] (DirectJDKLog.java:180) org.apache.tomcat.util.net.NioSelectorPool : Using a shared selector for servlet write/read
2018/06/22 13:56:47,836 [INFO  ] (TomcatEmbeddedServletContainer.java:201) org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018/06/22 13:56:47,902 [INFO  ] (AbstractConnectionFactory.java:481) org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory : started 180.112.19.1153115.inorg.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory#0, host=180.112.19.115, port=3115
2018/06/22 13:56:47,922 [INFO  ] (AbstractEndpoint.java:120) org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter : started org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter#0
2018/06/22 13:56:47,949 [INFO  ] (EventDrivenConsumer.java:108) org.springframework.integration.endpoint.EventDrivenConsumer : Adding {ip:tcp-outbound-channel-adapter} as a subscriber to the '180.112.19.1153115.out.input' channel
2018/06/22 13:56:47,950 [INFO  ] (AbstractSubscribableChannel.java:81) org.springframework.integration.channel.DirectChannel : Channel 'ck-da-bridge:local:8080.180.112.19.1153115.out.input' has 1 subscriber(s).
2018/06/22 13:56:47,950 [INFO  ] (AbstractConnectionFactory.java:481) org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory : started 180.112.19.1153115.inorg.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory#0, host=180.112.19.115, port=3115
2018/06/22 13:56:47,950 [INFO  ] (AbstractEndpoint.java:120) org.springframework.integration.endpoint.EventDrivenConsumer : started org.springframework.integration.config.ConsumerEndpointFactoryBean#1
2018/06/22 13:56:47,953 [INFO  ] (StartupInfoLogger.java:57) com.santander.ck.bridge.spring.Application : Started Application in 13.078 seconds (JVM running for 14.159)
2018/06/22 13:57:01,164 [ERROR ] (LoggingHandler.java:192) org.springframework.integration.handler.LoggingHandler : org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'ck-da-bridge:local:8080.180.112.19.1153115.in.channel#0'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=f0f8f0f0c2200000800000020400000000000000f0f5f9f9f1f0f3f0f6f2f2f1f3f5f6f5f5f0f0f0f0f1f2f0f6f0f2f2f0f2f0f0f0f9d4c3c3f0f1f1f1e3f0f0f8f2, headers={ip_tcp_remotePort=3115, ip_connectionId=amm012059amm.scisb.isban.corp:3115:53402:3722e84f-49ce-4e77-a4a1-6e82cefe58b4, ip_localInetAddress=/180.101.130.119, ip_address=180.112.19.115, id=2c6e2e09-9faa-a56e-3921-edf7a03a9a3c, ip_hostname=amm012059amm.scisb.isban.corp, timestamp=1529668621142}], failedMessage=GenericMessage [payload=f0f000022f0f6e3f0f0f8f2, headers={ip_tcp_remotePort=3115, ip_connectionId=amm012059amm.scisb.isban.corp:3115:53402:3722e84f-49ce-4e77-a4a1-6e82cefe58b4, ip_localInetAddress=/180.101.130.119, ip_address=180.112.19.115, id=2c6e2e09-9faa-a56e-3921-edf7a03a9a3c, ip_hostname=amm012059amm.scisb.isban.corp, timestamp=1529668621142}]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:93)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
        at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
        at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
        at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:188)
    at org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter.onMessage(TcpReceivingChannelAdapter.java:88)
    at org.springframework.integration.ip.tcp.connection.TcpNetConnection.run(TcpNetConnection.java:182)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=f0f8f0f0c2200000800000020400000000000000f0f5f9f9f1f0f3f0f6f2f2f1f3f5f6f5f5f0f0f0f0f1f2f0f6f0f2f2f0f2f0f0f0f9d4c3c3f0f1f1f1e3f0f0f8f2, headers={ip_tcp_remotePort=3115, ip_connectionId=amm012059amm.scisb.isban.corp:3115:53402:3722e84f-49ce-4e77-a4a1-6e82cefe58b4, ip_localInetAddress=/180.101.130.119, ip_address=180.112.19.115, id=2c6e2e09-9faa-a56e-3921-edf7a03a9a3c, ip_hostname=amm012059amm.scisb.isban.corp, timestamp=1529668621142}]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:154)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
    ... 11 more

您可以为
org.springframework.integration
类别打开调试日志记录级别,并跟踪消息的传播方式

此外,还有一种模式可供您跟踪标头中的消息路径。通过这种方式,您将能够看到您的消息通过了哪些频道,以及它在哪里停留在
Dispatcher has no subscribers

尽管在每次
IntegrationFlow
注册后需要重新启动
MessageHistoryConfigurer

您可以随意提出JIRA,让消息历史记录跟踪动态流

更新

嗯。让您的简单代码如下所示:

TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
TcpNetClientConnectionFactory cf = getclientConnectionFactory(host,port,headBytes);
adapter.setConnectionFactory(cf);
adapter.setClientMode(true);
adapter.setErrorChannelName("errorChannel");
adapter.setRetryInterval(retryInterval);
adapter.setOutputChannel(fromTcp());

IntegrationFlow flow = IntegrationFlows.from(adapter).get();
IntegrationFlow flow = IntegrationFlows.from(adapter).channel(fromTcp()).get();
事实上,在这个
处理程序之后没有更多的组件了(adn堆栈跟踪确实证实了这一点),我假设您使用了一些Spring Integration Java DSL版本,但没有正确的修复程序,从提供的
MessageProducer.getOutputChannel()
中提取
输出通道

为了解决这个问题,我建议您修改如下代码:

TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
TcpNetClientConnectionFactory cf = getclientConnectionFactory(host,port,headBytes);
adapter.setConnectionFactory(cf);
adapter.setClientMode(true);
adapter.setErrorChannelName("errorChannel");
adapter.setRetryInterval(retryInterval);
adapter.setOutputChannel(fromTcp());

IntegrationFlow flow = IntegrationFlows.from(adapter).get();
IntegrationFlow flow = IntegrationFlows.from(adapter).channel(fromTcp()).get();
我的意思是将通道引用从
tcprevivingchanneladapter
定义移动到流。或者尝试升级到最新的
1.2.3
版本,以获得
spring集成java dsl
依赖项

更新2

关于代码的另一个想法,我们到目前为止


您可以从
CommandLineRunner
注册一个
TCPrevivingChannelAdapter
。通过这种方式,
IntegrationFlow
将自动启动,并准备通过TCP接收数据,但与此同时,
@ServiceActivator(inputChannel=“fromTcp”)
尚未启动,无法使用来自所述通道的消息。这就是为什么
调度程序没有订户的原因。或者,您应该使用
autoStartup(false)
损坏您的
this.flowContext.registration(flow)
,并让它在正常的自动启动阶段最近启动,并与service activator一起启动。或者,对于这种逻辑,您不应该使用
CommandLineRunner
方法:现在开始一些活动实在太早了。

请提供更多堆栈跟踪?有没有可能在GitHub上共享一个简单的项目,让我们一起玩?@Artem Bilan,Aded complete stacktrace。我不能把一个github项目放进去,我不能完全控制一切你能确定什么是
ck da bridge
?您能为
org.springframework.integration
类别打开调试日志记录级别并跟踪消息的传播方式吗?好的。我想说的是,你没有显示所有关于这个问题的代码。根据频道按摩名称
ck da bridge:local:8080.180.112.19.1153115.in.channel#0
您的
in
流中还有其他内容。因为它确实表明问题出在
tcprecingChannelAdapter.onMessage()
上,但您的流只是显示这样一个
tcprecingChannelAdapter
只发送到
fromTcp()
。您使用的是哪种Spring集成版本?粘贴调试的bin,希望它能帮助您将项目上传到公共github,这是没有激活TcpSendingMessageHandler流的输出,您没有显示我请求的调试,并且日志中还没有消息历史记录。不过,这里有一些新的
CANAL
注意事项-也许这会对您有所帮助。我很抱歉,但是如果没有最小的项目,我们无法帮助您:您肯定不会显示代码中的其他内容…CANAL是入站Conctor名称的更改。我从TCP()从TcpConnectionsHolder移动到BridgeMessageEndpoint。现在它又完美地工作了,它不会发送消息,因为Dispatcher没有订户,这是否意味着它现在可以被同一类中的服务激活器看到?还是因为“fromTcp()”现在在endpoint类中?或者我应该更好地编辑问题?请在我的答案中查找更新。