tgf

June 11, 2026 · View on GitHub

Go Report Card Go Version License

tgf

tgf 是一套基于 Go 语言的分布式游戏服务器框架,同时把 HTTP web 服务 做成与 RPC 平级的一等公民。它专注于解决游戏 / web 业务开发中常见的稳定性、并发 与运维问题。v2/v3 在 v1 基础上做了系统性的重构——从网关连接生命周期到数据落库 可靠性,从可观测性接口到 API 一致性,再到 HTTP 服务的路由 / 中间件 / 优雅停机, 都有明显的提升。

设计目标:让中小型团队与独立开发者只关注业务逻辑,不必处理连接风暴、 跨节点协调、配置热更、指标埋点这些底层细节。

tgf 一套框架覆盖三类场景,各有对应示例:

场景形态对应示例
常规 http web 服务标准 REST API:路由 + 中间件 + 限流 + 鉴权 + 优雅停机example/http_rest/
分布式 web 服务HTTP 接入层经 HTTP→RPC 桥调后端 service(traceId 全链路、Consul 服务发现)example/http_rpc/
分布式游戏服务长连接网关(TCP/WS/KCP)+ 跨 module RPC + write-behind 落库example/single_process/

目录


v2 特性亮点

相对 v1,v2 的主要交付成果:

🛡️ 稳定性(A 档)

  • 网关连接生命周期统一 — 新增 IConn 抽象层,TCP / WebSocket / KCP 三种传输共享同一套 handleConn 管道,消除 v1 两套并行实现带来的 goroutine 泄漏和状态不一致
  • 跨节点登录原子化 — 基于 Redis 锁 + 定向踢远端 owner,替代 v1 的 BorderRPCMessage 广播方案
  • Write-behind 缓存可靠性toLongevity 重写,失败批次保留脏标志下轮补偿,配合 A1b 补偿队列跨重启恢复
  • KCP + AEAD 网关 — 第三种传输通道,ChaCha20-Poly1305 帧加密,复用 IConn 生命周期
  • RPC 超时策略化 — 支持按 module.method 覆盖全局默认超时

🔧 工程化(B 档)

  • 构建基线 — Makefile / .golangci.yml / Dockerfile / GitHub Actions CI 全套
  • 可观测性接口tgf/metricstgf/trace 两个新包,零外部依赖,默认 NoOp,业务按需写 Prometheus / OpenTelemetry adapter
  • 日志热路径优化log.*Tag 系列加 level + tag 前置过滤,新增 InfoTagWzap.Field 风格 API,避免 Sprintf 分配
  • 依赖升级 — Go 1.26.4(最新稳定线)、go-sql-driver/mysql、ants、excelize、protobuf 等保守升级到主线

