0

我们已经建立了一个修复客户端。修复客户端可以接收传入消息,但在发送最后一个心跳后无法发送传出心跳消息或回复 TestRequest 消息,触发某些东西以停止从客户端发送心跳。

修复版本:fix5.0

之前也发生过同样的事件,我们当时有一个会话的 tcpdump [1]:https://i.stack.imgur.com/oKx49.png

我们将每个修复会话部署到单独的 k8s pod。

  1. 我们怀疑这是 CPU 资源问题,因为在发布时间前后平均负载很高,但是在我们添加更多 cpu 内核后仍未解决。我们认为由于修复重新连接,平均负载很高。
  2. 我们怀疑这是 IO 问题,因为我们使用由 3 个会话共享的 AWS efs 进行日志记录和消息存储。但是在我们使用 pod affinity 将 3 个 session 分配给不同的节点后仍然没有解决。
  3. 这也不是网络问题,因为我们可以收到修复消息,当时其他会话运行良好。我们也在 k8s 集群中禁用了SNAT 。

我们正在使用 quickfixj 2.2.0 创建一个修复客户端,我们有 3 个会话,它们部署到不同节点中的 k8s pod。

  1. 评价会话以从服务器获取外汇价格
  2. 命令会话从服务器获取事务(执行报告)消息,我们只向服务器发送登录/心跳/注销消息。
  3. 后台会话以获取市场状态

我们使用 apache camel quickfixj 组件来简化我们的编程。它在大多数情况下运行良好,但在 3 个会话中不断发生重新连接以修复服务器,频率就像一个月一次,大多数只有 2 个会话有问题。

heartbeatInt = 30s

客户端的修复事件消息

20201004-21:10:53.203 Already disconnected: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=1)
20201004-21:10:53.271 MINA session created: local=/172.28.65.164:44974, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/10.60.45.132:11050
20201004-21:10:53.537 Initiated logon request
20201004-21:10:53.643 Setting DefaultApplVerID (1137=9) from Logon
20201004-21:10:53.643 Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
20201004-21:10:53.643 Received logon

在客户端修复传入消息

8=FIXT.1.1☺9=65☺35=0☺34=2513☺49=Quote1☺52=20201004-21:09:02.887☺56=TA_Quote1☺10=186☺
8=FIXT.1.1☺9=65☺35=0☺34=2514☺49=Quote1☺52=20201004-21:09:33.089☺56=TA_Quote1☺10=185☺
8=FIXT.1.1☺9=74☺35=1☺34=2515☺49=Quote1☺52=20201004-21:09:48.090☺56=TA_Quote1☺112=TEST☺10=203☺ 
----- 21:10:53.203 Already disconnected ----
8=FIXT.1.1☺9=87☺35=A☺34=1☺49=Quote1☺52=20201004-21:10:53.639☺56=TA_Quote1☺98=0☺108=30☺141=Y☺1137=9☺10=183☺
8=FIXT.1.1☺9=62☺35=0☺34=2☺49=Quote1☺52=20201004-21:11:23.887☺56=TA_Quote1☺10=026☺

在客户端修复传出消息

8=FIXT.1.1☺9=65☺35=0☺34=2513☺49=TA_Quote1☺52=20201004-21:09:02.884☺56=Quote1☺10=183☺
---- no heartbeat message around 21:09:32 ----
---- 21:10:53.203 Already disconnected ---
8=FIXT.1.1☺9=134☺35=A☺34=1☺49=TA_Quote1☺52=20201004-21:10:53.433☺56=Quote1☺98=0☺108=30☺141=Y☺553=xxxx☺554=xxxxx☺1137=9☺10=098☺
8=FIXT.1.1☺9=62☺35=0☺34=2☺49=TA_Quote1☺52=20201004-21:11:23.884☺56=Quote1☺10=023☺
8=FIXT.1.1☺9=62☺35=0☺34=3☺49=TA_Quote1☺52=20201004-21:11:53.884☺56=Quote1☺10=027☺

收到来自服务器的 TEST 消息时的线程转储。顺便说一句,要点来自我们具有相同部署的开发环境。 https://gist.github.com/hitxiang/345c8f699b4ad1271749e00b7517bef6

我们在 quickfixj 启用了调试日志,但信息不多,只有收到消息的日志。

4

1 回答 1

2

时间序列中的序列

  1. 20201101-23:56:02.742此时应该发送outgoing heartbeat,看起来是在发送,但是挂在io写-处于运行状态
  2. 20201101-23:56:18.651 来自服务器端的测试消息以触发线程转储
  3. 20201101-22:57:45.654 服务器端开始关闭连接
  4. 20201101-22:57:46.727 线程转储 - 对
  5. 20201101-23:57:48.363 登录信息
  6. 20201101-22:58:56.515 线程转储 - 左

右边(2020-11-01T22:57:46.727Z):挂机时,左边(2020-11-01T22:58:56.515Z):重连后 在此处输入图像描述

看起来我们正在使用的存储 - aws efs 使问题发生了。但是来自 aws 支持的反馈是 aws efs 方面没有任何问题。可能是 k8s ec2 实例和 aws efs 之间的网络问题。

  1. 首先,我们在所有会话中使日志记录异步,减少断开连接的发生。
  2. 其次,对于市场时段,我们将序列文件写入本地磁盘,在市场时段断开连接。
  3. 第三,最后我们将所有会话的 aws efs 替换为 aws ebs(persist volume in k8s)。现在效果很好。

顺便说一句,aws ebs 不是跨区域的高可用性,但它比修复断开连接要好。

于 2020-12-18T03:28:17.703 回答