Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 春季云流-如何处理下游区块?_Java_Spring Integration_Spring Kafka_Spring Cloud Stream - Fatal编程技术网

Java 春季云流-如何处理下游区块?

Java 春季云流-如何处理下游区块?,java,spring-integration,spring-kafka,spring-cloud-stream,Java,Spring Integration,Spring Kafka,Spring Cloud Stream,在Kafka集群的计划停机期间,我们基本上遇到了以下问题(显然是Kafka而不是RabbitMQ) 来自@GaryRussell的答案是: 通道sendTimeout仅在通道本身可以阻塞时适用,例如,具有当前已满的有界队列的QueueChannel;调用者将阻塞,直到队列中的空间变为可用,或者发生超时 在这种情况下,块位于通道的下游,因此sendTimeout是不相关的(在任何情况下,它是一个DirectChannel,无论如何都不能阻止,订阅的处理程序直接在调用线程上调用) 您看到的实际阻塞最

在Kafka集群的计划停机期间,我们基本上遇到了以下问题(显然是Kafka而不是RabbitMQ)

来自@GaryRussell的答案是:

通道
sendTimeout
仅在通道本身可以阻塞时适用,例如,具有当前已满的有界队列的
QueueChannel
;调用者将阻塞,直到队列中的空间变为可用,或者发生超时

在这种情况下,块位于通道的下游,因此sendTimeout是不相关的(在任何情况下,它是一个DirectChannel,无论如何都不能阻止,订阅的处理程序直接在调用线程上调用)

您看到的实际阻塞最有可能出现在rabbitmq客户机中的
socket.write()
,它没有超时,也不可中断;调用线程无法“超时”写入

我知道的唯一可能的解决方案是通过调用连接工厂上的
resetConnection()
来强制关闭兔子连接

很好地解释了为什么有问题的方法(
org.springframework.integration.channel.AbstractSubscribableChannel#doSend
)不考虑
超时。然而,这对我来说还是有点奇怪

spring-integration-kafka-3.2.1.RELEASE-sources.jar中/org/springframework/integration/kafka/outbound/KafkaProducerMessageHandler.java:566
,我们可以看到,如果需要
同步
行为:

565if(this.sync){
566 Long sendTimeout=this.sendTimeoutExpression.getValue(this.evaluationContext,message,Long.class);
567如果(sendTimeout==null | | sendTimeout<0){
568.get()的未来;
569        }
570其他{
571试试看{
572.get(发送超时,时间单位为毫秒);
573            }
574捕获(超时异常te){
575抛出新消息TimeoutException(消息,“等待KafkaProducer响应的超时”,te);
576            }
577        }
578    }
调用,其中考虑了超时。
sendTimeoutExpression
被指定为默认值:

    private static final long DEFAULT_SEND_TIMEOUT = 10000;
    private Expression sendTimeoutExpression = new ValueExpression<>(DEFAULT_SEND_TIMEOUT);

private static final long DEFAULT\u SEND\u TIMEOUT=10000;
私有表达式sendTimeoutExpression=新值表达式(默认值为发送超时);
但是,我们的堆栈跟踪揭示了一些不同的情况:

"pool-1-thread-3" - Thread t@108
   java.lang.Thread.State: TIMED_WAITING
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <4ebda621> (a org.springframework.util.concurrent.SettableListenableFuture$SettableTask)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:426)
    at java.util.concurrent.FutureTask.get(FutureTask.java:204)
    at org.springframework.util.concurrent.SettableListenableFuture.get(SettableListenableFuture.java:134)
*   at org.springframework.integration.kafka.outbound.KafkaProducerMessageHandler.processSendResult(KafkaProducerMessageHandler.java:572)
    at org.springframework.integration.kafka.outbound.KafkaProducerMessageHandler.handleRequestMessage(KafkaProducerMessageHandler.java:414)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:69)
    at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder$SendingHandler.handleMessageInternal(AbstractMessageChannelBinder.java:1035)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:69)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:570)
“池-1-线程-3”-线程t@108
java.lang.Thread.State:定时等待
在sun.misc.Unsafe.park(本机方法)
-停车等待(org.springframework.util.concurrent.SettableListenableFuture$SettableTask)
位于java.util.concurrent.locks.LockSupport.parknos(LockSupport.java:215)
在java.util.concurrent.FutureTask.waitDone(FutureTask.java:426)
位于java.util.concurrent.FutureTask.get(FutureTask.java:204)
位于org.springframework.util.concurrent.SettableListenableFuture.get(SettableListenableFuture.java:134)
*位于org.springframework.integration.kafka.outbound.KafkaProducerMessageHandler.processSendResult(KafkaProducerMessageHandler.java:572)
位于org.springframework.integration.kafka.outbound.KafkaProducerMessageHandler.handleRequestMessage(KafkaProducerMessageHandler.java:414)
位于org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
位于org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:69)
位于org.springframework.cloud.stream.binder.AbstractMessageChannelBinder$SendingHandler.handleMessageInternal(AbstractMessageChannelBinder.java:1035)
位于org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:69)
位于org.springframework.integration.dispatcher.AbstractDispatcher.tryoOptimizedDispatch(AbstractDispatcher.java:115)
位于org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
位于org.springframework.integration.dispatcher.UnicastingDispatcher.dispatcher(UnicastingDispatcher.java:106)
位于org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72)
位于org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:570)
*
标记的调用对应于
future.get(sendTimeout,TimeUnit.ms)呼叫

看看底层客户机似乎如何支持它(由
future.get()
调用支持超时这一事实给出),这将如何设置?在活页夹引用(请参阅)中,我能找到的仅有两个属性是
spring.cloud.stream.kafka.binder.healthTimeout
batchTimeout
,据我所知,它们不会影响此设置


查看如何在私有类
org.springframework.cloud.stream.binder.kafka.KafkaMessageChannelBinder.ProducerConfigurationMessageHandler
中构造
KafkaProducerMessageHandler
,bean重写似乎不是推荐的方法。

它似乎没有文档化,但与侦听器容器自定义程序类似,您可以添加一个
ProducerMessageHandlerCustomizer
@Bean
来设置消息处理程序上的任意属性


在较新版本的处理程序中,超时总是配置为至少与
ProducerConfig.DELIVERY\u timeout\u MS\u CONFIG
相同,以避免误报(处理程序超时后发布成功).

谢谢您提供的信息-如果可以的话,我会在接下来的几天内为文档做公关。关于
delivery.timeout.ms
设置的提示也非常有用。因为在中,这被设置为
120000
(120s)