【问题标题】:StompBrokerRelayMessageHandler - Transport failure: java.lang.IllegalStateException: No TcpConnection availableStompBrokerRelayMessageHandler - 传输失败:java.lang.IllegalStateException:没有可用的 TcpConnection
【发布时间】:2020-01-19 09:59:39
【问题描述】:

我们在我们的项目中使用 STOMP 代理中继(外部代理 - ActiveMQ 5.13.2),请参阅 https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-handle-broker-relay

我们使用以下堆栈:

org.springframework:spring-jms:jar:5.1.8.RELEASE
org.springframework:spring-messaging:jar:5.1.8.RELEASE
io.projectreactor:reactor-core:jar:3.2.8.RELEASE
io.projectreactor.netty:reactor-netty:jar:0.8.6.RELEASE
io.netty:netty-all:jar:4.1.34.Final

有时(假设每 2 周一次)我们可以在 tomcat catalina.out 日志中观察到错误

2019-08-21 13:38:58,891 [tcp-client-scheduler-5] ERROR com.*.websocket.stomp.SimpMessagingSender  - BrokerAvailabilityEvent[available=false, StompBrokerRelay[ReactorNettyTcpClient[reactor.netty.tcp.TcpClientDoOn@219abb46]]]
2019-08-21 13:38:58,965 [tcp-client-scheduler-1] ERROR org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler  - Transport failure: java.lang.IllegalStateException: No TcpConnection available

该错误之后 STOMP 通信中断(system 连接 - 单个 TCP 连接不可用)

似乎一切都是在我们从以下位置更新堆栈时开始的:

org.springframework:spring-jms:jar:5.0.8.RELEASE
org.springframework:spring-messaging:jar:5.0.8.RELEASE
io.projectreactor:reactor-core:jar:3.1.8.RELEASE
io.projectreactor.netty:reactor-netty:jar:0.7.8.RELEASE
io.netty:netty-all:jar:4.1.25.Final

ActiveMQ 版本未更改

spring 报告了一个错误,当system 连接丢失时自动重新连接失败请参阅: https://github.com/spring-projects/spring-framework/issues/22080

现在有 3 个问题:

  1. 如何让这个问题重现性更好?
  2. 如何解决此重新连接行为? :)
  3. 如何防止丢失此连接? :)

编辑 23.09.2019

发生错误后,端口 61613(STOMP) 的 TCP 堆栈如下(请注意 CLOSE_WAIT 状态):

netstat -an | grep 61613
tcp6       0      0 :::61613                :::*                    LISTEN
tcp6       2      0 127.0.0.1:49084         127.0.0.1:61613         CLOSE_WAIT

【问题讨论】:

  • 虽然此处涉及 ActiveMQ,但它似乎不是问题的根源(特别是考虑到版本没有更改的事实)所以我删除了 activemq 标签。
  • 只是一个想法,但是在主路由器离线并重新启动后会发生这种情况吗?我有一些软件似乎需要在网络出现故障或恢复时重新启动服务。

标签: java websocket stomp spring-messaging


【解决方案1】:

我不能说我有足够的信息来回答你的问题,尽管我有一些意见可以帮助你找到前进的方向。

ActiveMQ 通常用于托管/分布式环境中,因此应始终考虑负载和扩展。

大多数 dbs/message queues/ect.. 都需要对负载进行某种调整 - 即使在 AWS 上(通过请求更高的限制),尽管其中大部分都由托管服务提供商负责。

但我离题了...

在这种情况下,您的队列似乎正在使用 TCP 传输:

https://activemq.apache.org/tcp-transport-reference

如您所见,所有这些设置都可以调整并具有默认值。

因此,对于从 spring 端 连接到 AMQ 记录的问题,您需要缩短错误发生的时间,然后查看您的 AMQ 指标和日志。

如果你没有对 AMQ 的监控,我建议:

  1. 添加监控 - https://activemq.apache.org/how-can-i-monitor-activemq
  2. 添加日志记录(或找出日志的位置)。 - 然后启用详细日志记录。 (AMQ 使用 log4j,所以只需查看 log4j 配置文件或添加一个。)除此之外,考虑将日志发送到日志聚合器。 --https://activemq.apache.org/how-can-i-enable-detailed-logging
  3. 查看您的托管服务提供商的指标和停机时间。例如,如果使用 AWS,则会有关于网络故障或 VPC 或跨区域隧道、网络流量输入/输出等瞬时问题的非常详细的事件日志。

为您的分布式系统设置正确的工具以使您的团队能够搜索/查找错误/日志(并记录如何执行此操作)非常有帮助。超越这一点(对于成熟的系统)是在您的监控之上添加一个层,以便您的系统在出现问题时开始告诉您,而不是相反(去寻找问题)。

这可能有点冗长 - 但这一切都会让我询问您在失败时是否有 AMQ 系统的日志/指标。如果你这样做,请发布它们!

我提出这些建议是因为:

  • 没有提供关于您的负载预期、负载可变性或负载是系统考虑因素的信息(通过故障排除步骤)。
  • 提供的日志/错误完全来自客户端。
  • 错误的重现性很少且不一致 - 所以它几乎可以是任何事情(内存泄漏、负载问题等) - 因此需要进行监控。

还可以考虑添加 Spring Actuator 以在 Spring 端监控您的消息客户端,因为客户端连接池和高级设置也经常存在限制/设置,尤其是在您扩大/缩小实例大小等时。以及您的实例将处理更多/更少的负载,您的客户端库可能需要一些设置调整。

https://www.baeldung.com/spring-boot-actuators

Exposing metrics about current Websocket connections with Spring

您还可以捕获异常并拆除并重新创建您的连接/设置 - 尽管如果不了解更多有关连接失败时的情况和统计​​信息,这不是我建议的第一件事。

【讨论】:

  • 尽管这个答案并不能解决问题,但您会获得积分,以表彰您的尝试。
猜你喜欢
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多