При развертывании AppEngine не удается найти пакеты Go

У меня есть настройка микросервиса AppEngine в монорепозитории, между сервисами есть общий код, поэтому я провел рефакторинг для унификации моих модулей go (они действительно похожи). Рефакторинг работает локально, строится и запускается, и Goland успешно компилируется. Моя проблема в том, что развертывание 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)

Оригинальная структура

    > 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

После рефакторинга

    > 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

Ключевые моменты: utils / shared.go был перемещен за пределы каждого служебного каталога, а go.mod были унифицированы.

Я не понимаю, создает ли AppEngine двоичный файл go на моем локальном компьютере при запуске glcoud app deploy Или все это объединяет и запускает в облачной сборке.

  1. Как работает развертывание AppEngine?
  2. Как мне развернуть AppEngine, чтобы найти мой файл go.mod?
  3. Как связаны зависимости? (если он работает на CloudBuild, конечно, у него нет доступа к частным репозиториям)

2 ответа

Решение

Решение, которое я нашел для всех, у кого есть такая же проблема. Кажется, что существует несколько истин, хотя в документах это несколько двусмысленно. В документах говорится:

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.

Но это не похоже на правду, на самом деле, похоже, что ничего не копируется выше файла app.yaml.

Итак, решение требует:

  1. У каждого микросервиса есть собственный файл go.mod.
  2. Этот файл go.mod находится в том же каталоге, что и app.yaml.
  3. go mod edit используется, чтобы указать компилятору Go искать локально, а не пытаться получить через Интернет.
  4. Вендоринг используется для объединения всех зависимостей в том же каталоге, что и app.yaml, чтобы они были развернуты в AppEngine.

Немного о местном импорте

Кажется, что Go сначала ищет все в кэше / путях зависимостей, а затем полностью в Интернете. Если я создал свой локальный пакет, используя go mod init shared, его имя модуля - "общий". Чтобы сообщить Go, что вы хотите импортировать локально, а не через Интернет, вызовите go mod edit -replace=shared=../../shared/, вы должны увидеть, что ваш go.mod получит строку вроде replace shared => ../../shared. Если вы используете Goland, но он все еще не компилируется, попробуйте File>Invalidate Caches/Restart...

Немного о торговле

go mod vendorв папке go.mod будут объединены все зависимости, включая локальные, чтобы их можно было развернуть с помощью AppEngine. Это также хороший способ справиться с частными репозиториями, поэтому вам не нужно получать доступ к репозиторию git Cloud Build.

Чтобы ответить на ваши вопросы:

Как работает развертывание AppEngine?

  • Ваши исходные файлы загружены в Google Cloud Storage. Cloud Build создает ваше приложение и развертывает его в App Engine.

Как мне развернуть AppEngine, чтобы найти мой файл go.mod?

  • Вы помещаете файл go.mod вашего модуля в тот же каталог, что и файл app.yaml.

Как связаны зависимости?

  • На нем действительно работает Cloud Build. App Engine не может загрузить ваши частные зависимости в процессе сборки, поэтому вы должны включить их в код своего приложения при развертывании. Подробности можно найти в параграфе Использование частных зависимостей на странице документации "Определение зависимостей".

Что касается рефакторинга вашей файловой структуры: файловая структура должна соответствовать предписаниям, данным в параграфе " Структурирование ваших файлов":

  • go-app/: каталог службы Go 1.11.
    • app.yaml: параметры конфигурации вашего сервиса.
    • main.go: код вашего приложения.
Другие вопросы по тегам