Java REST 的正确 heartbeat/keep-alive technology/layer 是什么?网址? TCP?编码:分块?
What's the proper heartbeat/keep-alive technology/layer for Java REST? Http? Tcp? Encoding: chunked?
设置:
我们有一个 https://Main.externaldomain/xmlservlet site, which is authenticating/validating/geo-locating and proxy-ing (slightly modified) requests to http://London04.internaldomain/xmlservlet 例如。
根本无法直接访问向最终用户公开的内部域。站点之间的通信偶尔会中断,有时内部域节点会变为 unavailable/dead.
主站点正在使用 org.apache.http.impl.client.DefaultHttpClient(我知道它已被弃用,我们正在逐步升级此遗留代码)并将 readTimeout 设置为 10.000 毫秒。
请求和响应具有可变长度的 xml payload/body 并且使用了 Transfer-Encoding: chunked
,还使用了 Keep-Alive: timeout=15
。
问题:
有时 London04 实际上需要超过 10 秒(比方说 2 分钟)才能执行。有时它会非优雅地崩溃。有时会发生其他(网络)问题。
有时在那 2 分钟内——response-xml-data 的部分被逐渐填充,以至于这些部分之间没有 10 秒的间隔,因此永远不会超过 readTimeout,
有时会有 10 多秒的间隔并且 HttpClient 超时...
我们可以尝试增加 Main 端的超时,但这很容易 bloat/overload 侦听器池(仅通过常规流量,甚至还没有被 DDOS)。
我们需要一种方法来区分内部站点仍在生成响应和真正发生响应的情况 crashed/network_lost/etc。
最好的感觉是在交流过程中有某种心跳(每 5 秒一次)。
我们认为 Keep-Alive 可以拯救我们,但它似乎只能确保 请求之间的间隙(而不是在 期间请求)并且它似乎在间隙期间没有做任何心跳(只是 having/waiting_for 超时)。
我们认为分块编码可以通过发送一些心跳(0 字节大小的块)让另一方知道来拯救我们,但似乎没有 such/default 以这种方式支持任何心跳的实现而且似乎 0 字节大小的块本身就是一个 EOD 指标...
问题:
如果我们假设 KeepAlive/ChunkedEncoding 不会帮助我们实现 keptAlive/hearbeat/fastDetectionOfDeadBackend,那么:
1) 这种心跳应该在哪一层实现?网址? TCP?
2) 任何标准 framework/library/setting/etc 已经实施了吗? (如果可能:Java,REST)
更新
我还研究了 WADL/WSDL 的心跳实现器,虽然发现 none 用于 REST,但检查了 WebSockets...
还研究了 TCP-keepalives,这似乎是该任务的正确特征:
- https://en.wikipedia.org/wiki/Keepalive
- http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
- WebSockets ping/pong, why not TCP keepalive?
但是根据那些我必须设置类似的东西:
- tcp_keepalive_time=5
- tcp_keepalive_intvl=1
- tcp_keepalive_probes=3
这似乎是一个反建议(建议使用 2 小时,10 分钟已经显示为奇数,将变为 5 秒 sane/safe??如果是 - 可能是我的预先解决方案...... )
还有我应该在哪里配置这个?单独在 London04 上还是在 Main 上? (如果我在 Main 上设置它 - 它不会淹没客户端 - > Main 前端通信吗?或者站点之间的 NATs/etc 可能会轻易破坏 keepalive intent/support?)
P.S。欢迎任何 link 到 RTFM - 我可能只是遗漏了一些明显的东西:)
我的建议是不要使用检测信号。让您的 external-facing API return 带有 headers 的 303 See Other
指示何时何地可能提供所需的响应。
所以你可以打电话给:
POST https://public.api/my/call
然后回来
303 See Other
Location: "https://public.api/my/call/results"
Retry-After: 10
就您的服务器可以猜测构建响应需要多长时间而言,它应该将其计入 Retry-After
值。如果稍后对新位置进行 GET
调用并且结果尚未构建完成,则 return 具有更新的 Retry-After
值的响应。所以也许你尝试 10
,如果这不起作用,你告诉客户再等 110
,总共需要两分钟。
或者,使用旨在长时间保持开放的协议,例如 WebSockets。
看看SSE
示例代码:
https://github.com/rsvoboda/resteasy-sse
或顶点事件总线:
https://vertx.io/docs/apidocs/io/vertx/core/eventbus/EventBus.html
设置:
我们有一个 https://Main.externaldomain/xmlservlet site, which is authenticating/validating/geo-locating and proxy-ing (slightly modified) requests to http://London04.internaldomain/xmlservlet 例如。
根本无法直接访问向最终用户公开的内部域。站点之间的通信偶尔会中断,有时内部域节点会变为 unavailable/dead.
主站点正在使用 org.apache.http.impl.client.DefaultHttpClient(我知道它已被弃用,我们正在逐步升级此遗留代码)并将 readTimeout 设置为 10.000 毫秒。
请求和响应具有可变长度的 xml payload/body 并且使用了 Transfer-Encoding: chunked
,还使用了 Keep-Alive: timeout=15
。
问题:
有时 London04 实际上需要超过 10 秒(比方说 2 分钟)才能执行。有时它会非优雅地崩溃。有时会发生其他(网络)问题。 有时在那 2 分钟内——response-xml-data 的部分被逐渐填充,以至于这些部分之间没有 10 秒的间隔,因此永远不会超过 readTimeout, 有时会有 10 多秒的间隔并且 HttpClient 超时...
我们可以尝试增加 Main 端的超时,但这很容易 bloat/overload 侦听器池(仅通过常规流量,甚至还没有被 DDOS)。 我们需要一种方法来区分内部站点仍在生成响应和真正发生响应的情况 crashed/network_lost/etc。 最好的感觉是在交流过程中有某种心跳(每 5 秒一次)。
我们认为 Keep-Alive 可以拯救我们,但它似乎只能确保 请求之间的间隙(而不是在 期间请求)并且它似乎在间隙期间没有做任何心跳(只是 having/waiting_for 超时)。
我们认为分块编码可以通过发送一些心跳(0 字节大小的块)让另一方知道来拯救我们,但似乎没有 such/default 以这种方式支持任何心跳的实现而且似乎 0 字节大小的块本身就是一个 EOD 指标...
问题:
如果我们假设 KeepAlive/ChunkedEncoding 不会帮助我们实现 keptAlive/hearbeat/fastDetectionOfDeadBackend,那么:
1) 这种心跳应该在哪一层实现?网址? TCP?
2) 任何标准 framework/library/setting/etc 已经实施了吗? (如果可能:Java,REST)
更新
我还研究了 WADL/WSDL 的心跳实现器,虽然发现 none 用于 REST,但检查了 WebSockets... 还研究了 TCP-keepalives,这似乎是该任务的正确特征:
- https://en.wikipedia.org/wiki/Keepalive
- http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
- WebSockets ping/pong, why not TCP keepalive?
但是根据那些我必须设置类似的东西:
- tcp_keepalive_time=5
- tcp_keepalive_intvl=1
- tcp_keepalive_probes=3
这似乎是一个反建议(建议使用 2 小时,10 分钟已经显示为奇数,将变为 5 秒 sane/safe??如果是 - 可能是我的预先解决方案...... )
还有我应该在哪里配置这个?单独在 London04 上还是在 Main 上? (如果我在 Main 上设置它 - 它不会淹没客户端 - > Main 前端通信吗?或者站点之间的 NATs/etc 可能会轻易破坏 keepalive intent/support?)
P.S。欢迎任何 link 到 RTFM - 我可能只是遗漏了一些明显的东西:)
我的建议是不要使用检测信号。让您的 external-facing API return 带有 headers 的 303 See Other
指示何时何地可能提供所需的响应。
所以你可以打电话给:
POST https://public.api/my/call
然后回来
303 See Other
Location: "https://public.api/my/call/results"
Retry-After: 10
就您的服务器可以猜测构建响应需要多长时间而言,它应该将其计入 Retry-After
值。如果稍后对新位置进行 GET
调用并且结果尚未构建完成,则 return 具有更新的 Retry-After
值的响应。所以也许你尝试 10
,如果这不起作用,你告诉客户再等 110
,总共需要两分钟。
或者,使用旨在长时间保持开放的协议,例如 WebSockets。
看看SSE
示例代码: https://github.com/rsvoboda/resteasy-sse
或顶点事件总线: https://vertx.io/docs/apidocs/io/vertx/core/eventbus/EventBus.html