區域 ID
REGION_ID
是 Google 根據您在建立應用程式時選取的地區所指派的縮寫代碼。此代碼不對應至國家/地區或省份,即使部分區域 ID 可能與常用的國家/地區和省份代碼相似。如果是 2020 年 2 月後建立的應用程式,App Engine 網址會包含 REGION_ID.r
。如果是這段時間前建立的現有應用程式,網址可選擇是否包含地區 ID。
進一步瞭解區域 ID。
本文件說明 App Engine 應用程式如何接收要求及傳送回應。
詳情請參閱要求標頭和回應參考資料。
如果您的應用程式使用服務,則可以設定要求的位址,將要求傳送到特定服務或該服務的特定版本。如要進一步瞭解服務的定址功能,請參閱要求的轉送方式一文。
處理要求
您的應用程式負責啟動網路伺服器和處理要求。 只要是適用於您開發語言的網路架構,您都可以使用。
App Engine 收到應用程式的網路要求時,會叫用網址對應的 Servlet,如應用程式在 web.xml
目錄中的 WEB-INF/
檔案所述。接著,App Engine 會依照 Java Servlet 2.5 或 3.1 API 規範,提供要求資料給 Servlet,然後接受回應資料。
App Engine 會執行應用程式的多個執行個體,每個執行個體都有各自用來處理要求的網路伺服器。每個要求都能轉送至任何執行個體,因此同個使用者發出的連續要求不一定會送至相同的執行個體。執行個體的數量可隨流量變化而自動調整。
根據預設,每個網路伺服器一次僅能處理一個要求。如要將多個要求平行傳送至每個網頁伺服器,請將 <threadsafe>true</threadsafe>
元素新增至 appengine-web.xml
檔案,將應用程式標示為執行緒安全。
下列 Servlet 類別範例會在使用者瀏覽器上顯示簡單訊息。
配額與限制
App Engine 會在流量增加時自動分配資源給您的應用程式,然而這項作業會受到下列限制:
對於低延遲時間的應用程式 (回應要求的時間不到一秒),App Engine 會保留自動調整資源配置的容量。
大幅受到 CPU 限制的應用程式可能也會產生一些額外的延遲時間,以便和相同伺服器上的其他應用程式有效率地共用資源。對靜態檔案的要求則不受這些延遲限制。
每個傳送至應用程式的要求均會計入「Requests」(要求) 限制。 而回應要求所傳送的資料則會計入「Outgoing Bandwidth (billable)」(連出頻寬 (可計費)) 限制。
HTTP 及 HTTPS (加密連線) 要求均會計入「Requests」(要求)、「Incoming Bandwidth (billable)」(連入頻寬 (可計費)) 及「Outgoing Bandwidth (billable)」(連出頻寬 (可計費)) 的限制。Google Cloud 控制台的「Quota Details」(配額詳細資料) 頁面也會個別回報「Secure Requests」(安全性要求)、「Secure Incoming Bandwidth」(安全連入頻寬) 和「Secure Outgoing Bandwidth」(安全連出頻寬) 的值,以供參考之用。僅有 HTTPS 要求會計入這些值。詳情請參閱配額頁面。
要求處理常式的使用配額還受到下列特別限制:
限制 | 大小 |
---|---|
要求大小 | 32 MB |
回應大小 | 32 MB |
要求逾時 | 視應用程式使用的資源調度類型而定 |
檔案總數量的上限 (應用程式檔案和靜態檔案) | 總計 10,000 個 每個目錄 1,000 個 |
應用程式檔案大小上限 | 32 MB |
靜態檔案的大小上限 | 32 MB |
所有應用程式和靜態檔案的總大小上限 | 前 1 GB 免費 前 1 GB 過後,每個月每 GB$ 0.026 美元 |
待處理要求逾時 | 10 秒 |
單一要求標頭欄位的大小上限 | 標準環境中的第二代執行階段為 8 KB。如果傳送至這些執行階段的要求標頭欄位超過 8 KB,系統會傳回 HTTP 400 錯誤。 |
要求限制
所有 HTTP/2 要求在轉送到應用程式伺服器時,都會轉譯成 HTTP/1.1 要求。
回應限制
動態回應大小上限為 32 MB。如果指令碼處理常式產生大於此上限的回應,伺服器會傳回空白回應並顯示「500 Internal Server Error」(內部伺服器錯誤) 狀態碼。這項限制不適用於從舊版 Blobstore 和 Cloud Storage 提供資料的回應。
第二代執行階段的回應標頭大小上限為 8 KB。 如果回應標頭超出這項限制,系統會傳回 HTTP 502 錯誤,且記錄檔會顯示
upstream sent too big header while reading response header from upstream
。
要求標頭
傳入 HTTP 要求包含用戶端傳送的 HTTP 標頭。基於安全性考量,部分標頭在送達應用程式之前會由中繼 Proxy 進行處理或修改。
詳情請參閱要求標頭參考資料。
處理要求逾時
App Engine 已針對要求持續時間短暫的應用程式進行最佳化,尤其是回應要求只需耗費數百毫秒的應用程式。效率良好的應用程式能快速回應大部分的要求,至於回應速度不夠快的應用程式,則無法隨著 App Engine 的基礎架構妥善調度資源。為確保達到這個效能水準,系統會強制設定要求逾時上限,所有應用程式都必須在時限內回應。
如果應用程式超過這個期限,App Engine 會中斷要求處理常式。Java 執行階段環境會中斷 Servlet,方式為擲出com.google.apphosting.api.DeadlineExceededException
。如果沒有任何要求處理常式擷取到此例外情況,則執行階段環境會將「HTTP 500 伺服器錯誤」傳回用戶端。
如果有要求處理常式擷取到 DeadlineExceededException
,則執行階段環境會給要求處理常式準備自訂回應的時間 (不到一秒)。發生例外狀況後,如果要求處理常式準備自訂回應的時間超過一秒,則會產生 HardDeadlineExceededError
。
DeadlineExceededExceptions
和 HardDeadlineExceededErrors
都會強制終止要求並停止執行個體。
如要瞭解期限截止前還有多少時間,應用程式可以匯入 com.google.apphosting.api.ApiProxy
並呼叫 ApiProxy.getCurrentEnvironment().getRemainingMillis()
。如果應用程式打算啟動的工作可能需要過長的執行時間,則這項匯入及呼叫作業會非常有用;如果您知道一個工作單元的處理時間為五秒鐘,但 getRemainingMillis()
傳回的時間卻不到五秒,即沒必要啟動該工作單元。
回應
App Engine 會使用要求物件和回應物件來呼叫 Servlet,然後等待 Servlet 填入回應物件並回傳。 Servlet 回傳時,回應物件上的資料會傳送給使用者。您產生的回覆會受到大小限制,而且在傳回用戶端前可能已經過修改。
詳情請參閱要求回應參考資料。串流回應
若資料在要求處理過程中,以增量區塊的形式傳送至用戶端,那麼 App Engine 並不支援此類資料的串流回應。系統會依上述方式收集所有來自程式碼的資料,並做為單一 HTTP 回應傳送。
回應壓縮
App Engine 會盡量向支援壓縮 (gzip) 的用戶端提供壓縮內容。為判斷是否應壓縮內容,App Engine 會在收到要求時執行下列操作:查看要求中的
Accept-Encoding
和User-Agent
標頭,確認用戶端是否能穩定接收壓縮過的回應。這種方法可避免熱門瀏覽器中一些常在 gzip 格式的壓縮內容上發生的問題。查看您為回應處理常式設定的
Content-Type
標頭,確認是否適合壓縮內容。一般來說,壓縮適用於文字內容類型,但不適用於二進位內容類型。
注意事項:
用戶端可以將
Accept-Encoding
和User-Agent
要求標頭都設為gzip
,強制壓縮文字型內容類型。如果要求未在
Accept-Encoding
標頭中指定gzip
,App Engine 就不會壓縮回應資料。Google 前端會快取 App Engine 靜態檔案和目錄處理常式的回應。視多項因素而定 (例如最先快取的回應資料類型、您在回應中指定的
Vary
標頭,以及要求中包含的標頭),用戶端可能會要求壓縮資料,但收到未壓縮的資料,反之亦然。詳情請參閱回應快取。
回應快取
Google 前端,以及可能的使用者瀏覽器和其他中繼快取 Proxy 伺服器,會根據您在回應中指定的標準快取標頭,快取應用程式的回應。您可以透過架構、直接在程式碼中,或透過 App Engine 靜態檔案和目錄處理常式,指定這些回應標頭。
在 Google 前端,快取金鑰是要求的完整網址。
快取靜態內容
為確保用戶端在發布靜態內容後,能立即收到更新,建議您從版本目錄 (例如 css/v1/styles.css
) 提供靜態內容。快取到期前,Google 前端不會驗證快取 (檢查更新內容)。即使快取過期,只要要求網址的內容未變更,快取就不會更新。
您可以在
appengine-web.xml
中設定下列回應標頭,影響 Google 前端快取內容的方式和時間:
應設為
public
,Google 前端才能快取內容;除非您指定Cache-Control
private
或no-store
指令,否則 Google 前端也可能會快取內容。Cache-Control
如果您未在appengine-web.xml
中設定這個標頭,App Engine 會自動為靜態檔案或目錄處理常式處理的所有回應新增這個標頭。詳情請參閱「新增或取代的標頭」。Vary
:如要讓快取根據要求中傳送的標頭,針對網址傳回不同的回應,請在Vary
回應標頭中設定一或多個下列值:Accept
、Accept-Encoding
、Origin
或X-Origin
。由於其他
Vary
值可能具有高基數,因此系統不會快取這些值的資料。例如:
您指定下列回應標頭:
Vary: Accept-Encoding
應用程式會收到含有
Accept-Encoding: gzip
標頭的要求。App Engine 會傳回壓縮回應,而 Google 前端會快取回應資料的 gzip 版本。後續所有包含Accept-Encoding: gzip
標頭的這類網址要求,都會從快取收到經過 gzip 壓縮的資料,直到快取失效為止 (快取過期後內容變更)。您的應用程式收到不含
Accept-Encoding
標頭的要求。App Engine 會傳回未壓縮的回應,而 Google Frontend 會快取未壓縮的回應資料版本。後續對這個網址的所有要求,只要不含Accept-Encoding
標頭,都會從快取接收壓縮資料,直到快取失效為止。
如未指定
Vary
回應標頭,Google 前端會為網址建立單一快取項目,並用於所有要求,不論要求中的標頭為何。例如:- 您未指定
Vary: Accept-Encoding
回應標頭。 - 要求包含
Accept-Encoding: gzip
標頭,且回應資料的 gzip 壓縮版本會快取。 - 第二個要求不含
Accept-Encoding: gzip
標頭。 不過,由於快取包含回應資料的 gzip 壓縮版本,即使用戶端要求未壓縮的資料,回應仍會經過 gzip 壓縮。
要求中的標頭也會影響快取:
- 如果要求包含
Authorization
標頭,Google 前端不會快取內容。
快取到期
根據預設,App Engine 靜態檔案和目錄處理常式新增至回應的快取標頭,會指示用戶端和 Google 前端等網路 Proxy 在 10 分鐘後使快取失效。
擁有指定到期時間的檔案在傳輸之後,通常就無法從網路 Proxy 快取中清除,就算使用者清除了自己的瀏覽器快取也沒辦法。重新部署新版應用程式時,並不會重設任何快取。因此,如果您打算修改靜態檔案,請為其設定較短的效期 (不超過一小時)。在大多數情況下,預設的 10 分鐘效期即為適當的設定。
如要變更所有靜態檔案和目錄處理常式的預設到期日,請在 appengine-web.xml
檔案中指定 static-files
元素。
記錄
應用程式可以使用 java.util.logging.Logger,將資訊寫入應用程式記錄檔。您可以在 Google Cloud 控制台中使用 Cloud Logging 查看應用程式的記錄資料。每個記錄的要求都有系統指派的要求 ID,這是根據要求開始時間編號的全域不重複 ID。Google Cloud 主控台可辨識Logger
類別的記錄層級,並以互動方式顯示不同層級的訊息。
App Engine 可擷取 Servlet 寫入標準輸出串流 (System.out
) 和標準錯誤串流 (System.err
) 的所有資訊,並將資訊記錄在應用程式記錄中。寫入標準輸出串流的資料會以「INFO」層級記錄,而寫入標準錯誤串流的資料會以「WARNING」層級記錄。任何將資料記錄至輸出或錯誤串流的記錄架構 (例如 log4j) 皆可發揮作用,但如要更精細地控制 Google Cloud 控制台中顯示的記錄層級,記錄架構必須使用 java.util.logging
轉接器。
App Engine Java SDK 在 appengine-java-sdk/config/user/
目錄中含有 logging.properties
範本檔案。如要使用此檔案,請將檔案複製到您的 WEB-INF/classes
目錄 (或 WAR 的其他位置),然後將系統屬性 java.util.logging.config.file
複製到 "WEB-INF/logging.properties"
(或您選擇的路徑,該路徑必須是應用程式根目錄的相對路徑)。您可以在 appengine-web.xml
檔案中設定系統屬性,如下所示:
Servlet 會使用 INFO
記錄層級來記錄訊息 (使用 log.info()
)。預設的記錄層級是 WARNING
,此層級禁止輸出中包含 INFO
訊息。如要變更記錄層級,請編輯 logging.properties
檔案。
環境
所有系統屬性和環境變數僅供應用程式使用,不對外公開。設定系統屬性僅會影響應用程式對該屬性的檢視,不會影響 JVM 的檢視。您可以在部署作業描述元中設定應用程式的系統屬性和環境變數。
App Engine 會設定數種可以辨識執行階段環境的系統屬性:
在 App Engine 上執行時,
com.google.appengine.runtime.environment
為"Production"
,在開發伺服器上執行時,則為"Development"
。除了使用
System.getProperty()
之外,您還可以使用 Type-safe API 來存取系統屬性。例如:if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) { // The app is running on App Engine... }
com.google.appengine.runtime.version
是執行階段環境的版本 ID,例如"1.3.0"
。您可以叫用下列指令來取得版本:String version = SystemProperty.version.get();
com.google.appengine.application.id
是應用程式的 ID。您可以叫用下列指令來取得此 ID:String ID = SystemProperty.applicationId.get();
com.google.appengine.application.version
是目前正在執行的應用程式服務的主要和次要版本,以「X.Y」表示。主要版本號碼 (「X」) 會在服務的appengine-web.xml
檔案中指定。次要版本號碼 (「Y」) 會在每個應用程式版本上傳至 App Engine 時自動設定。您可以叫用下列指令來取得此 ID:String ID = SystemProperty.applicationVersion.get();
在開發網路伺服器上,傳回的主要版本一律是預設的服務版本,而次要版本一律是「1」。
App Engine 在應用程式伺服器上初始化 JVM 時,還會設定下列系統屬性:
file.separator
path.separator
line.separator
java.version
java.vendor
java.vendor.url
java.class.version
java.specification.version
java.specification.vendor
java.specification.name
java.vm.vendor
java.vm.name
java.vm.specification.version
java.vm.specification.vendor
java.vm.specification.name
user.dir
執行個體 ID
您可以使用下列程式碼來擷取處理要求的執行個體 ID:
com.google.apphosting.api.ApiProxy.getCurrentEnvironment().getAttributes().get("com.google.appengine.instance.id")
在實際工作環境中,登入的管理員可在下列網址中使用此 ID:
https://INSTANCE_ID-dot-VERSION_ID-dot-SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com
。要求會轉送至指定的執行個體。如果執行個體無法處理要求,則會立即傳回 503 錯誤。
要求 ID
提出要求時,您可以儲存不重複的要求 ID,以利之後用於在要求與其相關記錄之間建立關聯。
下列程式碼示範如何在要求的內文中取得要求 ID:
com.google.apphosting.api.ApiProxy.getCurrentEnvironment().getAttributes().get("com.google.appengine.runtime.request_log_id")
強制 HTTPS 連線
基於安全性考量,所有應用程式皆應鼓勵用戶端透過 https
連線。如要指示瀏覽器針對指定網頁或整個網域採用 https
而非 http
,請在回應中設定 Strict-Transport-Security
標頭。例如:
Strict-Transport-Security: max-age=31536000; includeSubDomains
大多數應用程式架構和網路伺服器都支援為程式碼產生的回應設定這個標頭。如要瞭解 Spring Boot 中的 Strict-Transport-Security
標頭,請參閱「HTTP 嚴格傳輸安全性 (HSTS)」。
處理非同步背景工作
背景工作是指應用程式在傳送 HTTP 回應後,為要求執行的任何工作。請避免在應用程式中執行背景工作,並檢查程式碼,確認在您傳送回應之前,所有非同步作業皆已完成。
如果是長時間執行的工作,建議使用 Cloud Tasks。使用 Cloud Tasks 時,HTTP 要求會長時間存在,且只有在任何非同步工作結束後才會傳回回應。