Files
apiServer-service/README.md
T

356 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
go build -ldflags="-s -w" -o initializer .
```
## 模板使用步骤
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 服务注册)
`initializer` 已内置 `.env.example``install.sh`、启停脚本和 `deploy/*.service`。将它与三个业务二进制放到部署目录后执行:
```bash
chmod +x initializer server cli scheduler
sudo ./initializer
# 请输入项目前缀(例如 myapp
```
初始化工具会自动释放部署文件、添加执行权限、把前缀保存到 `.service-prefix`,并在 `.env` 不存在时根据 `.env.example` 自动创建它,随后执行 `install.sh`。已有 `.env` 会被保留,不会覆盖其中的密钥和环境配置。注册出的服务名为 `myapp-server``myapp-cli``myapp-scheduler`
无人值守初始化时可直接传入前缀:
```bash
sudo ./initializer -prefix myapp
```
### 日常运维
```bash
bash start.sh # 启动全部 (server + cli + scheduler)
bash stop.sh # 停止全部
bash restart.sh # 重启全部
```
单独管理:
```bash
systemctl status myapp-server # 主服务状态
systemctl status myapp-scheduler # 调度器状态
systemctl restart myapp-scheduler # 只重启调度器
journalctl -u myapp-server -f # 主服务实时日志
journalctl -u myapp-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 # 定时任务调度器
├── initializer # 首次安装工具(内置部署资源)
├── .env # 环境配置
├── .service-prefix # 初始化时保存的 systemd 服务名前缀
├── 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 # 定时任务专用日志
```
CI 会将 `server``cli``scheduler``initializer` 打包为 `deployment.tar.gz` 后上传。部署目录由工作流顶部的 `DEPLOY_DIR` 统一配置(默认 `/root`)。压缩包上传完成后,服务器依次执行 `stop.sh`、覆盖解压、添加执行权限和 `start.sh`;启停脚本会读取 `.service-prefix` 操作带项目前缀的三个服务。首次部署前需要先运行一次 `initializer`
## 内置功能清单
- Hertz HTTP 框架 + 路由分组
- Recovery / AccessLog / CORS 中间件
- 统一 JSON 响应格式 + 参数绑定校验
- GORM 数据库(MySQL / PostgreSQL,自动迁移)
- 事件 Hook 体系(同步/异步、优先级、发布-订阅)
- 定时任务调度器(秒级 cron、独立进程、专用日志)
- HTTP 访问日志采集 → Redis 缓冲 → ES 批量上报
- Redis 工具(单例连接池)
- Nacos 服务注册、发现、配置管理
- gRPC 客户端(连接复用)
- 彩色日志 + 文件日志(主服务/定时任务分离)
- 优雅关闭 (Graceful Shutdown)
- systemd 服务管理(开机自启 + 崩溃自动重启)