Java 8 已达到支持终止期限,并将于 2026 年 1 月 31 日
弃用。弃用后,您将无法部署 Java 8 应用,即使您的组织之前曾使用组织政策重新启用旧版运行时的部署,也无法部署。现有的 Java 8 应用在
弃用日期之后将继续运行并接收流量。我们建议您
迁移到最新支持的 Java 版本。
配置预热请求以提高性能
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
在将应用代码加载到新创建的实例时,您可以使用预热请求来缩短请求与响应的延迟时间。
App Engine 经常需要将应用代码加载到全新实例中。以下情况下可能会加载实例:
- 重新部署应用版本时。
- 由于请求产生的负载超过当前运行中实例集的容量而创建新实例时。
- 维护和维修底层基础架构或物理硬件时。
将应用代码加载到新实例会产生加载请求。加载请求可能会延长用户的请求延迟时间,但您可以使用预热请求来避免此延时。预热请求会在任何实际请求到达新实例之前,先将应用的代码加载到新实例中。
如果您为应用启用了预热请求,则 App Engine 会尝试检测您的应用何时需要新实例,并发出预热请求来对新实例进行初始化。但是,此类检测尝试并不适用于所有情况。因此,即使应用中启用了预热请求,您也可能会遇到加载请求。例如,如果您的应用目前没有任何流量,则对应用的第一个请求始终会是加载请求,而不是预热请求。
与任何其他发送至 App Engine 应用的请求一样,预热请求也会使用实例小时数。在大多数启用了预热请求的情况下,您不会注意到实例小时数的增加,因为您的应用只是在预热请求(而非加载请求)中进行初始化。如果您决定执行更多工作,例如在预热请求期间预先缓存,则使用的实例小时数可能会增加。如果您将 min_idle_instances
设置为大于 0
,则在这些实例首次启动时,您可能会遇到预热请求,但在此之后这些实例将保持可用。
默认预热请求设置会导致所有 JAR 文件在内存中编入索引,并初始化应用和过滤器。
启用预热请求
App Engine 调度程序会使用预热请求,以便根据用户提供的配置来控制实例的自动扩缩。App Engine Java 运行时默认启用预热请求,因此 App Engine 会向 /_ah/warmup
发出 GET
请求,以便您可以根据需要进行响应并初始化应用的代码。您可以采用以下任一方法来对预热请求进行响应:
- 使用
<load-on-startup>
Servlet
- 提供预热逻辑的最简单方法是在
web.xml
配置文件中将您自己的 Servlet 标记为 <load-on-startup>
。
- 使用
ServletContextListener
- 让您可以在通过预热请求或加载请求第一次调用任意 Servlet 之前运行自定义逻辑。
- 使用自定义预热 Servlet
- 自定义预热 Servlet 的
service
方法只会在处理预热请求时调用,在处理加载请求时不会调用。
您可能需要为 /_ah/warmup
实现自己的处理程序,具体取决于您选择的方法。
准备工作
启用预热请求后,若调度程序确定需要更多实例,便会启动实例。调度程序会使用预热请求来启动您的应用,即使应用不处理这些预热请求,您也会看到日志。
以下消息指示 /_ah/warmup
日志中的预热请求:
This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
请注意,系统不一定会调用预热请求。在某些情况下,系统会改为发送加载请求:例如,如果实例是第一个被启动的实例,或者流量出现急剧上升。但是,如果启用了预热请求,系统将“尽力”尝试向已经预热的实例发送请求。
Java 8 应用默认启用预热请求。要启用预热请求,请将 - warmup
添加至 appengine-web.xml
中的 inbound_services
指令。由于预热会默认启用,因此只有在您先前已部署了一个应用,并且在 appengine-web.xml
中停用了预热请求时,才需要明确启用它们。如果是这种情况,您需要将 <warmup-requests-enabled>
值设置为 true
,然后重新部署。
使用 <load-on-startup>
Servlet
提供预热逻辑的最简单方法是在 web.xml
中将您自己的 Servlet 标记为 <load-on-startup>
。此方法无需更改应用代码,并可在初始化您的应用时初始化所有指定 Servlet。
在 web.xml
文件中,对于要在启动时加载的 Servlet,请将 <load-on-startup>1</load-on-startup>
元素添加到 <servlet>
元素。例如:
<servlet>
<servlet-name>my-servlet</servlet-name>
<servlet-class>com.company.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
这些代码会加载指定的 Servlet 类并调用 Servlet 的 init()
方法。在处理任何实际请求前,预热请求会先初始化指定的 Servlet。但是,如果没有预热请求,则会在新实例第一次收到请求时注册 <load-on-startup>
中指定的 Servlet,从而生成加载请求。如前所述,应用需要新实例时,App Engine 可能并不会每次都发出预热请求。
使用 ServletContextListener
如果您在调用任何 Servlet 之前要运行自定义逻辑,请执行以下操作:
在 web.xml
文件中注册一个 ServletContextListener
。
<listener>
<listener-class>com.company.MyListener</listener-class>
</listener>
提供一个类以及您的 Servlet 和过滤器代码:
public class MyListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// This will be invoked as part of a warmup request, or
// the first user request if no warmup request was invoked.
}
public void contextDestroyed(ServletContextEvent event) {
// App Engine does not currently invoke this method.
}
}
ServletContextListener
会在处理预热请求时运行。如果没有预热请求,它将在新实例第一次收到请求时运行。这可能会生成加载请求。
使用自定义预热 Servlet
自定义预热 Servlet 的 service
方法只会在处理预热请求时调用。通过将开销很大的逻辑放置到自定义预热 Servlet 中,您可以避免增加加载请求的加载时间。
如需创建自定义预热 Servlet,只需在 web.xml
中替换 _ah_warmup
的内置 Servlet 定义即可:
<servlet>
<servlet-name>_ah_warmup</servlet-name>
<servlet-class>com.company.MyWarmupServlet</servlet-class>
</servlet>
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-09-04。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["很难理解","hardToUnderstand","thumb-down"],["信息或示例代码不正确","incorrectInformationOrSampleCode","thumb-down"],["没有我需要的信息/示例","missingTheInformationSamplesINeed","thumb-down"],["翻译问题","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-09-04。"],[[["\u003cp\u003eWarmup requests help reduce latency by loading your app's code into a new instance before live requests arrive.\u003c/p\u003e\n"],["\u003cp\u003eApp Engine uses warmup requests to initialize new instances, but they aren't guaranteed to be called in every situation, and loading requests may still occur.\u003c/p\u003e\n"],["\u003cp\u003eWarmup requests are enabled by default in Java 8, and can be managed through \u003ccode\u003e<load-on-startup>\u003c/code\u003e servlets, \u003ccode\u003eServletContextListener\u003c/code\u003e, or custom warmup servlets.\u003c/p\u003e\n"],["\u003cp\u003eEnabling warmup requests will generally not increase instance hours, as it's often simply shifting initialization from loading requests to warmup requests.\u003c/p\u003e\n"],["\u003cp\u003eWhen using warmup requests, the scheduler starts up instances as needed and utilizes these warmup requests to initiate your application.\u003c/p\u003e\n"]]],[],null,["# Configuring Warmup Requests to Improve Performance\n\nYou can use warmup requests to reduce request and response latency during the\ntime when your app's code is being loaded to a newly created instance.\n\nApp Engine frequently needs to load your app's code into a fresh\ninstance. Loading an instance can happen in the following situations:\n\n- When you redeploy a version of your app.\n- When new instances are created due to the load from requests exceeding the capacity of the current set of running instances.\n- When maintenance and repairs of the underlying infrastructure or physical hardware occur.\n\nLoading your app's code to a new instance can result in [loading\nrequests](/appengine/docs/legacy/standard/java/how-instances-are-managed#loading_requests).\nLoading requests can result in increased request latency for your users, but you\ncan avoid this latency using *warmup requests*. Warmup requests load your\napp's code into a new instance before any live requests reach that instance.\n\nIf warmup requests are enabled for your application, App Engine attempts\nto detect when your application needs a new instance and initiates a warmup\nrequest to initialize a new instance. However, these detection attempts do not\nwork in every case. As a result, you might encounter loading requests, even if\nwarmup requests are enabled in your app. For example, if your app is serving no\ntraffic, the first request to the app will always be a loading request, not a\nwarmup request.\n\nWarmup requests use instance hours like any other request to your\nApp Engine application. In most cases where warmup requests are enabled,\nyou won't notice an increase in instance hours because your application is\nsimply initializing in a warmup request instead of a loading request. Your\ninstance hour usage can increase if you decide to do more work, such as\npre-caching during a warmup request. If you set\n[`min_idle_instances`](/appengine/docs/legacy/standard/java/config/appref#min_idle_instances)\nto greater than `0`, you might encounter warmup requests when those instances\nfirst start, but they will remain available after that time.\nThe default warmup request causes all JAR files to be indexed in memory and initializes your application and filters.\n\nEnabling warmup requests\n------------------------\n\nWarmup requests are used by the App Engine scheduler, which\ncontrols the auto scaling of instances based on user-supplied configuration.\nIn the App Engine Java runtime, warmup requests are enabled by\ndefault, and so App Engine issues `GET` requests to `/_ah/warmup`, which allows\nyou to respond and initialize your application's code as it requires. You can\nrespond to warmup requests by using one of the following methods:\n\n[Using a `\u003cload-on-startup\u003e` servlet](#load-on-startup)\n: The easiest way to provide warmup logic is to mark your own servlets as\n `\u003cload-on-startup\u003e` in the `web.xml` configuration file.\n\n[Using a `ServletContextListener`](#servlet-context-listener)\n: Allows you to run custom logic before any of your servlets is first invoked\n either through a warmup request or a loading request.\n\n[Using a custom warmup servlet](#custom-servlet)\n: Using a custom warmup servlet invokes the servlet's `service` method *only*\n during a warmup request rather than during loading requests.\n\nYou might need to implement your own handler for `/_ah/warmup` depending on\nwhich of these methods you choose.\n\nBefore you begin\n----------------\n\nWhen warmup requests are enabled, the scheduler starts up instances when it\ndetermines that more instances are needed. The scheduler uses warmup\nrequests to start your app, so you'll see logs even if your app doesn't process\nthose warmup requests.\n\nThe following message indicates warmup requests in the `/_ah/warmup` logs: \n\n```\nThis request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.\n```\n\nNote that warmup requests are not guaranteed to be called. In some situations\nloading requests are sent instead: for example, if the instance is the first one\nbeing started up, or if there is a steep ramp-up in traffic. However, there\nwill be a \"best effort\" attempt to send requests to already warmed-up instances\nif warmup requests are enabled.\n\nIn Java 8, warmup requests are enabled by default. To enable them,\nadd `- warmup` to the\n[`inbound_services`](/appengine/docs/legacy/standard/java/config/appref#inbound_services)\ndirective in `appengine-web.xml`. Because by default,\nwarmups are enabled, you only need to explicitly enable them if you have\npreviously deployed an application with warmup requests disabled in the `appengine-web.xml`.\nIf this is the case, you need to set the `\u003cwarmup-requests-enabled\u003e` value to\n`true` and then redeploy.\n\nUsing a `\u003cload-on-startup\u003e` servlet\n-----------------------------------\n\nThe easiest way to provide warmup logic is to mark your own servlets as\n`\u003cload-on-startup\u003e` in `web.xml`. This method requires no changes to your\napplication code, and initializes all specified servlets when your application\ninitializes.\n\nIn your `web.xml` file, for the servlets that you want to load on startup,\nadd the `\u003cload-on-startup\u003e1\u003c/load-on-startup\u003e` element to your `\u003cservlet\u003e`\nelement. For example: \n\n \u003cservlet\u003e\n \u003cservlet-name\u003emy-servlet\u003c/servlet-name\u003e\n \u003cservlet-class\u003ecom.company.MyServlet\u003c/servlet-class\u003e\n \u003cload-on-startup\u003e1\u003c/load-on-startup\u003e\n \u003c/servlet\u003e\n\nThese lines load the specified servlet class and invoke the servlet's `init()`\nmethod. The warmup request initializes the specified servlets before servicing\nany live requests. However, if there is no warmup request, the servlets\nspecified in `\u003cload-on-startup\u003e` are registered upon the first request to a new\ninstance, which result in a loading request. As noted earlier, App Engine might\nnot issue a warmup request every time your application needs a new instance.\n\nUsing a `ServletContextListener`\n--------------------------------\n\nIf you have custom logic that you want to run before any of your servlets is\ninvoked:\n\n1. Register a [`ServletContextListener`](https://docs.oracle.com/javaee/7/api/javax/servlet/ServletContextListener.html)\n in your `web.xml` file.\n\n \u003clistener\u003e\n \u003clistener-class\u003ecom.company.MyListener\u003c/listener-class\u003e\n \u003c/listener\u003e\n\n2. Supply a class alongside your servlet and filter code:\n\n public class MyListener implements ServletContextListener {\n public void contextInitialized(ServletContextEvent event) {\n // This will be invoked as part of a warmup request, or\n // the first user request if no warmup request was invoked.\n }\n public void contextDestroyed(ServletContextEvent event) {\n // App Engine does not currently invoke this method.\n }\n }\n\nThe `ServletContextListener` runs during a warmup request. If there is no warmup\nrequest, it runs upon the first request to a new instance. This might result in\nloading requests.\n\nUsing a custom warmup servlet\n-----------------------------\n\nThe custom warmup servlet invokes the servlet's `service` method *only* during a\nwarmup request. By placing expensive logic in a custom warmup servlet, you can\navoid increased load times on loading requests.\n\nTo create a custom warmup servlet, simply override the built-in servlet\ndefinition for `_ah_warmup` in `web.xml`: \n\n \u003cservlet\u003e\n \u003cservlet-name\u003e_ah_warmup\u003c/servlet-name\u003e\n \u003cservlet-class\u003ecom.company.MyWarmupServlet\u003c/servlet-class\u003e\n \u003c/servlet\u003e"]]