跳到主要内容

Kratos 框架核心特性

井云服务中心后端基于 Go 语言和 Kratos v2 微服务框架构建。Kratos 是一个轻量级的 Go 微服务框架,包含大量微服务相关框架及工具,帮助开发者快速构建微服务系统。本文档介绍 Kratos 框架的核心特性及其在井云项目中的应用。

📋 特性概览

Kratos 框架提供了完整的微服务开发工具链,包括以下核心特性:

特性说明项目应用
APIsHTTP/gRPC 协议通信,通过 Protobuf 定义所有服务接口定义
ErrorsProtobuf Enum 错误码定义,工具生成判定接口统一错误处理
MetadataMiddleware 规范化服务元信息传递租户ID、用户ID传递
Config多数据源配置合并,Atomic 动态配置支持Consul 配置中心
Logger标准日志接口,支持三方 log 库集成结构化日志输出
Metrics统一指标接口,默认集成 Prometheus服务监控指标
Tracing遵循 OpenTelemetry 规范分布式链路追踪
EncodingAccept/Content-Type 自动编码选择JSON/Protobuf 支持
Transport统一 HTTP/gRPC 传输层,Middleware 插件认证、限流、CORS
Registry统一注册中心接口,插件化对接Consul 服务注册
ValidationProtobuf 统一校验规则,适用于 HTTP/gRPC请求参数验证
SwaggerAPI自动生成 Swagger API 文档和 UIOpenAPI 文档生成

🔌 APIs - 协议通信

特性说明

Kratos 支持通过 Protocol Buffers 定义 API 接口,同时支持 HTTP 和 gRPC 双协议:

  • 统一定义: 使用 .proto 文件定义服务接口和消息类型
  • 双协议支持: 同一份定义可生成 HTTP 和 gRPC 服务代码
  • 类型安全: 编译时类型检查,避免运行时错误
  • 代码生成: 自动生成客户端和服务端代码

项目应用

在井云项目中,所有微服务的 API 接口都通过 Protobuf 定义:

// 示例:用户服务 API 定义
service UserService {
rpc CreateUser(CreateUserRequest) returns (CreateUserReply) {
option (google.api.http) = {
post: "/v1/users"
body: "*"
};
}

rpc GetUser(GetUserRequest) returns (GetUserReply) {
option (google.api.http) = {
get: "/v1/users/{id}"
};
}
}

