kratoscore

package module
v0.0.31 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 16 Imported by: 0

README

kratos-core

简体中文 | 繁體中文 | English | 日本語

kratos-core 是 Kratos 服务的通用运行时。宿主项目负责业务 Case、Service、API 和进程入口;Core 负责基础设施、传输层、资源注册以及应用生命周期。

Core 不是完整的业务模板。宿主通过一个 module.Module 把业务服务和构建期资源交给 Core,再由 NewApp 统一装配并交给宿主启动。

Core 负责什么

  • bootstrap.Context 解析数据库、Redis、队列、OSS、JWT、翻译器和性能分析配置。
  • 按模块资源创建多数据源 GORM 客户端、缓存、队列、OSS、翻译器和共享 biz.BaseCase
  • 按配置创建 HTTP、gRPC、MCP、SSE、队列和持久化定时任务运行时,并把模块服务注册到对应传输层;任务、SSE 流和队列消费者分别作为独立集合注入。
  • 装配时按顺序执行数据库迁移、OpenAPI 接口同步、租户角色菜单同步和 Casbin 策略重建。
  • 统一装配可选服务并交给 Kratos 管理生命周期;基础资源由 Wire 生成的清理函数释放。

公共边界

跨项目可以依赖的 Go 代码分为四类入口:

  • 根包提供 ProviderSetNewApp。宿主通常只需要把 ProviderSet 放入自己的 Wire 图。
  • 根目录的 bizconfigconstdataerrorsxjobmcpmodulequeueresourceserversse 提供跨项目公共包。
  • api 是独立 Go 模块,api/proto 保存 Core 的 protobuf 定义,api/gen/go 保存生成的 Go 类型。
  • client 是独立 Go 模块,提供基于 kratos-kit 配置的 gRPC 连接和进程内 gRPC 连接。

data 包只公开多数据源客户端初始化、事务边界以及 API、任务、日志和权限资源的宿主存储契约;数据库模型和生成仓储由宿主项目提供。Core 创建的缓存、队列、OSS、翻译器和多数据源 GORM 客户端会注入 biz.BaseCase,同时写入 kratos-kit/sdk.Runtime,业务代码可以按需从 BaseCase 或 SDK 获取。

Wire 接入

宿主在自己的 Wire 组合根中提供一个实现 module.Module 的业务模块,并使用 Core 唯一公开的 ProviderSet

//go:build wireinject

package main

import (
	"github.com/go-kratos/kratos/v3"
	"github.com/google/wire"
	core "github.com/liujitcn/kratos-core"
	"github.com/liujitcn/kratos-core/module"
	"github.com/liujitcn/kratos-kit/bootstrap"
	"github.com/liujitcn/kratos-kit/redact"
)

// initializeApp 将宿主提供的实例策略解析器交给 Core 各协议入口。
func initializeApp(ctx *bootstrap.Context, policyResolver redact.PolicyResolver) (*kratos.App, func(), error) {
	panic(wire.Build(
		core.ProviderSet,
		newHostModule,
		newHostModules,
	))
}

func newHostModules(host *hostModule) []module.Module {
	return []module.Module{host}
}

Core 的 ProviderSet 汇总配置、基础设施、模块资源、数据访问、资源同步和各协议运行时,并包含 NewApp。宿主只需补充自己的业务 Provider,并提供 []module.Module,不需要重复加入 Core 的 ProviderSet。Core 根目录不再维护 wire.gowire_gen.go;宿主项目应通过自己的 Wire 命令生成组合根和 wire_gen.go,也可以使用 make wire WIRE_DIR=<宿主 Wire 目录>

Core 的任务、日志和权限资源运行时依赖 data 包中的 Store/Writer 契约。宿主应在自己的 Wire 组合根中提供这些契约的实现;Admin 的实现位于 backend/adapter/core。Core 不依赖宿主的数据库模型或生成仓储。

请求脱敏策略

