TCP:内存不足—考虑调整tcp_mem

发布于:2021-01-07 16:18:08

0

1952

0

java 内存 tcp_mem

Ram Lakshmanan在Elastic Load Balancer之后的多个AWS EC2实例上运行的应用程序中讨论了一个奇怪的生产问题。在本文中,查找有关错误消息“ TCP:内存不足-考虑调整tcp_mem”,如何处理以及有关内存问题和'dmesg'命令的一些结论性建议。

最近,我们遇到了一个有趣的生产问题。一个应用程序在Elastic Load Balancer后面的多个AWS EC2实例上运行。该应用程序在GNU / Linux OS,Java 8和Tomcat 8应用程序服务器上运行。

突然之间,一个应用程序实例变得无响应。所有其他应用程序实例都在正确处理流量。每当从浏览器向该应用程序实例发送HTTP请求时,我们都会在浏览器上打印以下响应。

Proxy Error  The proxy server received an invalid response from an upstream server.  The proxy server could not handle the request GET /. Reason: Error reading from remote server

我们使用了APM(应用程序性能监视)工具来检查问题。从APM工具中,我们可以观察到CPU和内存利用率是完美的。另一方面,从APM工具中,我们可以看到流量并没有进入这个特定的应用程序实例。真是令人费解。为什么流量没有进入?

我们登录到该有问题的AWS EC2实例。我们执行了vmstat,iostat,netstat,top,df命令,以查看是否可以发现任何异常。令我们惊讶的是,所有这些出色的工具均未报告任何问题。

对于下一步,我们重新启动了运行该应用程序的Tomcat应用程序服务器。它也没有任何区别。不过,这个应用程序实例根本没有响应。

DMESG命令

然后,我们在此EC2实例上发出了' dmesg '命令。此命令显示内核的消息缓冲区。该命令的输出通常包含设备驱动程序产生的消息。在此命令生成的输出中,我们注意到以下有趣的消息被重复打印:

[4486500.513856] TCP: out of memory -- consider tuning tcp_mem [4487211.020449] TCP: out of memory -- consider tuning tcp_mem [4487369.441522] TCP: out of memory -- consider tuning tcp_mem [4487535.908607] TCP: out of memory -- consider tuning tcp_mem [4487639.802123] TCP: out of memory -- consider tuning tcp_mem [4487717.564383] TCP: out of memory -- consider tuning tcp_mem [4487784.382403] TCP: out of memory -- consider tuning tcp_mem [4487816.378638] TCP: out of memory -- consider tuning tcp_mem [4487855.352405] TCP: out of memory -- consider tuning tcp_mem [4487862.816227] TCP: out of memory -- consider tuning tcp_mem [4487928.859785] TCP: out of memory -- consider tuning tcp_mem [4488215.969409] TCP: out of memory -- consider tuning tcp_mem [4488642.426484] TCP: out of memory -- consider tuning tcp_mem [4489347.800558] TCP: out of memory -- consider tuning tcp_mem [4490054.414047] TCP: out of memory -- consider tuning tcp_mem [4490763.997344] TCP: out of memory -- consider tuning tcp_mem [4491474.743039] TCP: out of memory -- consider tuning tcp_mem [4491859.749745] TCP: out of memory -- consider tuning tcp_mem [4492182.082423] TCP: out of memory -- consider tuning tcp_mem [4496318.377316] TCP: out of memory -- consider tuning tcp_mem [4505666.858267] TCP: out of memory -- consider tuning tcp_mem [4521592.915616] TCP: out of memory -- consider tuning tcp_mem

我们很高兴看到此错误消息:“ TCP:内存不足-请考虑调整tcp_mem ”。这意味着在TCP级别发生内存不足错误。我们一直教导说,内存不足错误只会在应用程序级别发生,而不会在TCP级别发生。

还请参见: 谁?为什么?什么?固定?– System.gc()

问题之所以令人着迷,是因为我们每天都在呼吸这个OutOfMemoryError问题。我们构建了故障排除工具,如GCeasy和 HeapHero,以方便工程师调试在应用程序级别(Java,Android,Scala,Jython…应用程序)发生的OutOfMemoryError。关于这个OutOfMemoryError主题,我们已经写了几个博客。但是我们很沮丧地看到OutOfMemory在设备驱动程序级别发生。我们从来没有想到稳定的Linux操作系统也会在设备驱动程序级别出现问题。受这个问题困扰,我们不确定如何进一步进行。

因此,我们求助于Google God的帮助。搜寻搜索词:“ TCP:内存不足-考虑调整tcp_mem”,仅显示12个搜索结果。除了一篇文章,他们都没有太多的内容。即使是一篇用外国语言写的文章,我们也听不懂。因此,我们不确定如何解决此问题。

现在没有其他解决方案了,我们继续实施了通用解决方案,即“重启”。我们重新启动了EC2实例,以扑灭即时起火。欢呼!!重新启动服务器可立即解决问题。显然,该服务器已经几天没有重启(例如超过70天以上)。可能由于这个原因,应用程序可能具有饱和的TCP内存限制。

我们与一位在世界一流技术公司工作的聪明朋友取得了联系。这个朋友问我们为以下内核属性设置的值:

  • net.core.netdev_max_backlog

  • net.core.rmem_max

  • net.core.wmem_max

  • net.ipv4.tcp_max_syn_backlog

  • net.ipv4.tcp_rmem

  • net.ipv4.tcp_wmem

老实说,这是我们第一次听到这些特性。我们发现以下是在服务器中为这些属性设置的值:

net.core.netdev_max_backlog = 1000 net.core.rmem_max = 212992 net.core.wmem_max = 212992 net.ipv4.tcp_max_syn_backlog = 256 net.ipv4.tcp_rmem = 4096        87380   6291456 net.ipv4.tcp_wmem = 4096        20480   4194304

我们的朋友建议更改以下值:

net.core.netdev_max_backlog=30000 net.core.rmem_max=134217728 net.core.wmem_max=134217728 net.ipv4.tcp_max_syn_backlog=8192 net.ipv4.tcp_rmem=4096 87380 67108864 net.ipv4.tcp_wmem=4096 87380 67108864

他提到设置这些值将消除我们面临的问题。我正在与您分享价值观(因为这可能会对您有所帮助)。显然,与他提供的价值相比,我们的价值非常低。

结论

以下是我们要得出的一些结论:

  • 甚至现代的行业标准APM(应用程序性能监视)工具也不能完全解决我们今天面临的应用程序性能问题。

  • ' dmesg '命令是您的朋友。您可能希望在应用程序无响应时执行此命令,它可能会指出有价值的信息。

  • 内存问题不必在我们编写的代码中发生,甚至可以在TCP /内核级别发生。