实现一个 Go 微服务框架:Microg
Microg 是什么?
Microg 是一个简单易用的 Go 微服务框架,提供了构建生产级微服务所需的核心功能:
- 服务注册发现:基于 Consul 的服务注册与发现
- gRPC & HTTP:同时支持 gRPC 和 HTTP 服务
- 链路追踪:集成 OpenTelemetry
- 结构化日志:基于 zap 的高性能日志
- 错误处理:支持错误码和 HTTP 状态码映射
- 负载均衡:多种负载均衡策略
GitHub 地址:https://github.com/atliliw/microg
为什么选择 Microg?
1. 简单易用
go
package main
import (
"github.com/atliliw/microg/app"
"github.com/atliliw/microg/server/rpcserver"
"github.com/atliliw/microg/pkg/log"
)
func main() {
rpcServer := rpcserver.NewServer(rpcserver.WithAddress(":9000"))
app.New(
app.WithName("my-service"),
app.WithRPCServer(rpcServer),
).Run()
}
2. 功能完备
框架内置了微服务开发所需的核心组件,开箱即用:
| 功能 | 说明 |
|---|---|
| 服务注册发现 | Consul 集成,自动健康检查 |
| gRPC 服务器 | 内置拦截器(超时、错误处理、链路追踪) |
| HTTP 服务器 | 基于 Gin,内置中间件 |
| 链路追踪 | OpenTelemetry 集成 |
| 结构化日志 | zap 日志,自动关联 traceID |
| 错误处理 | 错误码 + HTTP 状态码映射 |
| Prometheus 指标 | 内置指标收集 |
3. 高性能
基于成熟的开源组件构建:
- gRPC:高性能 RPC 框架
- Gin:高性能 HTTP 框架
- zap:高性能结构化日志
- OpenTelemetry:标准化的可观测性方案
核心功能介绍
应用生命周期管理
统一管理服务的启动、停止和生命周期:
go
app.New(
app.WithName("user-service"), // 服务名称
app.WithRPCServer(rpcServer), // gRPC 服务器
app.WithRestServer(restServer), // HTTP 服务器
app.WithRegistrar(registrar), // 服务注册器
)
框架会自动处理:
- 服务启动
- 服务注册
- 信号监听
- 优雅关闭
- 服务注销
服务注册发现
基于 Consul 的服务注册与发现:
go
// 创建注册器
consulClient, _ := api.NewClient(api.DefaultConfig())
registrar := consul.New(consulClient,
consul.WithHealthCheck(true), // 健康检查
consul.WithHeartbeat(true), // 心跳
)
// 服务发现(客户端)
conn, _ := rpcserver.NewClient(
rpcserver.WithEndpoint("discovery:///user-service"),
rpcserver.WithRegistrar(registrar),
)
gRPC 服务器
高性能 gRPC 服务器,内置多种拦截器:
go
rpcServer := rpcserver.NewServer(
rpcserver.WithAddress(":9000"),
rpcserver.WithTimeout(30 * time.Second),
rpcserver.WithMetrics(true), // Prometheus 指标
)
内置拦截器:
- 超时拦截器
- 错误处理拦截器
- Panic 恢复拦截器
- Prometheus 指标拦截器
- OpenTelemetry 链路追踪拦截器
HTTP 服务器
基于 Gin 的 HTTP 服务器:
go
restServer := restserver.NewServer(
restserver.WithPort(8080),
restserver.WithMode("release"),
restserver.WithHealthz(true), // /healthz
restserver.WithMetrics(true), // /metrics
restserver.WithPprof(true), // /debug/pprof
)
结构化日志
基于 zap 的高性能日志,支持自动关联 traceID:
go
// 结构化日志
log.Info("user action",
log.String("user", "john"),
log.Int("action", 1),
)
// Context 日志(自动关联 traceID)
log.InfoC(ctx, "processing order",
log.String("orderId", "123"),
)
// 错误日志
log.Error("operation failed",
log.Err(err),
log.String("operation", "create_user"),
)
错误处理
增强版错误包,支持错误码:
go
// 定义错误码
const (
ErrUserNotFound = 200001 // 404
ErrDatabase = 200003 // 500
)
// 创建带错误码的错误
err := errors.WithCode(ErrUserNotFound, "user %s not found", "john")
// 解析错误码
coder := errors.ParseCoder(err)
fmt.Println(coder.Code()) // 200001
fmt.Println(coder.HTTPStatus()) // 404
链路追踪
集成 OpenTelemetry:
go
// 初始化
trace.Init("user-service",
trace.WithEndpoint("http://localhost:14268/api/traces"),
)
// gRPC/HTTP 服务器自动启用链路追踪
实战示例
下面通过一个用户服务示例,展示如何使用 Microg 构建微服务。
项目结构
examples/user/
├── api/v1/ # Proto 定义
├── code/ # 错误码定义
├── srv/ # gRPC 服务端
│ ├── config/ # 配置
│ ├── controller/ # gRPC 控制器
│ ├── service/ # 业务逻辑
│ ├── data/ # 数据访问
│ └── main.go # 入口
└── client/ # HTTP 客户端
├── config/ # 配置
├── controller/ # HTTP 控制器
├── service/ # 业务逻辑
├── data/ # gRPC 客户端
└── main.go # 入口
gRPC 服务端
go
// srv/main.go
package main
import (
"github.com/atliliw/microg/pkg/log"
_ "github.com/atliliw/microg/examples/user/code"
)
func main() {
app, cleanup, err := InitApp()
if err != nil {
log.Fatalf("初始化应用失败: %v", err)
}
defer cleanup()
log.Info("启动用户 gRPC 服务",
log.String("service", app.Cfg.Service.Name),
log.String("grpc_address", app.Cfg.GRPC.Address),
)
app.Application.Run()
}
HTTP 客户端(API 网关)
go
// client/controller/user.go
func (c *UserController) Create(ctx *gin.Context) {
var req struct {
NickName string `json:"nickName" binding:"required"`
PassWord string `json:"passWord" binding:"required"`
Mobile string `json:"mobile" binding:"required"`
}
if err := ctx.ShouldBindJSON(&req); err != nil {
core.WriteResponse(ctx, err, nil)
return
}
cxt, cancel := context.WithTimeout(ctx.Request.Context(), 5*time.Second)
defer cancel()
user, err := c.svc.Create(cxt, req.NickName, req.PassWord, req.Mobile)
core.WriteResponse(ctx, err, user)
}
运行示例
bash
# 1. 启动 Consul
consul agent -dev
# 2. 启动 MySQL
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=microg_user \
-p 3306:3306 mysql:8
# 3. 运行 gRPC 服务端
cd examples/user/srv && go run .
# 4. 运行 HTTP 客户端
cd examples/user/client && go run .
# 5. 测试
curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-d '{"nickName":"john","passWord":"123456","mobile":"13800138000"}'
配置管理
支持 YAML 配置文件:
yaml
# config.yaml
service:
name: user-srv
grpc:
address: ":9001"
timeout: 30s
metrics: true
consul:
address: "localhost:8500"
enabled: true
health_check: true
tracing:
enabled: true
endpoint: "http://localhost:14268/api/traces"
log:
level: info
format: json
负载均衡
支持多种负载均衡策略:
| 策略 | 说明 |
|---|---|
random |
随机选择 |
round_robin |
轮询 |
weighted_round_robin |
加权轮询 |
p2c |
Power of Two Choices(推荐) |
go
conn, _ := rpcserver.NewClient(
rpcserver.WithEndpoint("discovery:///user-service"),
rpcserver.WithSelector("p2c"),
)
总结
Microg 是一个轻量级的 Go 微服务框架,它提供了构建生产级微服务所需的核心功能:
✅ 简单易用,快速上手
✅ 功能完备,开箱即用
✅ 高性能,基于成熟组件
✅ 可观测性,支持链路追踪和指标
如果你正在寻找一个简单、轻量的 Go 微服务框架,不妨试试 Microg!
相关链接
- GitHub:https://github.com/atliliw/microg
- 详细文档:doc/README.md
如果觉得有用,欢迎 Star ⭐ 支持一下!