6.1 项目结构
标准项目布局
project/
├── cmd/ # 应用程序入口
│ ├── myapp/
│ │ └── main.go
│ └── migration/
│ └── main.go
├── internal/ # 私有包
│ ├── config/
│ ├── handler/
│ ├── service/
│ ├── repository/
│ └── models/
├── pkg/ # 公共包
│ ├── logger/
│ ├── utils/
│ └── middleware/
├── api/ # API 定义
│ ├── openapi.yaml
│ └── proto/
├── configs/ # 配置文件
├── scripts/ # 脚本文件
├── deployments/ # 部署配置
│ ├── Dockerfile
│ └── k8s/
├── test/ # 测试文件
├── docs/ # 文档
├── go.mod
├── go.sum
├── Makefile
└── README.mdcmd 目录示例
go
// cmd/myapp/main.go
package main
import (
"context"
"flag"
"os"
"os/signal"
"syscall"
"time"
"example.com/myapp/internal/config"
"example.com/myapp/internal/handler"
"example.com/myapp/pkg/logger"
)
var version = "dev"
func main() {
// 命令行参数
var configFile string
flag.StringVar(&configFile, "config", "configs/config.yaml", "配置文件路径")
flag.Parse()
// 初始化日志
log := logger.NewLogger()
// 加载配置
cfg, err := config.Load(configFile)
if err != nil {
log.Error("加载配置失败", "error", err)
os.Exit(1)
}
// 初始化服务
userService := service.NewUserService(cfg.Database)
userHandler := handler.NewUserHandler(userService)
// 启动服务器
server := handler.NewServer(cfg.Server, userHandler)
// 优雅关闭
ctx, stop := signal.NotifyContext(context.Background(),
os.Interrupt, syscall.SIGTERM)
defer stop()
go func() {
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
server.Shutdown(shutdownCtx)
}()
if err := server.Start(); err != nil {
log.Error("服务器启动失败", "error", err)
os.Exit(1)
}
}配置管理 (viper)
go
import "github.com/spf13/viper"
type Config struct {
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
JWT JWTConfig `mapstructure:"jwt"`
}
func Load(configPath string) (*Config, error) {
v := viper.New()
v.SetConfigFile(configPath)
v.SetEnvPrefix("APP")
v.AutomaticEnv()
if err := v.ReadInConfig(); err != nil {
return nil, err
}
var cfg Config
if err := v.Unmarshal(&cfg); err != nil {
return nil, err
}
return &cfg, nil
}yaml
# configs/config.yaml
server:
port: 8080
read_timeout: 30
database:
host: localhost
port: 5432
user: postgres
password: secret
dbname: myapp