排解 App Engine 中的放送問題

本頁面說明 App Engine 中常見的應用程式初始化和服務錯誤,以及排解這些錯誤的方法。

使用預設服務帳戶建立應用程式時發生權限錯誤

首次啟用 App Engine API 後建立應用程式時,可能會發生下列錯誤:

gcloud CLI

An internal error occurred while calling service consumer manager for service account.
Creating  App Engine application in projectPROJECT and REGION....failed. DEBUG: (gcloud.app.create) Error Response: [13] an internal error has occurred

要求記錄

Service account creation is not allowed on this project.

主控台

Error while initialising App Engine.

建立應用程式時,如果強制執行機構政策限制 constraints/iam.disableServiceAccountCreation,就可能發生這個錯誤。這項政策會防止提供 App Engine 預設服務帳戶 PROJECT_ID@appspot.gserviceaccount.com

如要解決這個問題,您必須暫時移除機構政策限制 constraints/iam.disableServiceAccountCreation,才能建立及部署 App Engine 預設服務帳戶。預設服務帳戶是建立應用程式時的必要項目,無法略過。這項做法也適用於使用個別版本服務帳戶的情況。您可以刪除 App Engine 預設服務帳戶,或在成功部署後,以您建立的服務帳戶取代。

如果您使用的是自己建立的服務帳戶,請參閱「角色建議總覽」,瞭解如何強制執行限制權限,例如為服務代理建立的服務帳戶提供符記建立者角色。

應用程式未提供最新的程式碼變更

如果應用程式在部署後未提供最新的程式碼變更,您可以使用容器的根檔案系統檢查內容。以下疑難排解步驟說明如何擷取容器映像檔,以及匯出根目錄檔案系統以供進一步分析:

  1. 使用 Cloud Logging 搭配篩選器 GAE_FULL_APP_CONTAINER 取得容器映像檔網址。套用篩選器後,Cloud Logging 會顯示容器映像檔網址,以及完整網域名稱 (FQDN)。例如:GAE_FULL_APP_CONTAINER: FQDN/PROJECT_ID/appengine/SERVICE_NAME.VERSION_ID@sha256:SHA256_DIGEST

  2. 執行下列指令,匯出容器映像檔網址:

    export IMAGE_URL='FQDN/PROJECT_ID/appengine/SERVICE_NAME.VERSION_ID@sha256:SHA256_DIGEST'
    

    取代:

    • FQDN 與容器映像檔網址的完整網域名稱。
    • PROJECT_ID 替換為 Google Cloud 專案的專案 ID。
    • SERVICE_NAME 改為您的服務名稱。
    • VERSION_ID 替換為服務的版本 ID。
    • SHA256_DIGESTSHA256 值。
  3. 使用容器映像檔網址建立新容器:

    docker pull ${IMAGE_URL}
    export CONTAINER_ID=$(docker create ${IMAGE_URL})
    docker ps -a # the list should contain the newly created container with status `Created`
    
  4. 匯出容器映像檔的根檔案系統 (rootfs):

     docker export ${CONTAINER_ID} -o gae_app.tar
     mkdir gae_app
     mv -v gae_app.tar gae_app/
     cd gae_app/
     tar -xf gae_app.tar
     ls -la # inspect the container FS
    

    或者,如果您不需要 TAR 檔案,請執行下列指令:

      mkdir gae_app
      cd gae_app/
      docker export ${CONTAINER_ID} | tar -xC <dest>
      ls -la # inspect the container FS
    

    分析根檔案系統的內容,確認是否有最新的程式碼變更。

  5. 執行下列指令來清理映像檔:

    docker container rm ${CONTAINER_ID}
    docker image rm ${IMAGE_URL}
    unset IMAGE_URL CONTAINER_ID
    

Nginx 無法連線或聯絡應用程式容器

以下錯誤只會發生在 App Engine 彈性環境中,且通常會在錯誤發生後立即傳回 502 錯誤:

recv() failed (104: Connection reset by peer) while reading response header from upstream

這個錯誤表示 nginx 反向 Proxy (nginx sidecar) 無法連線至應用程式容器。在記錄中,您可以比較 nginx 記錄中 502 錯誤的關閉時間,以及 nginx.error 記錄的時間。在 nginx.error 後立即出現 502 nginx 錯誤,可能是 nginx 502 錯誤的原因。

當應用程式連線保持連線逾時時間小於 nginx 的保持連線逾時時間時,通常會發生這個錯誤。由於 App Engine 彈性環境中的 nginx 有 keepalive_timeout 650 秒,因此應用程式需要至少維持這麼長的連線時間。根據預設,Node.js 應用程式具有 5000 毫秒的 keepAliveTimeout。在這種情況下,您可以將 server.keepAliveTimeout 設為 700000 毫秒。

如要排解問題,請連線至 VM 執行個體,檢查在應用程式容器中執行的程式碼所寫入的記錄,並視需要新增更多記錄,找出問題的根本原因。

記憶體不足

下列記憶體不足錯誤會在 App Engine 彈性環境中發生,通常會傳回 502 錯誤:

kernel: [  133.706951] Out of memory: Kill process 4490 (java) score 878 or sacrifice child
kernel: [  133.714468] Killed process 4306 (java) total-vm:5332376kB, anon-rss:2712108kB, file-rss:0kB

這個錯誤表示 App Engine 已終止應用程式。

當執行個體的記憶體不足時,就會發生這個錯誤。根據預設,App Engine 彈性環境有 1GB 的記憶體,其中只有 600MB 是供應用程式容器使用。

如要排解問題,請檢查記錄檔是否有記憶體不足的項目,並更新 app.yaml 檔案中的 memory_gb 設定,然後重新部署。

開放連線不足,無法處理傳入要求

如果等待連線的數量等於或大於有效連線數量的 75%,應用程式可能會發生 502 錯誤。

如要解決這個問題,請檢查 Cloud Monitoring 指標,查看有效和等待連線的上限數量,並減少等待連線的數量,確保等待連線的上限數量小於或等於有效連線數量的 75%。