feat: 添加微服务模板基础架构
- 创建基于 CloudWego Hertz 的 Go 微服务脚手架 - 集成 Nacos 服务注册/发现功能 - 添加 gRPC 客户端支持 - 实现环境变量配置管理 (.env.example) - 添加 HTTP 中间件 (Recovery, AccessLog, CORS) - 配置 Gitea CI/CD 构建部署流程 BREAKING CHANGE: 项目结构调整,从简单的 API 服务升级为完整的微服务架构
This commit is contained in:
@@ -1,9 +1,295 @@
|
||||
# apiServer 微服务模板
|
||||
|
||||
## 使用步骤
|
||||
基于 [CloudWego Hertz](https://github.com/cloudwego/hertz) 的 Go 微服务脚手架,集成 Nacos 服务注册/发现 + gRPC 客户端 + 访问日志上报(Redis → ES)。
|
||||
|
||||
- 拉取该项目仓库
|
||||
- 修改配置文件 .env
|
||||
- 修改项目名称,将项目文件中的 apiServer_service 替换为项目名称
|
||||
- 新建gitea仓库,修改本地仓库地址
|
||||
- 项目入口在 cmd/main_program 文件下
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
├── apps/ # 业务处理层 (Handler)
|
||||
├── cmd/
|
||||
│ ├── main_program/ # 主程序入口 (HTTP 服务)
|
||||
│ └── cli_control/ # CLI 工具入口 (httplog 上报)
|
||||
├── middleware/ # HTTP 中间件 (Recovery, AccessLog, CORS)
|
||||
├── models/request_models/ # 请求参数模型
|
||||
├── proto/ # Protobuf 生成代码
|
||||
├── routes/ # 路由定义
|
||||
├── utils/
|
||||
│ ├── httplog/ # HTTP 访问日志采集 & ES 上报
|
||||
│ ├── logger/ # 日志工具 (logrus)
|
||||
│ ├── nacos/ # Nacos 服务注册/发现/配置
|
||||
│ ├── redis_tools/ # Redis 连接 & 通用操作
|
||||
│ ├── request/ # 请求绑定 & 统一响应
|
||||
│ └── server_cli/ # gRPC 客户端
|
||||
├── start.sh / stop.sh / restart.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 上报
|
||||
|
||||
# 4. 构建
|
||||
go build -ldflags="-s -w" -o server ./cmd/main_program
|
||||
go build -ldflags="-s -w" -o cli ./cmd/cli_control
|
||||
```
|
||||
|
||||
## 模板使用步骤
|
||||
|
||||
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` → 注册中间件(Recovery、AccessLog、CORS)→ 绑定路由 → Nacos 注册(可选)→ 启动 HTTP 监听 → 等待信号优雅关闭。
|
||||
|
||||
### cmd/cli_control — httplog 日志上报
|
||||
|
||||
独立后台进程,从 Redis 队列中消费访问日志,批量写入 Elasticsearch。
|
||||
|
||||
```bash
|
||||
go run ./cmd/cli_control
|
||||
```
|
||||
|
||||
启动后会以轮询方式从 `ES_REDIS_KEY` 队列中批量 pop 日志条目,组装 ES `_bulk` 请求写入 `ES_INDEX_PREFIX-YYYY.MM.DD` 索引。
|
||||
|
||||
### middleware — HTTP 中间件
|
||||
|
||||
在 `cmd/main_program/routs.go` 中统一注册:
|
||||
|
||||
```go
|
||||
r.Use(middleware.Recovery()) // panic 恢复,防止单个请求崩溃整个服务
|
||||
r.Use(middleware.AccessLog()) // 请求日志(方法、路径、状态码、耗时)
|
||||
r.Use(middleware.CORS()) // 跨域支持
|
||||
```
|
||||
|
||||
### utils/httplog — 访问日志采集
|
||||
|
||||
Hertz Tracer 实现,在请求完成后采集完整的访问事件(方法、路径、状态码、耗时、请求体、响应体等),通过 Redis List 异步缓冲。
|
||||
|
||||
**在主服务中接入:**
|
||||
|
||||
```go
|
||||
import (
|
||||
"apiServer_service/utils/httplog"
|
||||
"apiServer_service/utils/redis_tools"
|
||||
"github.com/cloudwego/hertz/pkg/app/server"
|
||||
)
|
||||
|
||||
rdb := redis_tools.ConnectRedis()
|
||||
tracer := httplog.NewRedisAccessLogTracer(rdb, "access_log", "my-service",
|
||||
httplog.WithSkipPrefix("/health"), // 跳过健康检查路径
|
||||
httplog.WithMaxResponseBody(4096), // 响应体最大采集 4KB
|
||||
httplog.WithUserIDExtractor(func(c *app.RequestContext) uint {
|
||||
// 根据你的认证方式提取 user_id
|
||||
return 0
|
||||
}),
|
||||
)
|
||||
h := server.Default(server.WithTracer(tracer))
|
||||
```
|
||||
|
||||
**特性:**
|
||||
- 敏感字段自动脱敏(password, token, secret 等)
|
||||
- multipart 文件字段替换为 `[file]` 占位符
|
||||
- 非文本响应自动跳过(图片、zip 等)
|
||||
- 异步写入 Redis,队列满时丢弃(不阻塞业务)
|
||||
|
||||
### utils/redis_tools — Redis 工具
|
||||
|
||||
单例连接,提供通用 KV 和 List 操作:
|
||||
|
||||
```go
|
||||
import "apiServer_service/utils/redis_tools"
|
||||
|
||||
// 连接(全局只初始化一次)
|
||||
rdb := redis_tools.ConnectRedis()
|
||||
|
||||
// KV 操作
|
||||
redis_tools.SetCache("key", "value", 10*time.Minute)
|
||||
val, err := redis_tools.GetCache("key")
|
||||
redis_tools.Del("key1", "key2")
|
||||
redis_tools.Exists("key")
|
||||
|
||||
// List 操作
|
||||
redis_tools.AddToList("queue", "item")
|
||||
items, _ := redis_tools.GetAllFromList("queue")
|
||||
redis_tools.RemoveFromList("queue", "item")
|
||||
```
|
||||
|
||||
### utils/nacos — Nacos 服务注册/发现/配置
|
||||
|
||||
```go
|
||||
import "apiServer_service/utils/nacos"
|
||||
|
||||
// 注册当前服务(读取 NACOS_SERVICE_* 环境变量)
|
||||
nacos.RegisterService()
|
||||
|
||||
// 发现服务(带内存缓存)
|
||||
instance, err := nacos.DiscoverService("user-service")
|
||||
addr := instance.Ip + ":" + strconv.Itoa(int(instance.Port))
|
||||
|
||||
// 配置管理
|
||||
content := nacos.GetConfig("app.yaml", "DEFAULT_GROUP")
|
||||
nacos.AddConfig("app.yaml", "DEFAULT_GROUP", "key: value")
|
||||
```
|
||||
|
||||
### utils/server_cli — gRPC 客户端
|
||||
|
||||
通过 Nacos 服务发现获取 gRPC 地址,连接复用:
|
||||
|
||||
```go
|
||||
import "apiServer_service/utils/server_cli"
|
||||
|
||||
err := server_cli.ReportVisit(token, note, ip, os, point, userId)
|
||||
defer server_cli.CloseGrpcConn()
|
||||
```
|
||||
|
||||
### utils/request — 请求绑定 & 统一响应
|
||||
|
||||
```go
|
||||
import "apiServer_service/utils/request"
|
||||
|
||||
// 参数绑定(失败自动返回 400)
|
||||
var req MyRequest
|
||||
if err := request.BindRequestStruct(c, &req); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 统一响应
|
||||
request.Success(c, data) // 200 {"code":200,"message":"Success","data":...}
|
||||
request.BadRequest(c, "参数错误") // 400
|
||||
request.Unauthorized(c, "未登录") // 401
|
||||
request.NotFound(c, "资源不存在") // 404
|
||||
request.Error(c, 500, "服务器内部错误") // 自定义状态码
|
||||
request.FileResponse(c, "/path/to/file", "download.zip")
|
||||
```
|
||||
|
||||
### routes — 路由定义
|
||||
|
||||
在 `routes/` 下按模块拆分路由文件,在 `cmd/main_program/routs.go` 中注册:
|
||||
|
||||
```go
|
||||
func SetupRoutes(r *server.Hertz) {
|
||||
r.Use(middleware.Recovery())
|
||||
r.Use(middleware.AccessLog())
|
||||
r.Use(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
|
||||
```
|
||||
|
||||
### 首次安装(systemd 服务注册)
|
||||
|
||||
将二进制、`.env`、脚本和 `deploy/` 目录上传到服务器后执行:
|
||||
|
||||
```bash
|
||||
chmod +x install.sh start.sh stop.sh restart.sh server cli
|
||||
|
||||
# 安装 systemd 服务 + 设置开机自启
|
||||
sudo bash install.sh
|
||||
```
|
||||
|
||||
`install.sh` 会自动:
|
||||
1. 将 `deploy/*.service` 适配当前路径后复制到 `/etc/systemd/system/`
|
||||
2. 执行 `systemctl daemon-reload`
|
||||
3. 执行 `systemctl enable server cli` 开机自启
|
||||
|
||||
### 日常运维
|
||||
|
||||
```bash
|
||||
bash start.sh # 启动全部服务
|
||||
bash stop.sh # 停止全部服务
|
||||
bash restart.sh # 重启全部服务
|
||||
```
|
||||
|
||||
也可以直接使用 `systemctl` 管理单个服务:
|
||||
|
||||
```bash
|
||||
systemctl status server # 查看主服务状态
|
||||
systemctl status cli # 查看 CLI 状态
|
||||
systemctl restart server # 只重启主服务
|
||||
journalctl -u server -f # 查看主服务实时日志
|
||||
journalctl -u cli -f --since today # 查看 CLI 今日日志
|
||||
```
|
||||
|
||||
### systemd 服务特性
|
||||
|
||||
| 特性 | 说明 |
|
||||
|------|------|
|
||||
| 开机自启 | `install.sh` 执行后自动启用 |
|
||||
| 崩溃自动重启 | `Restart=always`,server 间隔 3s,cli 间隔 5s |
|
||||
| 优雅关闭 | `KillSignal=SIGTERM`,等待 10s 超时后 SIGKILL |
|
||||
| 环境变量 | 通过 `EnvironmentFile` 加载 `.env` |
|
||||
| 文件描述符 | `LimitNOFILE=65536` |
|
||||
| 日志 | 同时写入 `logs/*.out` 和 `journalctl` |
|
||||
|
||||
### 部署目录结构
|
||||
|
||||
```
|
||||
/root/
|
||||
├── server # HTTP 主服务二进制
|
||||
├── cli # httplog 上报二进制
|
||||
├── .env # 环境配置
|
||||
├── deploy/
|
||||
│ ├── server.service # systemd 服务单元(模板)
|
||||
│ └── cli.service
|
||||
├── install.sh # 首次安装脚本
|
||||
├── start.sh # 启动
|
||||
├── stop.sh # 停止
|
||||
├── restart.sh # 重启
|
||||
└── logs/
|
||||
├── server.out
|
||||
└── cli.out
|
||||
```
|
||||
|
||||
## 内置功能清单
|
||||
|
||||
- Hertz HTTP 框架 + 路由分组
|
||||
- Recovery / AccessLog / CORS 中间件
|
||||
- 统一 JSON 响应格式
|
||||
- 参数绑定与校验
|
||||
- HTTP 访问日志采集 → Redis 缓冲 → ES 批量上报
|
||||
- Redis 工具(单例连接池)
|
||||
- Nacos 服务注册、发现、配置管理
|
||||
- gRPC 客户端(含连接复用)
|
||||
- 彩色日志输出 + 文件日志
|
||||
- 优雅关闭 (Graceful Shutdown)
|
||||
- systemd 服务管理(开机自启 + 崩溃自动重启)
|
||||
|
||||
Reference in New Issue
Block a user