【发布时间】:2019-07-19 05:40:16
【问题描述】:
设置:
我们有一个https://Main.externaldomain/xmlservlet 站点,例如,它正在对http://London04.internaldomain/xmlservlet 进行身份验证/验证/地理定位和代理(稍作修改)请求。
根本无法直接访问向最终用户公开的内部域。站点之间的通信偶尔会中断,有时内部域节点会变得不可用/死机。
主站点使用 org.apache.http.impl.client.DefaultHttpClient(我知道它已被弃用,我们正在逐步升级此遗留代码),并将 readTimeout 设置为 10.000 毫秒。
请求和响应具有可变长度的xml有效负载/正文,使用Transfer-Encoding: chunked,也使用Keep-Alive: timeout=15。
问题:
有时 London04 实际上需要超过 10 秒(比如说 2 分钟)来执行。有时它会不优雅地崩溃。有时会发生其他(网络)问题。 有时在这 2 分钟内 - response-xml-data 的部分被逐渐填充,部分之间没有 10 秒的间隙,因此永远不会超过 readTimeout, 有时会有 10 多秒的间隔,并且 HttpClient 超时...
我们可以尝试增加 Main 端的超时,但这很容易使侦听器池膨胀/过载(仅通过常规流量,甚至还没有被 DDOS 攻击)。 我们需要一种方法来区分 internal-site-still-working-on-generating-the-response 和它真正崩溃/network_lost/等的情况。 最好的感觉是交流期间的某种心跳(每 5 秒)。
我们认为 Keep-Alive 会拯救我们,但它似乎只能保护请求之间的间隙(而不是在请求期间)而且它似乎没有间隙期间的任何心跳(只是有/waiting_for 超时)。
我们认为分块编码可以通过发送一些心跳(0-bytes-sized-chunks)让对方知道来拯救我们,但似乎没有这样/默认的实现以这种方式支持任何心跳,而且看起来那个 0 字节大小的块本身就是一个 EOD 指标...
问题:
如果我们正确假设 KeepAlive/ChunkedEncoding 不会帮助我们实现 keepAlive/heartbeat/fastDetectionOfDeadBackend,那么:
1) 应该在哪一层实现这样的心跳?网址? tcp?
2) 任何标准框架/库/设置/等已经实现了吗? (如果可能:Java、REST)
更新
我还研究了 WADL/WSDL 的心跳实现器,虽然没有找到 REST,但检查了 WebSockets... 还研究了 TCP-keepalives,这似乎是该任务的正确功能:
- https://en.wikipedia.org/wiki/Keepalive
- http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
- Socket heartbeat vs keepalive
- WebSockets ping/pong, why not TCP keepalive?
但是根据那些我必须设置类似的东西:
- tcp_keepalive_time=5
- tcp_keepalive_intvl=1
- tcp_keepalive_probes=3
这似乎是一个反建议(建议 2 小时,10 分钟已经显示为奇数,5 秒是正常/安全的吗??如果是 - 可能是我的预先解决方案......)
我应该在哪里配置这个?单独在 London04 上还是在 Main 上? (如果我在 Main 上设置它 - 它不会淹没客户端 - >主要前端通信吗?或者站点之间的 NATs/etc 是否会轻易破坏 keepalive 意图/支持?)
附:欢迎任何指向 RTFM 的链接 - 我可能只是遗漏了一些明显的东西 :)
【问题讨论】:
标签: java rest keep-alive heartbeat tcp-keepalive