“Java应用延迟降低”

提升Java应用的延迟降低效果

在我的应用开发生涯中,我所面临的一个艰难而模糊的问题是改进分布式数据检索应用程序的延迟。

这是一个容器化的Java应用程序,用于在最大的零售网站上提供产品广告。目标是减少延迟,以便提供额外的处理空间,特别是运行和实验先进的机器学习模型,以为客户提供更好的广告。

我使用的技术之一是内存分析,以了解JVM内存使用情况周围的活动。尽管听起来很简单,但我发现了一些重大的障碍,需要一些时间来解决。最后,我成功地克服了每一个障碍,并将应用程序p99延迟从400毫秒降低到240毫秒。

延迟降低对我来说是一个新的挑战,所以我需要最佳的工具来应对。有许多可用的工具,包括开源和付费工具,但我发现eclipse内存分析工具MAT在免费工具中最有用。有许多关于如何安装和使用MAT的文章,所以我不会详细介绍。

在本文中,我将介绍与大型生产应用程序的内存分析相关的挑战以及如何克服它们。

挑战

  1. 大型应用程序的JVM堆内存占用量非常大,在我的案例中大约为100 GB。分析如此庞大的堆转储需要大量内存来运行分析工具,通常在普通笔记本上速度很慢。
  2. 大型堆转储同样需要大量磁盘空间。如果磁盘空间不足,堆转储命令将失败,或者在最糟糕的情况下填满根分区并导致主机崩溃。
  3. 堆转储是一个停止应用程序运行的事件。进行堆转储会暂停应用程序中的所有活动,这可能导致健康检查失败并导致应用程序被终止,使得难以获取堆转储文件。

解决方案

  1. 对于大型堆转储,最好使用像AWS EC2这样具有足够内存和磁盘空间的云资源。
  2. 为了解决磁盘空间问题,如果应用程序正在一些云资源上运行,通常会有单独的附加存储空间。在进行堆转储之前,可以增加单独的存储空间。
  3. 检查应用程序是否使用定期健康检查进行监控,例如是否是负载均衡器的一部分。如果是这样的情况,需要将其从提供服务的群组中移除,以避免在开始堆转储命令后被终止。
  4. 在一定时间间隔内进行多次堆转储,以捕捉服务状态的变化。

改进

  1. 一个主要问题是内存缓存,导致保留的内存过多,从而导致频繁的垃圾回收并造成延迟影响。
  2. 内存分析提供了一个重要的线索,关于如何使用用于数据检索的数据索引。结果发现,完整的索引加载在JVM堆中,并且还存储在tmpfs上,因此使用了两倍于所需内存,这是不必要的,并且导致频繁的垃圾回收。

结论

对于任何大规模生产应用程序来说,内存分析都是至关重要的。

在应用程序内部进行数据缓存可能是有用的,但应密切监控以检测任何随时间而降低的情况。

堆转储分析是一个强大的工具。如果使用正确的机器和工具进行,它可能会变得很麻烦。

在进行堆转储时,注意生产应用程序的健康检查例程,以成功收集相同的信息。

为了保持文章简短,我没有深入细节。如果有人想要更多信息,请随时向我发送消息。