server.NewHTTPServerserver.NewGRPCServermcp.NewServer 的最后一个构造参数为 redact.PolicyResolver。宿主必须在 Wire 图中显式提供该接口,可使用上例的组合根参数,或由宿主 Provider 返回接口;具体类型 Provider 需要 wire.Bind(new(redact.PolicyResolver), new(*HostPolicyResolver))。Core 不注册默认 Provider、不读取进程全局策略,也不改变 module.Module 的注册接口。即使协议未启用,Wire 仍需解析该依赖;仅使用静态规则的宿主可显式传入 nil。

  • HTTP 在最外层 Handler 注入请求上下文,覆盖业务中间件、原生路由和响应 encoder;原有编码、静态资源、SSE 和超时行为保持不变。
  • gRPC 通过原生 UnaryInterceptor / StreamInterceptor 注入 unary 和 server/client/bidi stream 上下文,并使用前置 Kratos middleware 让日志、会话等中间件也可读取策略;模块仍收到原始 *kratosGRPC.Server,可继续通过 Use 挂载中间件。现有生成包装器可从 stream.Context() 获取解析器,无需重生成 Proto。
  • MCP 使用 SDK 接收中间件,在模块中间件之前注入,覆盖独立 HTTP、Legacy SSE、STDIO 和挂载 HTTP 模式;挂载时以 MCP 自身的构造参数为准。

Core 只传递策略,不额外执行 ApplyWith 或修改响应,避免与生成包装器重复脱敏。业务调用 redact.ApplyWith(ctx, nil, value) 时读取当前请求策略;显式非 nil resolver 优先。构造参数为 nil 时会屏蔽上游上下文策略,保留 Kit 的静态规则与默认文本清理,不等同于禁用脱敏。原有 redact.Apply(value) 和日志脱敏接口保持不变,取消信号与 deadline 随请求上下文传递。

本次接口需要包含 WithPolicyResolver / PolicyResolverFromContext 的 Kit/redact 版本,以及支持 CreateGrpcServerWithOptions 的 Kit/server/grpc 版本。新版本发布前,使用临时 GOWORK 同时包含 Core 与这两个本地 Kit 模块联调,不向仓库 go.mod 写入本地 replace;宿主还需重新生成 Wire 装配代码。

模块契约

业务模块实现 module.Module。模块自己持有业务 Service,并在协议注册方法中完成 HTTP、gRPC 和 MCP 注册:

type hostModule struct{}

func (*hostModule) RegisterGRPC(grpc.ServiceRegistrar) {}
func (*hostModule) RegisterHTTP(*kratosHTTP.Server)    {}
func (*hostModule) RegisterMCP(*mcpserver.Server)      {}

各方法的职责如下:

方法 作用
RegisterGRPC 注册生成的 gRPC Service。未配置 gRPC 服务时不会创建 Core gRPC Server。
RegisterHTTP 注册 HTTP Service 和路由。未配置 HTTP 服务时不会创建 Core HTTP Server。
RegisterMCP 注册 MCP 工具。MCP 可以独立监听,也可以挂载到 HTTP。

多个业务模块可以由宿主 Wire 组合根作为 module.Module 提供。任务通过 job.Tasks 提供,SSE 流通过 sse.Streams 提供,队列消费者通过 queue.Consumers 提供;没有对应能力时提供空集合。Core 会按提供顺序转发协议注册,并在装配时校验重复资源和重复 SSE 流标识。

构建期资源

module.Resource 是宿主提供的一组资源接口,module.Resources 聚合多个资源实现:

方法 内容与约束
ProjectKey() / ProjectName() 项目稳定标识和展示名称;ProjectKey 为空时使用 kratos-core,ProjectName 为空时回退到 ProjectKey。
Models() 按数据源名称分组的 GORM 模型。含模型的数据源必须在配置中存在,默认数据源必须配置。
Migrations() 版本化迁移列表。每项 module.Migration 声明 NameFSPathDependencies,Core 按依赖顺序执行;每个数据库类型或命名数据源目录使用 README.md 作为主说明,可选的 README.<locale>.md 由宿主同步。
OpenAPI() / I18n() 分别返回 OpenAPI 和语言 JSON 文件系统,未提供的资源返回 nil。

资源通常由宿主通过 embed.FS、代码生成器或 fstest.MapFS 提供:

type hostResources struct{}

