為減少執行階段遷移作業的負擔和複雜度,App Engine 標準環境可讓您在第二代執行階段中存取許多舊版套裝服務和 API,例如 Memcache。第二代 Go 應用程式可透過 Go 適用的 App Engine SDK 呼叫套裝組合服務 API,並存取與 Go 1.11 執行階段相同的大部分功能。
您也可以選擇使用 Google Cloud 產品,這些產品提供的功能與舊版服務套裝組合類似。這些產品提供慣用的 Go 適用的 Cloud 用戶端程式庫。對於Google Cloud中未以獨立產品形式提供的套裝服務 (例如圖片處理、搜尋和訊息),您可以改用第三方供應商或其他解決方法。 Google Cloud
在 main() 函式中,請呼叫 appengine.Main(),而非 http.ListenAndServe()。確保 user 和 appengine API 可以存取目前的要求情境。
編寫 main 套件
如果您的服務尚未包含 main 套件,請新增 package main 陳述式並編寫 main() 函式。main() 函式「至少」應:
讀取 PORT 環境變數並呼叫 http.ListenAndServe() 函式:
port:=os.Getenv("PORT")ifport==""{port="8080"log.Printf("Defaulting to port %s",port)}log.Printf("Listening on port %s",port)iferr:=http.ListenAndServe(":"+port,nil);err!=nil{log.Fatal(err)}
註冊 HTTP 處理常式
您可以透過下列其中一個選項註冊 HTTP 處理常式:
建議使用的方法為手動將所有 http.HandleFunc() 呼叫從您的套件移至 main 套件的 main() 函式。
或者,將應用程式的套件匯入您的 main 套件,確保每個 init() 函式 (當中包含 http.HandleFunc()) 都能在啟動時執行。
您可以透過下列的 bash 指令碼找到使用 http.HandleFunc() 呼叫的所有套件,並將輸出內容複製到 main 套件的 import 區塊:
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["難以理解","hardToUnderstand","thumb-down"],["資訊或程式碼範例有誤","incorrectInformationOrSampleCode","thumb-down"],["缺少我需要的資訊/範例","missingTheInformationSamplesINeed","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-09-04 (世界標準時間)。"],[[["\u003cp\u003eThis guide provides instructions for migrating applications from first-generation to supported second-generation Go runtimes on App Engine, including changes to \u003ccode\u003eapp.yaml\u003c/code\u003e, memory and CPU usage, and request headers.\u003c/p\u003e\n"],["\u003cp\u003eGo 1.11 reached its end of support on January 30, 2024, and while existing applications will continue to run, redeployment might be blocked; thus, it is recommended to migrate to the latest supported Go runtime.\u003c/p\u003e\n"],["\u003cp\u003eSecond-generation runtimes allow access to many legacy bundled services via the App Engine SDK, but some are not available, requiring the use of alternative Google Cloud products, third-party services, or other workarounds.\u003c/p\u003e\n"],["\u003cp\u003eMigrating to a second-generation Go runtime requires creating a \u003ccode\u003emain\u003c/code\u003e package, and registering your HTTP handlers either by manually moving \u003ccode\u003ehttp.HandleFunc()\u003c/code\u003e calls or importing packages with \u003ccode\u003einit()\u003c/code\u003e functions.\u003c/p\u003e\n"],["\u003cp\u003eUpgrading may involve managing increased baseline memory and CPU usage, avoiding underscores in request headers, and adjusting the \u003ccode\u003eapp.yaml\u003c/code\u003e file's \u003ccode\u003eapp_engine_apis\u003c/code\u003e, \u003ccode\u003elogin\u003c/code\u003e, and \u003ccode\u003eruntime\u003c/code\u003e elements.\u003c/p\u003e\n"]]],[],null,["# Migrate from Go 1.11 to the latest Go runtime\n\nThis page covers instructions for migrating from the\n[first-generation to the second-generation](/appengine/docs/standard/runtimes)\nGo runtimes. To upgrade your second-generation app to use the latest supported\nversion of Go, see [Upgrade an existing application](/appengine/docs/standard/go/upgrade-go-runtime).\n\nGo 1.11 has reached [end of support](/appengine/docs/standard/lifecycle/runtime-lifecycle#end_of_support)\non January 30, 2024. Your existing Go 1.11 applications will continue\nto run and receive traffic. However, App Engine might block re-deployment of applications\nthat use runtimes [after their end of support date](/appengine/docs/standard/lifecycle/support-schedule#go).\nWe recommend that you migrate to the [latest supported runtime](/appengine/docs/standard/lifecycle/support-schedule#go) of Go by using the\nguidelines in this page.\n\nMigrating to a [supported second-generation Go runtime](/appengine/docs/standard/runtimes)\nlets you use up-to-date language\nfeatures and build apps that are more portable, with idiomatic code.\n\nChanges in the second-generation runtimes\n-----------------------------------------\n\nConsider the following differences when upgrading to a [supported](/appengine/docs/standard/lifecycle/support-schedule#go) second-generation Go runtime:\n\n- To reduce runtime migration effort and complexity, the App Engine standard environment lets you\n [access many of the legacy bundled services and APIs in the second-generation\n runtimes](/appengine/docs/standard/go/services/access), such as Memcache.\n Your second-generation Go app can call the bundled services APIs through the\n App Engine SDK for Go, and access most of the same features as on the\n Go 1.11 runtime.\n\n | **Note:** Not all the App Engine bundled services available for Go 1.11 have a corresponding service in the second-generation runtimes. For the full list of available legacy bundled services APIs in the second-generation runtimes, see the [legacy bundled services API references documentation](/appengine/docs/standard/go/services/access).\n\n You also have the option to use Google Cloud products that offer\n similar features as the legacy bundled services. These Google Cloud\n products provide idiomatic [Cloud Client Libraries for Go](https://github.com/googleapis/google-cloud-go).\n For the bundled services that are not available as separate products in\n Google Cloud, such as image processing, search, and messaging, you can\n use third-party providers or other workarounds.\n\n To learn more about migrating to unbundled services, see\n [Migrating from bundled services](/appengine/migration-center/standard/services/migrating-services).\n- The behavior of some elements in the `app.yaml` configuration file has been\n modified. For more information, see [Changes to the `app.yaml` file](#app-yaml).\n\n- Logging in the second-generation runtime follows the logging standard in\n [Cloud Logging](/logging). In the second-generation runtimes,\n app logs are no longer bundled with the request logs but are separated in\n different records. To learn more about reading and writing logs in the\n second-generation runtimes, see the [logging guide](/appengine/docs/standard/writing-application-logs).\n\n### Memory usage differences\n\nSecond-generation runtimes see a higher baseline of memory usage compared\nto first-generation runtimes. This is due to multiple factors, such as different\nbase image versions, and differences in how the two generations calculate memory\nusage.\n\nSecond-generation runtimes calculate instance memory usage as the sum of what an\napplication process uses, and the number of application files dynamically cached\nin memory. To avoid memory-intensive applications from experiencing instance\nshutdowns due to exceeding memory limits, upgrade to a larger\n[instance class](/appengine/docs/standard#instance_classes) with more memory.\n\n### CPU usage differences\n\nSecond-generation runtimes can see a higher baseline of CPU usage upon instance\ncold-start. Depending on an application's scaling configuration, this might have\nunintended side effects, such as, a higher instance count than anticipated if an\napplication is configured to scale based on CPU utilization. To avoid this\nissue, review and test application scaling configurations to ensure the number\nof instances are acceptable.\n\n### Request header differences\n\nFirst-generation runtimes allow request headers with underscores\n(e.g. `X-Test-Foo_bar`) to be forwarded to the application. Second-generation\nruntimes introduces Nginx into the host architecture. As a result of this\nchange, second-generation runtimes are configured to automatically remove\nheaders with underscores (`_`). To prevent application issues, avoid using\nunderscores in application request headers.\n\nChanges to the `app.yaml` file\n------------------------------\n\nThe behavior of some elements in the `app.yaml` configuration file has been\nmodified:\n\nFor more information, see the\n[`app.yaml` reference](/appengine/docs/standard/reference/app-yaml).\n\nCreate a `main` package\n-----------------------\n\nYour service must include a `package main` statement in at least one source\nfile.\n\n### App Engine legacy bundled services\n\nIf your service uses the\n[legacy bundled services\nfor the second-generation runtimes](/appengine/docs/standard/go/services/access):\n\n- Your service must only use v2 (`google.golang.org/appengine/v2`) packages.\n Using the older v1 (`google.golang.org/appengine`) packages causes errors.\n\n- In your `main()` function, call `appengine.Main()` instead of\n `http.ListenAndServe()`. This ensures that the `user` and `appengine`\n APIs have access to current request context.\n\n### Writing a main package\n\nIf your service doesn't already contain a `main` package, add the\n`package main` statement and write a `main()` function. At a **minimum** ,\nthe `main()` function should:\n\n- Read the `PORT` environment variable and call the `http.ListenAndServe()`\n function:\n\n port := os.Getenv(\"PORT\")\n if port == \"\" {\n \tport = \"8080\"\n \tlog.Printf(\"Defaulting to port %s\", port)\n }\n\n log.Printf(\"Listening on port %s\", port)\n if err := http.ListenAndServe(\":\"+port, nil); err != nil {\n \tlog.Fatal(err)\n }\n\n### Registering your HTTP handlers\n\nYou can register your HTTP handlers by choosing **one** of the following\noptions:\n\n- The preferred method is to manually move all `http.HandleFunc()` calls from your packages to your `main()` function in your `main` package.\n- Alternatively, import your application's packages into your `main` package,\n ensuring each `init()` function that contains calls to `http.HandleFunc()`\n gets run on startup.\n\n You can find all packages which use the `http.HandleFunc()` call with the\n following bash script, and copy the output into your `main` package's\n `import` block: \n\n gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#\"$gp/src/\"} && find . -name \"*.go\" | xargs grep \"http.HandleFunc\" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed \"s#\\./\\(.*\\)/[^/]\\+\\.go#\\t_ \\\"$pkg/\\1\\\"#\" | sort | uniq\n\nStructuring your files\n----------------------\n\nGo requires each package has its own directory. You can tell\nApp Engine where your `main` package is by using `main:` in your\nproject's `app.yaml` file. For example, if your app's file structure looked\nlike this: \n\n```\nmyapp/\n├── app.yaml\n├── foo.go\n├── bar.go\n└── web/\n └── main.go\n```\n\nYour `app.yaml` file would have: \n\n main: ./web # Relative filepath to the directory containing your main package.\n\nFor more information about the `main` flag, see the [`app.yaml`\nreference](/appengine/docs/standard/go/config/appref#main).\n\nMoving files to your `GOPATH`\n-----------------------------\n\nFind your `GOPATH` by using the following command: \n\n go env GOPATH\n\nMove all relevant files and imports to your `GOPATH`. If using relative\nimports, such as `import ./guestbook`, update your imports to use the full\npath: `import github.com/example/myapp/guestbook`."]]