🌐 HTTP 一等公民(G 档)

  • WithHTTPService(web.Options{...}) — HTTP 与 RPC 平级的服务构建器,同进程共存、共享优雅停机;可多次调用挂多个端口
  • 标准库路由 — 基于 Go 1.22 net/http.ServeMux"GET /users/{id}" 模式 + 路径参数),零第三方 web 框架依赖
  • 内置中间件链 — Trace(X-Trace-Id)/ AccessLog / Metrics / Recover / RateLimit / Auth,与 net/http 生态同构(func(http.Handler) http.Handler
  • HTTP→RPC 桥 — handler 经注入的 web.Backend 调任意后端 service,单进程直通 / 分布式 rpcx 自动选路,traceId 从 HTTP 请求透传到后端 RPC
  • 生产级停机http.Server 实例(带超时,防 slowloris)挂进 D3 停机序列,Shutdown(ctx) 带超时 drain in-flight 请求

🏗️ API / 架构演进(C 档)

  • GameConfig 热更component.ReloadGameConf() + OnReload(fn) + fsnotify 自动监听
  • 配置系统升级 — 新 tgf/config 包,struct tag 驱动的反射加载器,新增字段只改一处
  • Server Builder 重构WithGatewayOptions(...) 合并 v1 四个平行 API,WithStandalone() 语义糖
  • IService 接口重塑 — 可选子接口 IStatefulService / IUserLifecycleService,Module 基类自动满足
  • DB 补偿队列FailureQueue 接口 + NoopImpl / MemoryImpl / FileImpl 三种实现
  • RPC 策略化完整版MethodPolicy{Timeout, MaxConcurrency, RateLimit, CircuitBreaker},集成 metrics 拒绝路径计数
  • 单进程模式(C8)WithSingleProcess() 一键开关,多 Module 在同一进程通过反射直通通信,零 Consul 依赖,适合单元测试和小型部署

📊 验证指标

  • 265 个单测 / 集成测试(集成测试以 //go:build integration tag 隔离,默认不跑)
  • go test -race -count=1 ./...workspace 内(仓库外 go.work 同时检出 tgf/rpcx/rpcx-consul 三仓)全绿
  • go vet 零告警
  • 14 处 pre-existing bug / race 顺带修复

上述构建/测试结果在 go.work workspace 内与 GOWORK=off 单仓模式下均成立 (go.mod 内置指向同工作区 fork 目录的 path replace,见下文「从源码构建」)。 无本机 Consul/Redis/MySQL 的纯单元测试可独立跑通;集成测试需对应外部服务。


5 分钟快速上手

1. 安装

要求 Go 1.26+(go.mod 声明 go 1.26.0 / toolchain go1.26.4)。

tgf 自 v2.0.0 起 module path 带 /v2 主版本后缀,直接 go get

go get github.com/thkhxm/tgf/v2@v2.0.0

import 路径相应带 /v2,例如:

import (
    "github.com/thkhxm/tgf/v2/rpc"
    "github.com/thkhxm/tgf/v2/web"
)

下游业务工程不需要任何 replace 块。 tgf 依赖的 rpcx / rpcx-consul fork 也已 迁移为带 /v2 后缀的自有 module path(github.com/thkhxm/rpcx/v2 / github.com/thkhxm/rpcx-consul/v2,当前 tag v2.0.3 / v2.0.2),由 tgf 的 go.mod 直接 require 引入并随之自动拉取——业务方既不必 require 它们,也不必 写 replace。tgf 仓库内 go.mod 保留的那条指向 ../rpcx 的 path replace 只在本仓 脱离 go.work(GOWORK=off)时生效,依赖方会忽略它,按 require 的对应 tag 从远端拉取。

从源码构建(贡献者)

本仓库与 fork 一起放在一个 Go workspace(仓库外的 go.work 同时 use tgf/rpcx/rpcx-consul/ 三个目录)。tgf/go.mod 另内置两条指向 ../rpcx../rpcx-consul 的 path replace,因此只要按 doc/architecture.md 的布局把三个仓库检出到同级目录, workspace 内与 GOWORK=off 单仓模式均可直接构建。

2. 配置与凭据(重要)

tgf 按 TGFMODULE 环境变量加载 .env.<module> 文件(缺省 dev),里面是 Consul / Redis / MySQL 的地址与口令。真实凭据绝不入库

  • 仓库只提供占位值模板 .env.example / .env.test.example / .env.release.example(被跟踪,安全)。

  • 复制模板为对应的 .env.dev / .env.test / .env.release 并填入本地/生产真实值:

    cp .env.example .env.dev          # 然后改 RedisPassword / MySqlPwd 等真实口令
    
  • .env.env.dev.env.test.env.release 等已被 .gitignore 忽略,git add . 不会把它们提交。

  • 生产环境推荐通过容器编排 / 密钥管理(Vault、K8s Secret 等)注入这些值,而不是落盘提交。

3. Hello, tgf(单进程模式,不需要 Consul / Redis / MySQL)

package main

import (
    "fmt"
    "time"

    "github.com/thkhxm/tgf/v2/rpc"
    "golang.org/x/net/context"
)

// --- 定义一个 Service ---

type HelloService struct {
    rpc.Module
}

func (s *HelloService) Startup() (bool, error) { return true, nil }

type HelloReq struct{ Name string }
type HelloRes struct{ Greeting string }

func (s *HelloService) Greet(ctx context.Context, req *HelloReq, reply *HelloRes) error {
    reply.Greeting = "你好, " + req.Name
    return nil
}

var GreetAPI = &rpc.ServiceAPI[*HelloReq, *HelloRes]{
    ModuleName: "hello", Name: "Greet", MessageType: "hello.Greet",
}

// --- 启动 + 调用 ---

func main() {
    // 1. 启动单进程 server
    rpc.NewRPCServer().
        WithSingleProcess().                                       // 不挂 Consul
        WithService(&HelloService{Module: rpc.Module{Name: "hello"}}).
        WithGatewayOptions(rpc.GatewayOptions{TCPPort: "8082"}).
        Run()
    time.Sleep(200 * time.Millisecond)

    // 2. 在任何地方通过 SendRPCMessage 调用(进程内直通)
    res, err := rpc.SendRPCMessage(context.Background(),
        GreetAPI.NewRPC(&HelloReq{Name: "世界"}))
    if err != nil {
        fmt.Printf("失败: %v\n", err)
        return
    }
    fmt.Println(res.Greeting) // → 你好, 世界
}

跑起来

go run main.go
# 输出: 你好, 世界

没有 Consul、没有 Redis、没有 MySQL——WithSingleProcess() 让框架跑在零依赖模式。 从单进程原型平滑迁移到分布式部署只需要去掉这一行调用。

更多场景见 example/ 目录下的示例项目。


HTTP 一等公民(G 档)

tgf 把 HTTP web 服务做成与 RPC 平级的一等公民:用 WithHTTPService 即可在同一个 进程里起一个标准 HTTP 服务,与 RPC 服务共享生命周期与优雅停机。核心实现放在 自包含的 tgf/web 包(只依赖标准库 + log/metrics/trace 三个叶子包,不 import rpc,无 import 环);rpc.Server 单向 import web,把"调用后端 RPC 的能力"以 web.Backend 接口注入进来。

最小用法

import (
    "net/http"
    "github.com/thkhxm/tgf/v2/rpc"
    "github.com/thkhxm/tgf/v2/web"
)

rpc.NewRPCServer().
    WithStandalone().                       // 纯 web 进程:不挂 Consul
    WithHTTPService(web.Options{
        Addr: ":8090",                      // 省略则读配置 HTTPPort(默认 8090)
        Routes: func(r *web.Router) {
            r.GET("/health", func(w http.ResponseWriter, _ *http.Request) {
                _, _ = w.Write([]byte("ok"))
            })
            r.GET("/users/{id}", func(w http.ResponseWriter, req *http.Request) {
                _, _ = w.Write([]byte(req.PathValue("id")))   // Go 1.22 路径参数
            })
            // 鉴权分组:/admin/* 全部要求 Bearer 口令(fail-closed)
            admin := r.Group("/admin", web.Auth(web.StaticBearerToken("s3cr3t")))
            admin.GET("/stats", statsHandler)
        },
        Limiter: web.NewTokenBucketLimiter(1000),   // 全局 1000 QPS(E1 同款语义)
    }).
    Run()                                   // 启动监听;收到信号后 Destroy 优雅 drain

完整可跑示例:example/http_rest/

路由与中间件

  • 路由:基于 Go 1.22 net/http.ServeMux。模式 "GET /users/{id}"(method + 路径参数), handler 内 req.PathValue("id") 取参;r.Group(prefix, mws...) 派生带前缀的分组, r.Use(mws...) 只影响之后注册的路由。便捷方法 GET/POST/PUT/DELETE/PATCH
  • 内置中间件链(外 → 内):Trace → AccessLog → Metrics → Recover → RateLimit → Backend 注入 → 用户 Middlewares → 路由。可经 DisableTrace/DisableAccessLog/ DisableMetrics/DisableRecover 单独关闭。
  • 中间件形状type Middleware func(http.Handler) http.Handler,与 net/http 生态 完全同构——任何第三方中间件直接可用。内置构造器:Trace() / AccessLog() / Metrics() / Recover() / RateLimit(Limiter) / Auth(AuthFunc)
  • 鉴权web.Auth(web.StaticBearerToken(token))web.BearerToken(provider) (支持热轮换)。比对走 subtle.ConstantTimeCompare 防时序侧信道;未配置口令 → 503(fail-closed),带错/缺口令 → 401。

HTTP→RPC 桥(分布式 web 服务)

HTTP handler 经框架注入的 web.Backend 调用任意后端 service,不必裸写 net/http (若进程本身想"不伪装成 RPC 节点",用 WithClientOnly(),见下文):

func getPlayer(w http.ResponseWriter, r *http.Request) {
    backend, _ := web.BackendFromRequest(r)          // 框架自动注入的默认后端
    args := GetPlayerReq{PlayerId: r.PathValue("id")}
    var reply GetPlayerRes
    if err := backend.Invoke(r.Context(), "player", "GetPlayer", &args, &reply); err != nil {
        http.Error(w, err.Error(), http.StatusBadGateway)
        return
    }
    // 写 reply ...
}
  • WithHTTPService 装配时 Options.Backend 留空 → 框架自动注入默认后端 (defaultWebBackend):单进程命中 localDispatcher 走进程内直通,否则走 SendRPCMessageByStr 分布式路径。两条路径业务代码一样,且共用 E1 策略管道 (限流/熔断)+ A7 超时 + E3 埋点
  • traceId 全链路web.Trace 中间件注入的 traceId(入站 X-Trace-Id 复用, 否则新生成)会被写进 rpcx ReqMetaData,后端 service 内 trace.TraceIDFromContext(ctx) 读到的是同一个 id。
  • 业务也可注入自己的 web.Backend(如更丰富的 HTTP→RPC 编解码桥)替换默认实现。

完整可跑示例(含单进程 / 多进程两种部署):example/http_rpc/

与 RPC 共存 / client-only / Consul 注册

  • 与 RPC 共存:同一个 rpc.NewRPCServer()WithService(...) 注册游戏 service, 又 WithHTTPService(...) 起 HTTP 服务,二者同进程、同一条 D3 优雅停机序列。

  • client-only web 接入层:HTTP 进程用 WithClientOnly() + WithHTTPService(...) (或 WithHTTPServiceConsul(...))。WithClientOnly() 才是"不把自己伪装成 RPC 节点"的开关:不注册任何 service、不创建 rpcx server、不监听 rpcx 端口、不进入 RPC 服务发现,但照常初始化 Consul discovery + RPC client,所以 Backend.Invoke 经服务发现跨节点调游戏服。

    ⚠️ 常见误解:默认 Run() 即便不 WithService 任何 service,仍会创建 rpcx server、监听 ServicePort、并在 discovery 非 nil 时注册进 Consul——那仍是一个 RPC 节点,不是 client-only。client-only 语义只有显式调用 WithClientOnly() 才成立(它与 WithService / WithGateway* / WithoutServiceClient / WithoutConsul 互斥,RunvalidateClientOnly fail-fast)。

    从单进程平滑迁移到多进程分布式只改 server 构建那几行,handler 一字不改 (见 example/http_rpc/)。

  • HTTP 服务注册进 ConsulWithHTTPServiceConsul(opt, reg) = WithHTTPService + 把这个 HTTP 服务注册进 Consul(自动挂 health 路由、TTL 续约、Destroy 时摘除), 让"分布式 web 服务"可被标准 Consul 生态(DNS / API / fabio / traefik)发现与 负载均衡。详见下方「client-only + HTTP + Consul 注册:纯 web 接入进程」。

  • 优雅停机:HTTP 用独立 http.Server 实例(带 ReadHeaderTimeout 等超时,防 slowloris),挂进框架 Destroy 链;停机时先停 accept → drain in-flight HTTP 请求(http.Server.ShutdownShutdownTimeout)→ 再 drain RPC → 终末 flush

  • 脱离 rpc 单独用web.NewServer(opts).Start() / Shutdown(ctx) 可不依赖 rpc.Server 独立起一个 HTTP 服务(此时 Backend 需自行注入或不调后端)。

HTTP 一等公民 · Server builder API 清单

API作用
WithHTTPService(opt web.Options) *Server装载一个 HTTP 服务(注册 Consul)。可多次调用起多个端口。
WithHTTPServiceConsul(opt web.Options, reg HTTPRegistration) *Server装载 HTTP 服务并注册进 Consul(自动挂 health 路由 + TTL 续约 + Destroy 摘除),使分布式 web 服务可被发现/负载均衡。
WithClientOnly() *Server开启 client-only 模式:不注册 service、不创建 rpcx server、不监听 rpcx 端口,仅保留 RPC client(可调后端)+ HTTP 服务 + HTTP 的 Consul 注册。与 WithService / WithGateway* 互斥。

HTTPRegistrationWithHTTPServiceConsul 的第二参数)关键字段:

字段说明
ServiceName stringConsul service 逻辑名(发现/负载均衡检索键)。必填,为空则跳过注册(Error 日志提示)。
Address string显式对外可达地址 host:port。空 → 取 HTTP 实际监听地址(:0 随机端口也注册真实端口)。
HealthPath stringhealth endpoint 路径。空 → /health
HealthCheck func() error业务自检(如 Redis/MySQL ping),失败时 health 返 503 摘流量;nil → 端口活性级探活。
DisableHealthRoute bool已自行注册 health 路由或不需要 endpoint 时置 true。
UseHTTPCheck booltrue → Consul agent 主动 GET health;false(默认)→ TTL check(框架续约 goroutine 维持,容器/NAT 零配置可用)。
Interval / Timeout / DeregisterCriticalAfterTTL 续约周期 / HTTP 探测超时 / critical 后自动摘除时长。
Tags []string / Meta map[string]string透传到 Consul service。

client-only + HTTP + Consul 注册:纯 web 接入进程

一个无状态 REST 接入进程:自身注册成 RPC 节点(WithClientOnly),只对外提供 HTTP,并把这个 HTTP 服务注册进 Consul(可被发现/负载均衡),handler 经 web.Backend 跨节点调后端游戏 service:

package main

import (
    "github.com/thkhxm/tgf/v2/rpc"
    "github.com/thkhxm/tgf/v2/web"
)

type GetPlayerReq struct{ PlayerId string }
type GetPlayerRes struct {
    PlayerId string
    Level    int
}

func main() {
    rpc.NewRPCServer().
        // client-only:不伪装成 RPC 节点(不注册 service、不监听 rpcx 端口),
        // 但初始化 RPC client,可经服务发现调后端。
        WithClientOnly().
        // 装载 HTTP 服务并把它注册进 Consul(带 health 路由 + TTL 续约)。
        WithHTTPServiceConsul(web.Options{
            Addr: ":8091",
            Routes: func(r *web.Router) {
                // web.RPC[Req,Res] 泛型 handler:HTTP body ⇄ 后端 module.method,
                // 内部经 web.Backend 跨节点调 player.GetPlayer。
                r.POST("/api/player", web.RPC[GetPlayerReq, GetPlayerRes]("player", "GetPlayer"))
            },
        }, rpc.HTTPRegistration{
            ServiceName: "player-web", // Consul 逻辑名
            // 其余字段取默认:TTL check、/health 路由、本机出口 IP + 实际端口注册。
        }).
        Run()
}

要点:

  • client-only 不是"少 WithService":默认 Run()WithService 任何 service 时仍会创建 rpcx server、监听 ServicePort 并注册进 Consul——必须显式 WithClientOnly() 才真正不伪装成 RPC 节点。
  • 不需要把 HTTP 服务注册进 Consul(如前面有外部 LB / 网关),把 WithHTTPServiceConsul(opt, reg) 换成 WithHTTPService(opt) 即可,其余不变。
  • handler 也可不用泛型 web.RPC,而在普通 http.HandlerFuncweb.BackendFromRequest(r)Backendbackend.Invoke(ctx, module, method, &args, &reply) 手动调用(见 example/http_rpc/)。

配置项

配置项(env)默认值说明
HTTPPort8090WithHTTPService 未显式指定 Addr 时的监听端口
HTTPReadHeaderTimeoutSec5读请求头超时(秒,防 slowloris)
HTTPShutdownTimeoutSec10优雅停机 drain 超时(秒)

登记于 tgf/config.HTTPConfigdefine.goEnvironment 常量; Options 的零值字段在 Run 时按这些配置项与 web 包默认值填充。


核心架构

┌───────────────────────────────────────────────────────────────┐
│  业务侧 Module(IService + Hooks + StateHandler)             │
└───────────────────────────┬───────────────────────────────────┘

┌───────────────────────────▼───────────────────────────────────┐
│  Server Builder (rpc.NewRPCServer)                           │
│  ├── WithSingleProcess / WithStandalone (C1/C8)              │
│  ├── WithGatewayOptions (C1) / WithGatewayKCP (A8)           │
│  ├── WithHTTPService (G1) ── HTTP 一等公民                    │
│  ├── WithMethodPolicy (C6) / WithMetrics (B4) / WithTracer   │
│  └── WithHealthCheck (A6)                                    │
└───────────────────────────┬───────────────────────────────────┘

   ┌───────────────┬────────┴───────────────┬───────────────────┐
   │               │                        │                   │
┌──▼───────────┐ ┌─▼──────────────┐  ┌──────▼─────────────────┐ │
│ HTTP (web/)  │ │  Gateway        │  │  RPC Server            │ │
│ ├ Router(G1) │ │  ├ TCP / WS/WSS │  │  ├ rpcx service registry│ │
│ ├ 中间件链   │ │  ├ KCP+AEAD(A8) │  │  ├ Consul discovery     │ │
│ ├ Backend桥  │─┼─→ IConn (A2)    │  │  ├ localDispatcher (C8) │ │
│ └ Shutdown   │ │  └ 登录锁 (A3)   │  │  └ MethodPolicy 管道(C6)│ │
└──┬───────────┘ └─┬──────────────┘  └──────┬─────────────────┘ │
   │               │                        │                   │
┌──▼───────────────▼────────────────────────▼───────────────────┐
│  Data Layer                                                   │
│  ├── autoCacheManager (write-behind, A1 + A1b FailureQueue)  │
│  ├── game_config (C5 hot reload + fsnotify)                  │
│  └── config/ (C3 struct-tag 驱动)                              │
└───────────────────────────────────────────────────────────────┘

HTTP(web/)是自包含层(不 import rpc,无 import 环);rpc.ServerWithHTTPService 把后端调用能力以 web.Backend 注入,HTTP handler 即可经桥 调任意后端 service(图中 HTTP → Gateway/RPC 的虚线)。

完整架构说明见 doc/architecture.md


功能清单

HTTP web 服务(G 档)

能力API说明
HTTP 服务构建器Server.WithHTTPService(web.Options{...})与 RPC 同进程共存,可多次调用挂多端口
路由web.Router GET/POST/PUT/DELETE/PATCH / Handle("GET /p/{x}", h)Go 1.22 ServeMux,路径参数 req.PathValue
路由分组r.Group(prefix, mws...) / r.Use(mws...)前缀 + 分组中间件
内置中间件Trace / AccessLog / Metrics / Recover / RateLimit / Auth链顺序外→内,可单独 Disable
限流web.NewTokenBucketLimiter(qps)E1 同款令牌桶,超限 429
鉴权web.Auth(web.StaticBearerToken(t)) / web.BearerToken(provider)constant-time + fail-closed
HTTP→RPC 桥web.BackendFromRequest(r).Invoke(ctx, module, method, &args, &reply)单进程直通 / 分布式选路,traceId 透传
优雅停机Run() + 框架 Destroy独立 http.Server + Shutdown(ctx) 带超时 drain
脱离 rpc 单用web.NewServer(opts).Start() / Shutdown(ctx)不依赖 rpc.Server 独立起 HTTP

网关与连接

能力API说明
TCP / WS / WSS / KCP 网关WithGatewayOptions(GatewayOptions{TCPPort, WSPath, WSTLSKey, WSTLSCert, KCP})统一入口,按需组合
KCP + AEADNewKCPBuilder(port).WithAEADKey(key)ChaCha20-Poly1305 帧加密
踢人 / 重复登录loginCoord 接口Redis 锁 + 定向踢远端
健康心跳`WithHealthCheck(interval)$\text{F2} 已接真实 \text{Consul} \text{TTL} \text{check}(\text{Consul} 开启且注册成功时默认 5\text{s} 自动启用,\text{TTL}=3 \times \text{interval},节点宕机自动摘除)
单进程模式$WithSingleProcess()`反射直通,零 Consul

数据缓存

能力API说明
泛型自动缓存NewAutoCacheBuilder[Key, Val]()builder 配置内存 / Redis / MySQL 三级
快捷入口NewDefaultAutoCacheManager / NewLongevityAutoCacheManager常用配置预设
基础 KV / Map / Listdb.Get / Set / GetMap / PutMap / GetList / AddListItemRedis 操作
分布式锁db.NewLock(key) + db.UnLock(lock)基于 bsm/redislock
补偿队列(A1b)FailureQueue + ReplayFailureQueue落库失败跨重启恢复

RPC 调用

能力API说明
同步调用SendRPCMessage[Req, Res](ctx, api)带超时 + 策略检查
单向调用SendNoReplyRPCMessage后台执行
异步调用SendAsyncRPCMessage返回 Call
指定地址SendNoReplyRPCMessageByAddress跨节点定向
方法策略WithMethodPolicy / SetMethodPolicyTimeout + 限流 + 熔断 + 并发

可观测性

能力API说明
指标metrics.NewCounter / NewGauge / NewHistogram接口 + NoOp 默认
Provider 切换Server.WithMetrics(p)业务注入 Prometheus adapter
追踪trace.StartSpan(ctx, name)接口 + NoOp 默认
Tracer 切换Server.WithTracer(t)业务注入 OpenTelemetry adapter
框架内建埋点tgf_gate_connections / tgf_rpc_latency_ms 等 7 个自动触发

日志

能力API说明
Sprintf 风格log.InfoTag(tag, msg, params...)v1 兼容
zap.Field 风格(v2 推荐)log.InfoTagW(tag, msg, zap.Field...)零分配热路径
Tag 过滤log.CheckLogTag(tag)LogIgnoredTags 环境变量控制
分类日志log.Game / DB / Service写到独立文件

配置

能力API说明
环境变量加载config.Load()struct tag 驱动
当前快照config.Current()原子读
热更config.Reload() + OnReload(fn)业务侧手动调用,或经 admin 控制面 POST /config/reload 触发(ServeAdmin 启用,需 ADMIN_TOKEN);Reload 会先重读 .env.<module> 文件(文件值覆盖进程 env),旧 tgf.GetStrConfig 同步读到新值
游戏配置component.GetGameConf[Val](id)泛型查询
游戏配置热更component.ReloadGameConf() + StartConfigWatcher()手动调用 / fsnotify 目录监听

示例项目

example/ 目录下有 11 个可独立运行的示例,覆盖 tgf v2 的各个模块:

目录演示内容
http_rest/纯 REST API(WithHTTPService + 路由/中间件/限流/鉴权/优雅停机)——常规 http web 服务
http_rpc/REST + 调游戏服 RPC(HTTP→RPC 桥 + traceId 全链路 + 单/多进程部署)——分布式 web 服务
single_process/单进程多 Module + 跨 module RPC + 策略 + metrics
robot_test/WS + KCP robot 自测(登录 + 多人移动同步,QPS ~200 万)
db_cache/AutoCacheBuilder + Redis KV/Map/List + 分布式锁 + 补偿队列
log_usage/Sprintf vs zap.Field 风格 + Tag 过滤 + 分类日志
config_reload/struct tag 加载 + Reload + OnReload + 类型校验
metrics_trace/Counter / Gauge / Histogram + Span + TraceID
game_config/JSON 游戏配置 + ReloadGameConf + fsnotify watcher
rpc_policy/限流 / 熔断 / 并发控制 三场景
util_tools/协程池 + Snowflake + 随机数 + 类型转换

直接运行

cd tgf/example/single_process
go run .

大部分示例不需要外部服务(Redis/MySQL 缺失时静默跳过),go run . 即可。


文档

文档说明
doc/architecture.mdv2 完整架构图 + 关键包索引 + 流程说明
doc/migration-v1-to-v2.mdv1 → v2 迁移指南 + 升级 checklist
doc/observability.mdPrometheus / OpenTelemetry / Loki 接入指南
CHANGELOG.md完整变更日志

外部链接


技术选型

Go 工具链:Go 1.26+(v3 升级到最新稳定线,go.mod 声明 go 1.26.0 / toolchain go1.26.4

类别版本用途
RPCthkhxm/rpcxfork 自 smallnest/rpcx,已迁移为自有 module path 直接 require底层 RPC 引擎
服务发现thkhxm/rpcx-consulfork 自 rpcxio/rpcx-consul,已迁移为自有 module path 直接 requireConsul 适配
缓存go-redis/v9v9.7.0Redis 客户端
分布式锁bsm/redislockv0.9.4基于 Redis 的锁
数据库go-sql-driver/mysqlv1.9.3MySQL 驱动
日志zapv1.27.1结构化日志
日志切割lumberjack.v2v2.2.1滚动归档
并发ants/v2v2.12.0协程池
JSONsonicv1.15.0高性能 JSON
线程安全集合cornelk/hashmapv1.0.8无锁 map
ID 生成bwmarrin/snowflakev0.3.0Snowflake
一致性哈希edwingeng/doublejumpv1.0.1jump consistent hash
KCP(A8 新增)xtaci/kcp-gov5.4.20可靠 UDP 传输
文件监听(C5 新增)fsnotifyv1.9.0配置目录 watcher
环境变量godotenvv1.5.1.env 文件加载
WebSocketgorilla/websocketv1.5.3WS 服务端/客户端
Excelexcelize/v2v2.10.1Excel 读写

社区与交流

  • QQ 交流群:7400585
  • Issues:欢迎通过 GitHub Issues 提 bug 报告和功能建议
  • PR:fork → 新建 feature/xxx 分支 → 提交 PR

贡献指南

  1. 阅读 doc/architecture.md 了解架构
  2. 查看 doc/migration-v1-to-v2.md 了解 API 约定
  3. 运行 make testgo test -race ./... 确认测试通过
  4. 新增功能请同时补单元测试和示例

路线图

  • ✅ v2-alpha:A / B / C 档落地(稳定性修复 + 工程化 + API 演进),265 个测试
  • v3-D 档:止血与发布可用(已随 v2.0.0 发布)——消灭 P0(串包、单进程网关、 优雅停机、下游可消费、凭据卫生、登录鉴权地基),让框架"对外存在"
  • v3-E 档:接线收尾(已随 v2.0.0 发布)——策略管道全覆盖、配置系统收敛、 可观测性落地、数据层故障路径
  • v3-F 档:生产化地基(已随 v2.0.0 发布)——fork 治理(rpcx / rpcx-consul 迁移 为带 /v2 后缀的自有 module path)、Consul TTL check、会话与踢人收尾、过载保护
  • v3-G 档:HTTP 一等公民(已随 v2.0.0 发布)——WithHTTPService + 路由/中间件/ 限流/鉴权 + HTTP→RPC 桥 + 共享 D3 优雅停机,把"常规 http web 服务 / 分布式 web 服务 / 分布式游戏服务"三场景讲清
  • 📅 更远期(v2.x 后续小版本):
    • DB 层真正的分库分表(sqlBuilder 重构)
    • OpenTelemetry / Prometheus adapter 官方 subpackage

License

MIT License — 见 LICENSE


tgf v2.0.0 · 最后更新 2026-06-11