func (*hostResources) ProjectKey() string                    { return "host" }
func (*hostResources) ProjectName() string                   { return "Host Service" }
func (*hostResources) Models() module.Models                 { return map[string][]interface{}{defaultDataSource: models.Models()} }
func (*hostResources) OpenAPI() fs.FS                        { return openAPIFS }
func (*hostResources) I18n() fs.FS                           { return i18nFS }
func (*hostResources) Migrations() module.Migrations          { return module.Migrations{{Name: "host", FS: migrationFS, Path: "."}} }

func NewModuleResources() module.Resources { return module.Resources{&hostResources{}} }

迁移说明目录结构:

assets/<version>/<database-type>/README.md
assets/<version>/<database-type>/README.<locale>.md
assets/<version>/<database-type>/<data-source>/README.md
assets/<version>/<database-type>/<data-source>/README.<locale>.md

迁移记录的 up_filesdown_filesdescription_files 使用 JSON 数组保存相对文件路径和 SHA-256,不再保存 SQL 或 Markdown 正文。Core 将本地化 README 的文件引用按 target_type=7、迁移记录 ID 同步到 base_i18n,缺少对应语言时由调用方回退到主说明。Migration.ReadFiles(module, version, dataSource, references) 从已注册模块文件系统按需读取,按原顺序返回每个文件的路径和独立内容,不合并正文,并校验目录归属和内容摘要;缺失、越界或修改过的文件返回错误。SQL 摘要对应执行时去注释后的内容。

宿主可通过 os.DirFS 注册部署目录,不必嵌入迁移文件。发布时必须携带并保留历史版本文件,迁移资源目录不应作为公开静态目录挂载。旧版正文记录不做隐式兼容;GORM 自动迁移不会删除旧列,也不会将正文转换为文件引用,存量库需另行备份转换,开发环境可按既有流程重建。发布依赖使用 kratos-kit/database/gorm/migration 的正式 tag。

运行时能力

基础上下文

biz.BaseCase 是宿主业务共用的基础上下文,包含 bootstrap.Context、缓存、队列、OSS、翻译器和多数据源 GORM 客户端,并提供 GetAuthInfo 读取当前认证用户。

Core 还向宿主提供以下具体业务服务:

  • job.Job:启动、停止或立即运行数据库中的持久化任务。
  • resource/openapi.OpenAPI:按请求语言、服务或 HTTP 操作查询 OpenAPI 信息。
  • sse.SSE:建立 SSE 订阅并发布 JSON 事件。
服务与中间件

HTTP 和 gRPC 服务会按配置挂载 request ID、I18n、日志、认证授权和参数校验中间件。HTTP 还支持本地 OSS 静态文件、SPA 回退和 Swagger;启用进程内 MCP 或 SSE 时,对应端点会挂载到 HTTP 服务,因此必须同时配置 HTTP。

队列运行时负责消费任务日志消息并转发宿主通过 queue.Consumers 提供的业务事件消费者;Core 审计流水线负责投递并异步写入 API 访问和策略评估日志,完整模型注册与自动迁移仍由宿主提供。Cron 运行时从数据库重载启用的 BaseJob,按 job.Tasks 中的执行器执行任务,并在执行入口按任务编号取得 Redis 分布式锁;Redis 锁初始化失败时自动降级为进程内内存锁,仅保证单实例互斥。

装配与启动顺序

ProviderSetNewApp 的主要装配顺序如下:

  1. 解析启动配置并收集模块资源,根据模块模型创建数据源和迁移注册表。
  2. 执行数据库迁移,随后在同一事务中同步 OpenAPI 接口、base_api_i18n 语言快照、租户角色菜单和 Casbin 数据库规则;接口语言记录使用 operation + locale 唯一键,不关联会变化的 base_api.id;事务提交后刷新内存策略。
  3. 创建共享基础服务、认证授权、HTTP/gRPC/MCP/SSE、队列和 Cron 运行时,并注册独立的任务、SSE 流和队列消费者集合。
  4. 组装 Kratos App;Kratos 统一启动和停止传输服务,Wire 生成的清理函数负责释放其余基础资源。

目录职责

api/
  proto/common/v1/      Core 公共 protobuf 定义
  gen/go/common/v1/     protobuf 生成的 Go 代码

client/
  connection.go         远程或进程内 gRPC 连接适配
  localgrpc/             进程内 gRPC 服务注册与调用

