Golang多可执行文件项目的结构设计

Golang多可执行文件项目的结构设计 我正在尝试用Go构建一个微服务架构项目。目前使用的是支持模块的Go 1.11版本,因此我将根目录放在了GOPATH之外的自选目录中。

如果我对微服务架构概念的理解正确的话,虽然我的微服务需要保持独立,但它们可以共享依赖项(而且我认为没有其他实现方式,对吗?)

以下是我的目录结构:

.
├── go.mod
├── lambda
│   └── account_create
│       └── main.go
├── readme.md
└── types
    ├── account.go
    ├── location.go
    ├── order.go
    ├── pricing.go
    ├── product.go
    └── types.go

我期望的行为是能够运行go build lambda/account_create并获取具有该功能的可执行文件,以便将其提供给相应的AWS Lambda函数。

然而,当我运行该命令时,出现以下错误:

can't load package: package lambda/account_create: unknown import path "lambda/account_create": cannot find module providing package lambda/account_create

请解释为什么这不起作用,并就此类项目的正确结构给我一些建议。

非常感谢!


更多关于Golang多可执行文件项目的结构设计的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

为什么使用vendor?他使用的是Go 1.11。

更多关于Golang多可执行文件项目的结构设计的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


尝试在项目根目录使用 vendor 文件夹,如下所示:

├── vendor
│   └── lambda
│           └── account_create
│                   └── main.go

并在主文件或其他文件中添加:

import "lambda/account_create"

你的 go.mod 文件中的模块名是什么?

顺便说一句(与这个问题无关),你的包名不符合 Go 命名规范:

其他语言中典型的命名风格在 Go 程序中可能并不惯用。以下是两个在其他语言中可能是良好风格但在 Go 中不太合适的命名示例:

computeServiceClient
priority_queue

https://blog.golang.org/package-names

我忽略了这一点。我尝试了以下简单的示例,它可以正常工作。

文件夹结构(假设位于 $HOME 目录下):

├── $HOME
│   └── projects
│          └── lambda
│                  ├── account_create
│                  |      └── main.go
│                  └──  main.go

projects/lambda/account_create/main.go

package account_create

func A() {
    println("Hello from account_create")
}

projects/lambda/main.go

package main

import "projects/lambda/account_create"

func main() {
    account_create.A()
    println("Hello from main")
}

创建 go.mod 文件。不要错过这一步,否则无法工作。

cd $HOME/projects/lambda
go mod init projects/lambda

编译并运行示例:

go build
./lambda
Hello from account_create
Hello from main

当然,您可以根据需要进行调整。也可以阅读 Dave Cheney 关于模块的简短文章

在Go模块项目中,子目录中的可执行文件需要有自己的go.mod文件才能正确构建。以下是解决方案:

问题分析

当你在项目根目录运行go build lambda/account_create时,Go工具链期望找到一个有效的Go模块。但lambda/account_create目录没有自己的go.mod文件,因此无法被识别为独立的包。

解决方案

方案1:为每个Lambda函数创建独立模块

# 项目根目录结构
.
├── go.mod
├── lambda/
│   └── account_create/
│       ├── go.mod
│       └── main.go
├── types/
│   ├── account.go
│   ├── location.go
│   └── types.go
└── readme.md

lambda/account_create/go.mod中:

module myproject/lambda/account_create

go 1.11

require (
    myproject v0.0.0
)

replace myproject => ../..

在项目根目录的go.mod中:

module myproject

go 1.11

方案2:使用多模块工作区(Go 1.18+)

如果你使用Go 1.18或更高版本:

# 初始化工作区
go work init
go work use ./lambda/account_create

lambda/account_create/go.mod中:

module myproject/lambda/account_create

go 1.18

方案3:从子目录构建

进入子目录进行构建:

cd lambda/account_create
go build

或者使用相对路径:

go build ./lambda/account_create

完整示例

项目根目录go.mod

module myproject

go 1.11

types/account.go

package types

type Account struct {
    ID       string
    Name     string
    Email    string
}

lambda/account_create/go.mod

module myproject/lambda/account_create

go 1.11

require myproject v0.0.0

replace myproject => ../..

lambda/account_create/main.go

package main

import (
    "fmt"
    "myproject/types"
)

func main() {
    account := types.Account{
        ID:    "123",
        Name:  "John Doe",
        Email: "john@example.com",
    }
    fmt.Printf("Created account: %+v\n", account)
}

构建命令:

cd lambda/account_create
go build

或者从项目根目录:

go build -o bin/account_create ./lambda/account_create

这种结构允许每个微服务独立构建和部署,同时共享公共的类型定义和工具函数。

回到顶部