排解 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 取得容器映像檔 URL,並套用 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_DIGEST,並使用 SHA256 值。
  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 應用程式的 keepAliveTimeout 為 5000 毫秒。在本例中,您可以將 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 彈性環境有 1 GB 的記憶體,其中只有 600 MB 可供應用程式容器使用。

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

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

如果等待連線數上限等於或大於有效連線數的 75%,應用程式可能會遇到 502 錯誤。

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