biz/                     基础上下文、认证授权、日志事件和公共业务能力
config/                  启动配置解析
const/                   公共常量
data/                    多数据源客户端、事务和宿主存储契约
errorsx/                 统一错误构造
job/                     Cron 注册、持久化任务和运行时
mcp/                     MCP 服务与生命周期适配
module/                  宿主模块、资源和协议注册契约
queue/                   队列消息辅助能力与消费者生命周期
resource/                I18n、迁移、OpenAPI 和启动资源同步
  biz/                    API、租户和 Casbin 资源同步业务
    dto/                  资源同步 DTO
  i18n/                   国际化资源合并
  locale/                 语言标识解析
  migration/              数据库迁移
  openapi/                OpenAPI 注册、查询和 HTTP 挂载
    dto/                  OpenAPI 查询 DTO
server/                  HTTP、gRPC 和中间件
  middleware/             HTTP/gRPC 通用中间件
sse/                     SSE 流注册、传输和发布
bootstrap.go             对外 ProviderSet 和应用生命周期装配
Makefile                 生成、格式化、测试和静态检查命令

开发命令

make tools     # 安装并锁定代码生成与格式化工具
make api       # 生成 api/gen/go
make wire      # 在 WIRE_DIR 指定的宿主目录生成 Wire 代码
make fmt       # goimports 格式化 Go 代码
make test      # 检查根、api、client 三个 Go 模块
make vet       # 检查根、api、client 三个 Go 模块
make lint      # 当前等同于 make vet

发布版本 tag

scripts/tag_release.py 参照 kratos-kit 按 Go module 独立发布版本。执行前先提交并推送代码,脚本只检查远程默认分支上的提交,不会提交工作区改动:

git add -A
git commit -m "提交说明"
git push origin main

make tag

默认扫描根模块、apiclient,只有模块自上一个 tag 后存在已推送的代码更新时才创建并推送下一个 patch tag:

模块 tag 格式
根模块 vX.Y.Z
api api/vX.Y.Z
client client/vX.Y.Z

也可以只处理指定模块:

MODULE=api make tag              # 从 api 目录开始递归扫描
MODULE=api EXACT=1 make tag      # 只处理 api 模块

脚本会自动跳过没有代码更新或 tag 已存在的模块;根模块的变更检测会排除 apiclient 子模块,避免子模块改动重复触发根模块 tag。

项目要求 Go 1.27.0apiclient 是独立 Go 模块,修改它们时还应分别执行 cd api && go test ./...cd client && go test ./...。修改公共模块契约后,应额外编译依赖 Core 的宿主项目。

客户端连接的独立说明见 client/README.md

HTTP、SSE 和 OpenAPI 文档入口均校验实际请求令牌所属会话;同账号其他设备在线不会使已撤销的令牌重新获得访问权限。

Documentation

Overview

Package kratoscore 提供 Core 应用的依赖注入入口与运行时组装能力。

Index

Constants

This section is empty.

Variables

ProviderSet 汇总 Core 应用所需的配置、业务、资源与传输层依赖。 宿主提供 bootstrap.Context、业务模块以及独立的资源和可选能力集合,Wire 会按此集合完成其余运行时组件的装配。 Wire 根据类型依赖图解析提供者,以下排列仅用于职责分组,不表示实例创建或服务启动顺序。

Functions

func NewApp added in v0.0.3

func NewApp(
	ctx *bootstrap.Context,
	syncResult *resource.SyncResult,
	httpServer transport.Server,
	grpcServer *grpc.Server,
	mcpServer *mcp.Server,
	sseServer *sse.Server,
	queueServer *queue.Server,
	jobServer *job.Server,
) *kratos.App

NewApp 将 Wire 创建的 Core 组件组装为最终的 Kratos 应用。 syncResult 记录依赖注入阶段已经完成的资源同步结果;HTTP 与 gRPC 服务按配置可选创建; MCP 和 SSE 仅在独立传输模式下加入应用生命周期,进程内模式由 HTTP 服务统一承载; 队列消费者和定时任务作为后台服务随应用共同启动和停止。

Types

This section is empty.

Directories

Path Synopsis
api module
client module
biz
requestmeta
Package requestmeta 提供服务端请求关联标识的统一读取能力。
Package requestmeta 提供服务端请求关联标识的统一读取能力。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL