通过 UDP 暴露应用程序是否正在进行 GC
Exposing whether an application is undergoing GC via UDP
这个问题背后的动机是看看我们是否可以通过首先应用其指定特定节点的常规策略来将 HTTP 请求路由到(例如,通过回合robin策略)然后"peeking"进入系统内部状态,看是否正在进行垃圾回收。如果是这样,负载均衡器将完全避开该节点并移动到下一个节点。
在理想情况下,每个节点都会 "emit" 每隔几秒通过 UDP 将其内部状态发送到某个消息队列,让负载均衡器知道哪些节点可能 "radio-active" 如果它们正在通过GC(我将其可视化为一个简单的布尔值)。
这里的问题是:我可以调整我的应用程序以利用其 JVM 的内部状态,并且 (a) 弄清楚我们是否立即处于 GC 模式 (b) 通过某种协议发出此结果 (UDP/HTTP) 通过网络连接到其他实体(如 MQ 或其他实体)。
有很多方法可以远程监控和报告虚拟机。例如,众所周知的协议是 SNMP。但这是一个非常复杂的课题。
实施在某种程度上取决于您的要求。如果您确实需要确保 VM 处于良好状态,则可能需要将您的应用程序包装在控制实际 VM 的包装器 VM 中。这是相当复杂的。
许多实现使用内置的监视和分析接口,这些接口作为 bean 通过 JMX 公开给参与的应用程序。同样,这需要进行大量调整。
我想您可以创建一个仅充当金丝雀的工作线程。它每 X 秒广播一次 ping,如果被 ping 的服务错过了两到三个 ping,它就认为 VM 还没有准备好提供服务。
问题是当 VM 似乎永远不会恢复时决定要做什么。是虚拟机、网络还是其他?您如何跟踪虚拟机?这些都不是棘手的问题,但它们以有趣的方式结合在一起,让您的生活同样有趣。
有很多方法可以解决这个问题,每种方法都有微妙的含义。
你能做到吗?是的
GarbageCollectorMXBean
可以向应用程序代码提供 GC 事件的通知。 (例如,请参阅 this article,其中包含用于配置通知侦听器和处理事件的示例代码。)
鉴于此,您可以轻松地编写应用程序代码,以便将关键的 GC 事件作为 UDP 消息发送出去,and/or 发送常规 UDP 消息来报告当前的 GC 状态。
但是,如果 GC 执行 "stop the world" 收集,那么您发送消息的代码也将停止,并且没有办法解决 1。如果这是一个问题,那么您可能需要采用 "canary" 方法……或者切换到低暂停收集器。 "canary" 或 "heart-beat" 方法还检测其他类型的不可用性,这将与负载均衡器相关。但是,不利的一面是您也可能会得到误报;例如"heart" 仍然是 "beating" 但 "patient" 是 "comatose"。
这是否真的对负载平衡有用是一个完全不同的问题。当然还有其他故障模式的余地。例如,如果负载均衡器错过了一条表明 JVM GC 已完成的 UDP 消息,那么 JVM 可能会有效地退出负载均衡器的池。
1 - 至少,不在 Java 之内。您可以想象在 JVM 外部构建一些东西(例如)读取 GC 日志文件并检查 OS 级进程使用信息。
您可以编写一个检测 JVM 的外部应用程序,例如通过 dtrace probes 并将事件发送到负载均衡器或由负载均衡器查询。
这个问题背后的动机是看看我们是否可以通过首先应用其指定特定节点的常规策略来将 HTTP 请求路由到(例如,通过回合robin策略)然后"peeking"进入系统内部状态,看是否正在进行垃圾回收。如果是这样,负载均衡器将完全避开该节点并移动到下一个节点。
在理想情况下,每个节点都会 "emit" 每隔几秒通过 UDP 将其内部状态发送到某个消息队列,让负载均衡器知道哪些节点可能 "radio-active" 如果它们正在通过GC(我将其可视化为一个简单的布尔值)。
这里的问题是:我可以调整我的应用程序以利用其 JVM 的内部状态,并且 (a) 弄清楚我们是否立即处于 GC 模式 (b) 通过某种协议发出此结果 (UDP/HTTP) 通过网络连接到其他实体(如 MQ 或其他实体)。
有很多方法可以远程监控和报告虚拟机。例如,众所周知的协议是 SNMP。但这是一个非常复杂的课题。
实施在某种程度上取决于您的要求。如果您确实需要确保 VM 处于良好状态,则可能需要将您的应用程序包装在控制实际 VM 的包装器 VM 中。这是相当复杂的。
许多实现使用内置的监视和分析接口,这些接口作为 bean 通过 JMX 公开给参与的应用程序。同样,这需要进行大量调整。
我想您可以创建一个仅充当金丝雀的工作线程。它每 X 秒广播一次 ping,如果被 ping 的服务错过了两到三个 ping,它就认为 VM 还没有准备好提供服务。
问题是当 VM 似乎永远不会恢复时决定要做什么。是虚拟机、网络还是其他?您如何跟踪虚拟机?这些都不是棘手的问题,但它们以有趣的方式结合在一起,让您的生活同样有趣。
有很多方法可以解决这个问题,每种方法都有微妙的含义。
你能做到吗?是的
GarbageCollectorMXBean
可以向应用程序代码提供 GC 事件的通知。 (例如,请参阅 this article,其中包含用于配置通知侦听器和处理事件的示例代码。)
鉴于此,您可以轻松地编写应用程序代码,以便将关键的 GC 事件作为 UDP 消息发送出去,and/or 发送常规 UDP 消息来报告当前的 GC 状态。
但是,如果 GC 执行 "stop the world" 收集,那么您发送消息的代码也将停止,并且没有办法解决 1。如果这是一个问题,那么您可能需要采用 "canary" 方法……或者切换到低暂停收集器。 "canary" 或 "heart-beat" 方法还检测其他类型的不可用性,这将与负载均衡器相关。但是,不利的一面是您也可能会得到误报;例如"heart" 仍然是 "beating" 但 "patient" 是 "comatose"。
这是否真的对负载平衡有用是一个完全不同的问题。当然还有其他故障模式的余地。例如,如果负载均衡器错过了一条表明 JVM GC 已完成的 UDP 消息,那么 JVM 可能会有效地退出负载均衡器的池。
1 - 至少,不在 Java 之内。您可以想象在 JVM 外部构建一些东西(例如)读取 GC 日志文件并检查 OS 级进程使用信息。
您可以编写一个检测 JVM 的外部应用程序,例如通过 dtrace probes 并将事件发送到负载均衡器或由负载均衡器查询。