实现位置:

  • Gateway 服务: /backend/services/gateway/api/*.proto
  • 各微服务: /backend/services/{service}/api/*.proto

代码生成命令:

make api  # 生成 API 代码(.pb.go, _grpc.pb.go, _http.pb.go)

❌ Errors - 错误处理

特性说明

Kratos 通过 Protobuf 的 Enum 定义错误码,并提供工具生成错误判定接口:

  • 错误码定义: 使用 Enum 定义标准错误码
  • 错误信息: 支持多语言错误信息
  • 错误判定: 自动生成错误类型判定函数
  • HTTP 映射: 自动映射到 HTTP 状态码

项目应用

井云项目定义了统一的错误码体系:

// 错误码定义
enum ErrorReason {
USER_NOT_FOUND = 0;
USER_ALREADY_EXISTS = 1;
INVALID_PASSWORD = 2;
TOKEN_EXPIRED = 3;
TOKEN_INVALID = 4;
TENANT_NOT_FOUND = 5;
// ... 更多错误码
}

错误码映射:

  • 401: Token 过期(用户需重新登录)
  • 402: Token 无效(用户需重新认证)
  • 404: 资源不存在
  • 500: 服务器内部错误

实现位置:

  • /backend/pkg/errors/business_errors.go

🏷️ Metadata - 元信息传递

特性说明

Kratos 通过 Middleware 规范化服务元信息传递:

  • 上下文传递: 在请求上下文中传递元信息
  • 标准化: 统一的元信息键值定义
  • 跨服务: 服务间调用自动传递元信息
  • 安全性: 支持敏感信息过滤

项目应用

井云项目使用 Metadata 传递租户和用户信息:

// 定义元信息键
const (
TenantIDKey = "tenant-id"
UserIDKey = "user-id"
TraceIDKey = "trace-id"
)

// 在 Middleware 中提取和设置
func TenantMiddleware() middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (interface{}, error) {
// 从 Header 中提取 tenant-id
tenantID := metadata.Get(ctx, TenantIDKey)
ctx = context.WithValue(ctx, contextkeys.TenantIDContextKey{}, tenantID)
return handler(ctx, req)
}
}
}

实现位置:

  • /backend/services/gateway/internal/contextkeys/context.go
  • /backend/services/gateway/internal/middleware/auth.go

⚙️ Config - 配置管理

特性说明

Kratos 支持多数据源配置合并,通过 Atomic 方式支持动态配置:

  • 多数据源: 支持文件、环境变量、Consul 等多种配置源
  • 配置合并: 自动合并多个配置源,后加载的覆盖先加载的
  • 动态配置: 支持运行时配置热更新,无需重启服务
  • 类型安全: 通过 Protobuf 定义配置结构,编译时类型检查

项目应用

井云项目使用 Consul 作为配置中心:

// 配置定义
message Server {
string network = 1;
string address = 2;
google.protobuf.Duration timeout = 3;
}

message Database {
string driver = 1;
string source = 2;
}

message Config {
Server server = 1;
Database database = 2;
// ... 其他配置
}

配置加载:

# 从 Consul 加载配置
./bin/gateway -conf consul:8500

# 配置路径
kratos/gateway.yaml

实现位置:

  • /backend/services/{service}/conf/config_*.proto
  • Consul KV: kratos/{service}.yaml

📝 Logger - 日志记录

特性说明

Kratos 提供标准日志接口,可方便集成三方 log 库:

  • 标准接口: 统一的日志接口定义
  • 日志级别: 支持 DEBUG、INFO、WARN、ERROR 等级别
  • 结构化日志: 支持结构化日志输出(如 JSON 格式)
  • 日志收集: 可通过 fluentd 等工具收集日志

项目应用

井云项目使用 Kratos 内置日志系统:

// 使用 Kratos 日志
import kratoslog "github.com/go-kratos/kratos/v2/log"

var log = kratoslog.NewHelper(kratoslog.With(
kratoslog.DefaultLogger,
"service", "gateway",
"version", "v1.0.0",
))

// 记录日志
log.Infof("用户登录成功: user_id=%d", userID)
log.Errorf("订单创建失败: error=%v", err)

日志格式:

{
"ts": "2025-12-28T10:30:00.000Z",
"caller": "auth.go:123",
"service.id": "gateway-001",
"service.name": "jingyun-gateway",
"service.version": "v1.0.0",
"trace.id": "abc-123-def",
"span.id": "456",
"msg": "用户登录成功",
"user_id": 1001
}

📊 Metrics - 指标监控

特性说明

Kratos 提供统一指标接口,默认集成 Prometheus:

  • 标准接口: 统一的指标接口定义
  • 指标类型: Counter、Gauge、Histogram、Summary
  • Prometheus 集成: 默认支持 Prometheus 指标收集
  • 自定义指标: 支持自定义业务指标

项目应用

井云项目集成 Prometheus 进行指标收集:

import (
"github.com/go-kratos/kratos/v2/metrics"
prometheus "github.com/go-kratos/kratos/contrib/metrics/prometheus/v2"
)

// 创建 Prometheus 指标
var counter = prometheus.NewCounter(&metrics.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
Labels: []string{"method", "path", "status"},
})

// 记录指标
counter.Inc("GET", "/api/v1/users", "200")

指标端点:

  • http://localhost:8000/metrics: Prometheus 指标暴露端点

关键指标:

  • http_requests_total: HTTP 请求总数
  • http_request_duration_seconds: 请求处理时间
  • grpc_server_handled_total: gRPC 请求总数

🔍 Tracing - 链路追踪

特性说明

Kratos 遵循 OpenTelemetry 规范实现微服务链路追踪:

  • OpenTelemetry: 遵循 OpenTelemetry 标准
  • 分布式追踪: 跨服务的请求追踪
  • Trace ID: 全局唯一的追踪 ID
  • Span: 服务内操作的时间跨度

项目应用

井云项目集成 OpenTelemetry 进行分布式追踪:

import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)

// 获取 Tracer
var tracer = otel.Tracer("gateway")

// 创建 Span
ctx, span := tracer.Start(ctx, "CreateUser")
defer span.End()

// 记录事件
span.AddEvent("validation_passed")
span.SetAttributes(attribute.Int("user_id", userID))

追踪信息:

  • trace.id: 全局追踪 ID
  • span.id: 当前操作 ID
  • parent.id: 父操作 ID

集成工具: Jaeger、Zipkin

🔄 Encoding - 内容编码

特性说明

Kratos 支持 Accept 和 Content-Type 进行自动选择内容编码:

  • 自动选择: 根据请求头自动选择编码格式
  • 多格式支持: JSON、Protobuf、XML 等
  • 编码器插件: 支持自定义编码器
  • 性能优化: Protobuf 二进制编码性能更优

项目应用

井云项目支持 JSON 和 Protobuf 双格式:

# JSON 格式请求
GET /api/v1/users/1
Accept: application/json

# Protobuf 格式请求
GET /api/v1/users/1
Accept: application/protobuf

响应格式:

  • HTTP API: 默认 JSON 格式
  • gRPC API: Protobuf 二进制格式

🚦 Transport - 传输层

特性说明

Kratos 提供通用的 HTTP/gRPC 传输层,实现统一的 Middleware 插件支持:

  • 统一接口: HTTP 和 gRPC 使用相同的 Middleware 接口
  • 插件化: 支持 Middleware 插件化扩展
  • 链式调用: Middleware 链式调用
  • 上下文传递: 统一的上下文传递机制

项目应用

井云项目使用 Middleware 实现各种横切关注点:

// HTTP Server Middleware
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
recovery.Recovery(), // 异常恢复
tracing.Server(), // 链路追踪
logging.Server(logger), // 日志记录
auth.AuthMiddleware(), // 认证中间件
cors.Server(), // CORS 跨域
),
)

// gRPC Server Middleware
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
recovery.Recovery(),
tracing.Server(),
logging.Server(logger),
),
)

常用 Middleware:

  • recovery: 异常恢复,防止服务崩溃
  • tracing: 分布式追踪
  • logging: 日志记录
  • auth: 认证鉴权
  • cors: 跨域资源共享
  • ratelimit: 限流控制

📋 Registry - 服务注册

特性说明

Kratos 实现统一注册中心接口,可插件化对接各种注册中心:

  • 统一接口: 标准化的服务注册接口
  • 多实现: 支持 Consul、Etcd、Nacos 等注册中心
  • 健康检查: 自动健康检查和状态上报
  • 服务发现: 自动服务发现和负载均衡

项目应用

井云项目使用 Consul 作为服务注册中心:

import (
"github.com/go-kratos/kratos/contrib/registry/consul/v2"
consul "github.com/hashicorp/consul/api"
)

// 创建 Consul 客户端
consulClient, _ := consul.NewClient(consul.DefaultConfig())
r := consul.New(consulClient)

// 服务注册
app := kratos.New(
kratos.Server(httpSrv, grpcSrv),
kratos.Registration(r),
)

Consul 配置:

  • 地址: consul:8500
  • 协议: http
  • 健康检查: 每隔 10 秒检查一次

服务列表:

  • jingyun-gateway: 8000/9000
  • jingyun-auth: 9001
  • jingyun-user: 9002
  • jingyun-tenant: 9003
  • jingyun-agent: 9004
  • jingyun-payment: 9006
  • jingyun-integration: 9007
  • jingyun-cron: 9008

✅ Validation - 参数验证

特性说明

Kratos 通过 Protobuf 统一定义校验规则,并同时适用于 HTTP/gRPC 服务:

  • 统一验证: HTTP 和 gRPC 使用相同的验证规则
  • Protobuf 注解: 在 Protobuf 中定义验证规则
  • 代码生成: 自动生成验证代码
  • 错误提示: 自动生成友好的错误提示

项目应用

井云项目在 Protobuf 中定义验证规则:

import "validate/validate.proto";

message CreateUserRequest {
string username = 1 [(validate.rules).string = {
min_len: 3,
max_len: 20,
pattern: "^[a-zA-Z0-9_]+$"
}];

string email = 2 [(validate.rules).string.email = true];

string password = 3 [(validate.rules).string = {
min_len: 8,
max_len: 32
}];

int64 tenant_id = 4 [(validate.rules).int64.gt = 0];
}

验证错误示例:

{
"code": 400,
"reason": "VALIDATION_ERROR",
"message": "username: 长度必须在 3-20 之间",
"metadata": {
"field": "username",
"constraint": "min_len"
}
}

📖 SwaggerAPI - API 文档

特性说明

Kratos 通过集成第三方 Swagger 插件能够自动生成 Swagger API 文档并启动内置的 Swagger UI 服务:

  • 自动生成: 从 Protobuf 定义自动生成 OpenAPI 文档
  • Swagger UI: 内置 Swagger UI 服务
  • 接口测试: 在线测试 API 接口
  • 文档同步: 代码和文档保持同步

项目应用

井云项目使用 protoc-gen-openapiv2 生成 OpenAPI 文档:

# 生成 OpenAPI 文档
make api

# 生成的文档
openapi.yaml

Swagger UI 访问:

  • 本地开发: http://localhost:8000/q/swagger-ui
  • 生产环境: 根据实际配置

文档内容:

  • 接口列表
  • 请求参数
  • 响应格式
  • 错误码说明
  • 示例代码

实现位置:

  • /backend/services/gateway/openapi.yaml
  • /backend/services/{service}/openapi.yaml

🔧 开发工具链

代码生成

Kratos 提供完整的代码生成工具链:

# 生成 API 代码
make api

# 生成配置代码
make config

# 生成 Wire 依赖注入代码
make wire

# 生成 Ent ORM 代码
make ent

# 生成所有代码
make all

依赖注入

Kratos 使用 Wire 进行编译时依赖注入:

// wire.go
func InitApp() (*kratos.App, func(), error) {
wire.Build(
DataSet,
BizSet,
ServiceSet,
newApp,
)
return nil, nil, nil
}

📚 最佳实践

API 设计

  1. RESTful 风格: 使用 RESTful 风格的 HTTP 路径
  2. 版本管理: 使用 /v1//v2/ 进行版本管理
  3. 错误码: 使用统一的错误码体系
  4. 分页: 使用统一的分页参数

错误处理

  1. 错误码定义: 使用 Enum 定义错误码
  2. 错误信息: 提供友好的错误信息
  3. 日志记录: 记录详细的错误日志
  4. 错误恢复: 使用 Recovery Middleware

配置管理

  1. 配置分层: 默认配置、环境配置、Consul 配置
  2. 敏感信息: 敏感信息使用环境变量
  3. 配置验证: 启动时验证配置有效性
  4. 配置热更新: 支持配置热更新

日志记录

  1. 结构化日志: 使用 JSON 格式日志
  2. 日志级别: 合理设置日志级别
  3. 上下文信息: 记录足够的上下文信息
  4. 日志脱敏: 敏感信息脱敏处理

🔗 相关文档