Go 1.15 现已正式发布。

将 App Engine 应用迁移至 Go 1.12+

了解如何在 App Engine 标准环境中将现有 App Engine 应用从 Go 1.11 运行时迁移到 Go 1.12+ 运行时。

App Engine Go 1.12+ 运行时中的更改

为使用 App Engine Go 1.12+ 运行时,您可以对现有 App Engine Go 应用和部署流程进行更改。以下是新运行时的主要不同之处:

从 App Engine Go SDK 迁移

appengine 软件包和 google.golang.org/appengine 软件包不再受支持。您必须迁移到 Google Cloud 客户端库才能访问等效 Google Cloud 服务:

app.yaml 文件的更改

修改了 app.yaml 配置文件中某些元素的行为:

元素 更改类型 说明
runtime 修改后 更改 runtime 元素以指定 Go 1.12 或更高版本
login 已弃用 Go 1.12+ 运行时不支持 login。您必须使用其他方法对用户进行身份验证

如需了解详情,请参阅 app.yaml 参考文档

创建 main 软件包

您的服务必须至少在一个源文件中包含 package main 语句。 或者,如果您的服务使用的是 google.golang.org/appengine 软件包,则调用 appengine.Main()

编写 main 软件包

如果您的服务尚不包含 main 软件包,请添加 package main 语句并编写 main() 函数。main() 函数至少应该:

  • 读取 PORT 环境变量并调用 http.ListenAndServe() 函数:

    port := os.Getenv("PORT")
    if port == "" {
    	port = "8080"
    	log.Printf("Defaulting to port %s", port)
    }
    
    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
    	log.Fatal(err)
    }

注册 HTTP 处理程序

您可以通过以下任一方案来注册 HTTP 处理程序:

  • 首选方法是手动将您的软件包中的所有 http.HandleFunc() 调用移入您的 main 软件包中的 main() 函数。
  • 另一种方法是将应用的软件包导入 main 软件包,并确保每个 init() 函数(包含对 http.HandleFunc() 的调用)在启动时运行。

    您可以通过以下 bash 脚本找到所有使用 http.HandleFunc() 调用的软件包,并将输出复制到 main 软件包的 import 块中:

    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
    

构建文件

Go 要求每个软件包都有自己的目录。您可以通过在项目的 app.yaml 文件中使用 main: 来辨认 App Engine main 软件包的位置。例如,如果您的应用的文件结构如下所示:

myapp/
├── app.yaml
├── foo.go
├── bar.go
└── web/
    └── main.go

您的 app.yaml 文件将包含:

main: ./web # Relative filepath to the directory containing your main package.

如需详细了解 main 标志,请参阅 app.yaml 参考文档

将文件移动到 GOPATH

使用以下命令查找您的 GOPATH

go env GOPATH

将所有相关文件和导入内容移动到 GOPATH。如果使用相对导入(例如 import ./guestbook),请将您的导入命令更新为使用完整路径:import github.com/example/myapp/guestbook