サポートされている第 2 世代の Go ランタイムにアップグレードする場合は、次の違いを考慮してください。
ランタイム移行の労力と複雑さを軽減するため、App Engine スタンダード環境では、Memcache など、以前のバンドル サービスや API の多くは第 2 世代ランタイムでも利用できるようになっています。第 2 世代の Go アプリは、App Engine SDK for Go を介してバンドル サービスの API を呼び出し、Go 1.11 ランタイムとほぼ同じ機能にアクセスできます。
以前のバンドル サービスと同様の機能を備えた Google Cloud プロダクトを使用することもできます。これらの Google Cloudプロダクトでは、慣用的な Go 用 Cloud クライアント ライブラリを使用できます。Google Cloudで独立したプロダクトとして使用できないバンドル サービス(画像処理、検索、メッセージングなど)の場合は、サードパーティ プロバイダまたはその他の回避策を使用できます。
main() 関数で、http.ListenAndServe() の代わりに appengine.Main() を呼び出します。これにより、user API と 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 UTC。"],[[["\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`."]]