【发布时间】:2023-03-16 04:22:01
【问题描述】:
我注意到在应用引擎上运行的应用会出现周期性但持续的延迟峰值。起初我认为网络可能很慢,但应用统计数据证实并非如此。
我已经能够使用旧版本和新版本的 SDK 重现延迟峰值,目前我正在使用以下版本:
- 应用引擎 SDK:1.9.42
- Google 云端点:1.9.42
- 对象化:5.1.13
- Appstats(用于调试网络延迟)
因此,该应用的使用率非常低,在过去 30 天里,我的请求量通常低于每秒 0.04 次:
大多数操作的延迟远低于一秒,但数量惊人的请求需要 10-30 倍的时间。
所以我认为这一定只是网络延迟,但每个运行速度较慢的 appstat 都反驳了这一点。数据存储和网络一直非常可靠。下面是一个耗时超过 30 秒的慢请求的剖析:
在高层次上,我的代码非常无趣:它是一个简单的 api,可以进行一些网络调用并从云数据存储中保存/读取数据。整个源代码可以在github here 上找到。该应用程序在单个 Auto Scaling 应用程序引擎实例上运行并已预热。
看到即使是快速操作,也有很大一部分时间花费在 CPU 上,这真的很奇怪,尽管代码只是创建了一些对象,将它们持久化并返回 JSON。我想知道 CPU 是否被另一个应用程序固定在我的应用程序引擎实例上,这可能会导致性能定期下降。
我的 appengine.xml 配置如下所示:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>sauce-sync</application>
<version>1</version>
<threadsafe>true</threadsafe>
<automatic-scaling>
<!-- always keep an instance up in order to keep startup time low-->
<min-idle-instances>1</min-idle-instances>
</automatic-scaling>
</appengine-web-app>
我的 web.xml 看起来像这样:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.sauce.sync.SauceSyncEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<!--reaper-->
<servlet>
<servlet-name>reapercron</servlet-name>
<servlet-class>com.sauce.sync.reaper.ReaperCronServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>reapercron</servlet-name>
<url-pattern>/reapercron</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>reaper</servlet-name>
<servlet-class>com.sauce.sync.reaper.ReaperServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>reaper</servlet-name>
<url-pattern>/reaper</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
TLDR 我完全被卡住了,我不知道如何调试或解决这个问题,我开始认为这对于应用引擎上的小型应用来说是正常的。
我正在考虑关闭常驻实例一段时间,希望我的应用程序刚刚运行了一些双层硬件或与消耗大量资源的应用程序一起运行。有没有人遇到过类似的性能问题或知道其他方法来分析您的应用程序?
编辑:
我尝试在 1 个常驻实例上运行,我还尝试在 2-4 per this question 设置并发请求,但没有结果。日志和 appstats 都确认花费了过多的时间来等待我的代码最初运行。这是一个在我的第一行代码运行之前需要 25 秒的请求,不确定此时端点/应用程序引擎在做什么。
再次负载仍然很低,这是请求在预热的实例上。
编辑2:
似乎无论出于何种原因,应用程序引擎 + 端点都不能很好地与 min-idle-instances 设置配合使用。恢复到默认的应用引擎配置解决了我的问题。
【问题讨论】:
-
可能相关(但在负载下可见):stackoverflow.com/questions/37307461/…
-
通常有多少实例处于活动状态?即使您将最小空闲实例设置为 1,但这并不意味着新实例的出现没有延迟。
-
一般1个实例,附上一张图,上面有实例的数量。不过,我不确定这是否意味着太多,即使是冷实例启动所需的时间也远短于 30 秒来启动和完成请求。高延迟似乎更有可能导致额外的节点产生。此外,所有慢速请求都发生在第一个实例上,因为未为这些慢速请求设置 loading_request
标签: java google-app-engine google-cloud-endpoints objectify