简体   繁体   English

AppEngine 部署找不到 Go 包

[英]AppEngine deploy cannot find Go packages

I have an AppEngine micro service setup in a monorepo, there is shared code between services so I've refactored to unify my go modules (they're really similar).我在 monorepo 中有一个 AppEngine 微服务设置,服务之间有共享代码,所以我已经重构以统一我的 go 模块(它们非常相似)。 The refactor works locally, builds and runs, and Goland compiles happily.重构在本地工作,构建并运行,Goland 编译愉快。 My issue is that AppEngine deploy no longer works, receiving erorrs such as:我的问题是 AppEngine 部署不再有效,收到如下错误:

Error message: cmd/main.go:4:2: cannot find package "github.com/gin-gonic/gin" in any of:
        /usr/local/go/src/github.com/gin-gonic/gin (from $GOROOT)
        /layers/google.go.appengine_gopath/gopath/src/github.com/gin-gonic/gin (from $GOPATH)
cmd/main.go:5:2: cannot find package "mymodulename/customer/internal/mypkg" in any of:
        /usr/local/go/src/mymodulename/customer/internal/cauth (from $GOROOT)
        /layers/google.go.appengine_gopath/gopath/src/mymodulename/customer/internal/mypkg (from $GOPATH)

Original structure原始结构

    > svc1
      > cmd/main.go
      > internal
         >utils/shared.go
         >mypkg
      > go.mod
      > app.yaml
    > svc2
      > cmd/main.go
      > internal
         >utils/shared.go
         >mypkg
      > go.mod
      > app.yaml

After refactor重构后

    > svc1
      > cmd/main.go
      > internal
         >mypkg
      > app.yaml
    > svc2
      > cmd/main.go
      > internal
         >mypkg
      > app.yaml
    > internal (common shared stuff)
      > utils/shared.go
    go.mod

Key points are utils/shared.go was moved to outside of each service directory and go.mod were unified.重点是utils/shared.go被移到了各个服务目录之外,go.mod被统一了。

What I'm unclear on is whether AppEngine builds the go binary on my local machine when i run glcoud app deploy or whether is bundles everything and runs it in cloud build.我不清楚的是,当我运行glcoud app deploy时,AppEngine 是否在我的本地机器上构建 go 二进制文件,或者是否捆绑所有内容并在云构建中运行它。

  1. How does AppEngine deploy work? AppEngine 部署如何工作?
  2. How do I get the AppEngine deploy to find my go.mod file?如何让 AppEngine 部署找到我的 go.mod 文件?
  3. How are the dependencies bundled?依赖项是如何捆绑的? (if it's running on CloudBuild surely it doesnt have access to private repos) (如果它在 CloudBuild 上运行,它肯定无权访问私有存储库)

To reply to your questions:回答您的问题:

How does AppEngine deploy work? AppEngine 部署如何工作?

  • Your source files are uploaded to Google Cloud Storage.您的源文件已上传到 Google Cloud Storage。 Cloud Build builds your app and deploys it to App Engine. Cloud Build 构建您的应用并将其部署到 App Engine。

How do I get the AppEngine deploy to find my go.mod file?如何让 AppEngine 部署找到我的 go.mod 文件?

  • You place your module's go.mod file in the same directory as your app.yaml file.您将模块的 go.mod 文件与 app.yaml 文件放在同一目录中。

How are the dependencies bundled?依赖项是如何捆绑的?

  • It is indeed running Cloud Build.它确实在运行 Cloud Build。 App Engine cannot download your private dependencies during the build process, so you must include them with your application code upon deployment. App Engine 无法在构建过程中下载您的私有依赖项,因此您必须在部署时将它们包含在您的应用程序代码中。 Details are to be found in the Using private dependencies paragraph of the "Specifying Dependencies" documentation page.详细信息可在“指定依赖项”文档页面的使用私有依赖项段落中找到。

Regarding refactoring of your file structure: the file structure needs to respect the prescriptions given in the Structuring your files paragraph:关于重构您的文件结构:文件结构需要尊重在构建您的文件段落中给出的规定:

  • go-app/: directory for your Go 1.11 service. go-app/:Go 1.11 服务的目录。
    • app.yaml: Your service's configuration settings. app.yaml:您的服务的配置设置。
    • main.go: Your application code. main.go:您的应用程序代码。

The solution I've reached for anyone else who has the same issue.我为其他有同样问题的人找到的解决方案。 A few truths seem to exist, though the docs are somewhat ambiguous about it.一些事实似乎存在,尽管文档对此有些模棱两可。 The docs say: 文档说:

Create your module's go.mod file in the same directory as your app.yaml file. App Engine searches the current directory, then successive parent directories until it finds a go.mod file.

But this does not seem to be true, infact, nothing seems to be copied at all above the app.yaml file.但这似乎不是真的,事实上,在 app.yaml 文件上方似乎根本没有复制任何内容。

So the solution requires:所以解决方案需要:

  1. Each microservice has a go.mod file of its own.每个微服务都有自己的 go.mod 文件。
  2. That go.mod file is in the same directory as the app.yaml该 go.mod 文件与 app.yaml 位于同一目录中
  3. go mod edit is used to tell the Go compiler to look locally rather than try and fetch via the internet. go mod edit用于告诉 Go 编译器在本地查找,而不是尝试通过 Internet 获取。
  4. Vendoring is used to bundle all dependencies in the same directory as app.yaml so they're deployed to AppEngine. Vendoring 用于将所有依赖项与 app.yaml 捆绑在同一目录中,以便将它们部署到 AppEngine。

A bit about local imports关于本地进口的一点

Go appears to look for everything first in the dependency cache / paths, but then entirely on the internet. Go 似乎首先在依赖项缓存/路径中查找所有内容,然后完全在 Internet 上查找。 If I created my local package using go mod init shared , its module name is 'shared'.如果我使用go mod init shared创建了我的本地包,它的模块名称是“共享”。 To tell Go that you want to import locally rather using the internet, invoke go mod edit -replace=shared=../../shared/ , you should see your go.mod gets a line like replace shared => ../../shared .要告诉 Go 你想在本地导入而不是使用互联网,调用go mod edit -replace=shared=../../shared/ ,你应该看到你的 go.mod 得到一行类似于replace shared => ../../shared If you're using Goland and it still isn't compiling, try File>Invalidate Caches/Restart...如果您正在使用 Goland 但它仍然无法编译,请尝试File>Invalidate Caches/Restart...

A bit about vendoring关于销售的一点

go mod vendor in your go.mod folder will bundle all dependendies, including local ones so they can be deployed by AppEngine. go.mod 文件夹中的go mod vendor将捆绑所有依赖项,包括本地依赖项,以便 AppEngine 部署它们。 This is also a good way to deal with private repos so you don't need to git Cloud Build access to your repo.这也是处理私有存储库的好方法,因此您无需通过 git Cloud Build 访问您的存储库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM