# apiServer 微服务模板 基于 [CloudWego Hertz](https://github.com/cloudwego/hertz) 的 Go 微服务脚手架,集成 Nacos 服务注册/发现 + gRPC 客户端 + 访问日志上报(Redis → ES)+ 定时任务 + 事件 Hook 体系。 ## 项目结构 ``` ├── apps/ # 业务处理层 (Handler) ├── cmd/ │ ├── main_program/ # 主程序入口 (HTTP 服务) │ ├── cli_control/ # CLI 工具入口 (httplog 上报) │ └── scheduler/ # 定时任务调度器 (独立进程) ├── crontab/ # 定时任务框架 │ └── tasks/ # 具体任务实现 ├── hooks/ # 事件 Hook 体系 │ └── registers/ # Hook 注册入口 ├── middleware/ # HTTP 中间件 (Recovery, AccessLog, CORS) ├── models/ │ ├── database/ # 数据库连接 & ORM 模型 (GORM) │ └── request_models/ # 请求参数模型 ├── proto/ # Protobuf 生成代码 ├── routes/ # 路由定义 ├── utils/ │ ├── httplog/ # HTTP 访问日志采集 & ES 上报 │ ├── logger/ # 日志工具 (logrus,主服务/定时任务分离) │ ├── nacos/ # Nacos 服务注册/发现/配置 │ ├── redis_tools/ # Redis 连接 & 通用操作 │ ├── request/ # 请求绑定 & 统一响应 │ └── server_cli/ # gRPC 客户端 ├── deploy/ # systemd 服务单元 ├── start.sh / stop.sh / restart.sh / install.sh ├── .env.example # 环境变量示例 └── go.mod ``` ## 快速开始 ```bash # 1. 复制配置 cp .env.example .env # 编辑 .env 填入实际配置 # 2. 安装依赖 go mod tidy # 3. 开发运行 go run ./cmd/main_program # HTTP 服务 go run ./cmd/cli_control # httplog 上报 go run ./cmd/scheduler # 定时任务调度器 # 4. 构建 go build -ldflags="-s -w" -o server ./cmd/main_program go build -ldflags="-s -w" -o cli ./cmd/cli_control go build -ldflags="-s -w" -o scheduler ./cmd/scheduler ``` ## 模板使用步骤 1. 拉取该项目仓库 2. 复制 `.env.example` 为 `.env` 并修改配置 3. 全局替换 `apiServer_service` 为你的项目模块名 4. 修改 `go.mod` 中的 module 名称 5. 新建 Gitea 仓库,修改本地仓库地址 --- ## 模块说明 ### cmd/main_program — HTTP 主服务 启动 Hertz HTTP 服务,绑定路由和中间件,可选连接数据库、注册到 Nacos。 ```bash go run ./cmd/main_program ``` 启动流程:加载 `.env` → 校验 `HOST`/`PORT` → 连接数据库(可选)→ 注册中间件 → 绑定路由 → Nacos 注册(可选)→ HTTP 监听 → 等待信号优雅关闭。 ### cmd/cli_control — httplog 日志上报 独立后台进程,从 Redis 队列消费访问日志,批量写入 Elasticsearch。 ```bash go run ./cmd/cli_control ``` ### cmd/scheduler — 定时任务调度器 独立进程运行定时任务,使用专用日志文件 `logs/cron_*.log`。 ```bash go run ./cmd/scheduler # 常驻模式 go run ./cmd/scheduler list # 列出已注册任务 go run ./cmd/scheduler run-once # 立即执行所有任务一次 go run ./cmd/scheduler run 健康检查 # 立即执行指定任务 ``` ### crontab — 定时任务框架 基于 `robfig/cron` 的调度器,支持秒级 cron 表达式,内置 panic 恢复。 **新增任务三步走:** ```go // 1. 在 crontab/tasks/ 下新建文件,实现 Task 接口 type MyTask struct{} func (t *MyTask) Name() string { return "我的任务" } func (t *MyTask) Spec() string { return "0 */10 * * * *" } // 每10分钟 func (t *MyTask) Run() { logger.CronInfo("MyTask", "执行中...") } // 2. 在 crontab/tasks/register.go 注册 func RegisterTasks(scheduler *crontab.Scheduler) { scheduler.Register(&HealthCheckTask{}) scheduler.Register(&MyTask{}) // 新增 } // 3. 完成,scheduler 进程会自动调度 ``` 定时任务日志独立写入 `logs/cron_YYYYMMDD.log`,不与主服务日志混合。 ### hooks — 事件 Hook 体系 发布-订阅模式的业务事件系统,支持同步/异步处理和优先级排序。 **触发事件:** ```go import "apiServer_service/hooks" hooks.DefaultManager().Trigger(ctx, hooks.EventType("order_paid"), &hooks.EventPayload{ UserID: 123, Extra: map[string]any{"order_id": 456, "amount": 99.9}, }) ``` **注册 Handler:** ```go // hooks/registers/register.go func RegisterHooks(m *hooks.Manager) { // 同步处理(按优先级顺序执行,阻塞直到完成) m.Register(hooks.EventType("order_paid"), hooks.HandlerFunc(OnOrderPaid)) // 异步处理(不阻塞主流程) m.RegisterAsync(hooks.EventType("order_paid"), hooks.HandlerFunc(SendNotification)) // 指定优先级(数值越大越先执行) m.RegisterWithPriority(hooks.EventType("order_paid"), 10, hooks.HandlerFunc(DeductInventory)) } func OnOrderPaid(ctx context.Context, event hooks.EventType, payload *hooks.EventPayload) error { // 业务逻辑 return nil } ``` **特性:** | 能力 | 说明 | |------|------| | 同步执行 | `Register` — 按优先级顺序执行,阻塞调用方 | | 异步执行 | `RegisterAsync` — goroutine 执行,不阻塞 | | 优先级 | `RegisterWithPriority` — 数值越大越先执行 | | panic 安全 | 异步 handler panic 不影响主流程 | | 函数适配 | `HandlerFunc` 可直接用匿名函数注册 | ### middleware — HTTP 中间件 在 `cmd/main_program/routs.go` 中统一注册: ```go r.Use(middleware.Recovery()) // panic 恢复 r.Use(middleware.AccessLog()) // 请求日志 r.Use(middleware.CORS()) // 跨域支持 ``` ### models/database — 数据库 (GORM) 支持 MySQL 和 PostgreSQL,`DB_TYPE` 为空时跳过连接。 ```go import db "apiServer_service/models/database" db.GetDB().Where("parent_id = ?", 0).Find(&groups) db.GetDB().Create(&db.HostGroup{Name: "生产环境"}) ``` 新增模型在 `models/database/` 下定义结构体,在 `init.go` 的 `Migrate()` 中注册。 ### utils/httplog — 访问日志采集 Hertz Tracer 实现,采集访问事件通过 Redis List 异步缓冲,由 `cli` 进程批量写入 ES。 ```go rdb := redis_tools.ConnectRedis() tracer := httplog.NewRedisAccessLogTracer(rdb, "access_log", "my-service", httplog.WithSkipPrefix("/health"), httplog.WithMaxResponseBody(4096), httplog.WithUserIDExtractor(func(c *app.RequestContext) uint { return 0 }), ) h := server.Default(server.WithTracer(tracer)) ``` ### utils/redis_tools — Redis 工具 ```go redis_tools.SetCache("key", "value", 10*time.Minute) val, _ := redis_tools.GetCache("key") redis_tools.Del("key1", "key2") redis_tools.Exists("key") redis_tools.AddToList("queue", "item") ``` ### utils/nacos — Nacos 服务注册/发现/配置 ```go nacos.RegisterService() instance, _ := nacos.DiscoverService("user-service") content := nacos.GetConfig("app.yaml", "DEFAULT_GROUP") ``` ### utils/server_cli — gRPC 客户端 ```go err := server_cli.ReportVisit(token, note, ip, os, point, userId) defer server_cli.CloseGrpcConn() ``` ### utils/request — 请求绑定 & 统一响应 ```go request.BindRequestStruct(c, &req) // 失败自动 400 request.Success(c, data) // 200 request.BadRequest(c, "参数错误") // 400 request.Unauthorized(c, "未登录") // 401 request.NotFound(c, "不存在") // 404 request.Error(c, 500, "错误") // 自定义 request.FileResponse(c, path, name) // 文件下载 ``` ### routes — 路由定义 ```go func SetupRoutes(r *server.Hertz) { r.Use(middleware.Recovery(), middleware.AccessLog(), middleware.CORS()) api := r.Group("/api") { routes.RegisterIndexRoutes(api) // routes.RegisterUserRoutes(api) // 新增模块在此注册 } } ``` --- ## 生产部署 ### 构建 ```bash go build -ldflags="-s -w" -o server ./cmd/main_program go build -ldflags="-s -w" -o cli ./cmd/cli_control go build -ldflags="-s -w" -o scheduler ./cmd/scheduler ``` ### 首次安装(systemd 服务注册) ```bash chmod +x install.sh start.sh stop.sh restart.sh server cli scheduler sudo bash install.sh ``` ### 日常运维 ```bash bash start.sh # 启动全部 (server + cli + scheduler) bash stop.sh # 停止全部 bash restart.sh # 重启全部 ``` 单独管理: ```bash systemctl status server # 主服务状态 systemctl status scheduler # 调度器状态 systemctl restart scheduler # 只重启调度器 journalctl -u server -f # 主服务实时日志 journalctl -u scheduler -f # 调度器实时日志 ``` ### systemd 服务特性 | 特性 | 说明 | |------|------| | 开机自启 | `install.sh` 执行后自动启用 | | 崩溃自动重启 | `Restart=always`,server 3s / cli 5s / scheduler 5s | | 优雅关闭 | `SIGTERM`,server 10s / scheduler 15s 超时 | | 环境变量 | `EnvironmentFile` 加载 `.env` | | 文件描述符 | `LimitNOFILE=65536` | ### 部署目录结构 ``` /root/ ├── server # HTTP 主服务 ├── cli # httplog 上报 ├── scheduler # 定时任务调度器 ├── .env # 环境配置 ├── deploy/ │ ├── server.service │ ├── cli.service │ └── scheduler.service ├── install.sh / start.sh / stop.sh / restart.sh └── logs/ ├── server.out # 主服务输出 ├── cli.out # httplog 输出 ├── scheduler.out # 调度器输出 └── cron_*.log # 定时任务专用日志 ``` ## 内置功能清单 - Hertz HTTP 框架 + 路由分组 - Recovery / AccessLog / CORS 中间件 - 统一 JSON 响应格式 + 参数绑定校验 - GORM 数据库(MySQL / PostgreSQL,自动迁移) - 事件 Hook 体系(同步/异步、优先级、发布-订阅) - 定时任务调度器(秒级 cron、独立进程、专用日志) - HTTP 访问日志采集 → Redis 缓冲 → ES 批量上报 - Redis 工具(单例连接池) - Nacos 服务注册、发现、配置管理 - gRPC 客户端(连接复用) - 彩色日志 + 文件日志(主服务/定时任务分离) - 优雅关闭 (Graceful Shutdown) - systemd 服务管理(开机自启 + 崩溃自动重启)