我正在使用Elasticsearch 1.5.1
和Tomcat 7
。 Web应用程序在服务器启动期间通过Spring Framework创建一个TCP client
实例作为Singleton。
注意到我在服务器关闭期间无法关闭客户端。
通过对VisualVm, JConsole, MAT in Eclipse
等各种工具的分析,很明显,即使在服务器(tomcat
)关闭之后,elasticsearch客户端创建的线程仍然存在。
注意:在通过client.close()
Context Listener
方法引入destroy
后,线程会被优雅地杀死。
但我的查询是,
我们在PROD中遇到了Out of memory:Perm gen
个错误。这可能是一个原因,但仍然是I would like to measure and provide stats for this.
请提出任何建议/帮助。
答案 0 :(得分:1)
通常,客户端在与其通信的服务不同的进程中运行。例如,我可以在Web浏览器中打开网页,然后关闭网络服务器,客户端将保持打开状态。
这与TCP / IP的基础设计选择有关。对细节进行着色,在大多数情况下,客户端仅检测到服务器在下一次向服务器发出请求时消失。 (一般来说)它不会连续轮询服务器以查看它是否存在,服务器通常也不会在关闭时发送“请断开连接”消息。
客户端通常不轮询服务器的原因是它允许服务器处理更多客户端。使用轮询方法,服务器受到运行的客户端数量的限制,但是没有轮询方法,它受到主动通信的客户端数量的限制。这允许它支持更多客户端,因为许多正在运行的客户端没有主动通信。
服务器通常不发送“我正在关闭”消息的原因是因为很多时候服务器无法控制地停机(停电,操作系统崩溃,火灾,短路等)这意味着协议如果服务器以不受控制的方式发生故障,需要这样的消息将使客户端处于损坏状态。
失去连接实际上是对服务器失败请求的一个功能。客户端通常仍会运行,直到下一次尝试做某事为止。
同样,打开与服务器的连接通常也不会在大多数情况下执行任何操作。要验证您确实与服务器建立了有效连接,您必须向它询问一些数据并获得回复。大多数协议自动执行此操作以简化逻辑;但是,如果您编写自己的服务,如果您不要求服务器提供数据,即使API说您有良好的“连接”,也可能不会。当您在计算机上成功配置了所有内容后,API可以报告良好的“连接”。要真正知道它是否在其他机器上100%工作,您需要询问数据(并获取它)。
最后服务器有时会丢失他们的客户端,但是因为他们不会浪费带宽与客户端聊天只是为了看他们是否在那里,通常服务器会在客户端连接上放置“超时”。基本上,如果服务器在10分钟内没有收到客户端的声音(或配置的值),那么它会关闭客户端的缓存连接信息(如果客户端回来,则根据需要重新创建连接信息)。
根据您的描述,您可能会看到哪些方案尚不清楚,但希望这些一般知识可以帮助您理解为什么在关闭连接的一侧之后,连接的另一侧可能仍然认为它是开放的一会儿。
有一些方法可以将网络连接配置为更快地报告闭包,但我会避免使用它们,除非您愿意丢失大量的网络带宽以保留活动消息并且不希望服务器响应尽可能快。