Skip to content

thkhxm/tgf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

443 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 string Consul service 逻辑名(发现/负载均衡检索键)。必填,为空则跳过注册(Error 日志提示)。
Address string 显式对外可达地址 host:port。空 → 取 HTTP 实际监听地址(:0 随机端口也注册真实端口)。
HealthPath string health endpoint 路径。空 → /health
HealthCheck func() error 业务自检(如 Redis/MySQL ping),失败时 health 返 503 摘流量;nil → 端口活性级探活。
DisableHealthRoute bool 已自行注册 health 路由或不需要 endpoint 时置 true。
UseHTTPCheck bool true → Consul agent 主动 GET health;false(默认)→ TTL check(框架续约 goroutine 维持,容器/NAT 零配置可用)。
Interval / Timeout / DeregisterCriticalAfter TTL 续约周期 / 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) 默认值 说明
HTTPPort 8090 WithHTTPService 未显式指定 Addr 时的监听端口
HTTPReadHeaderTimeoutSec 5 读请求头超时(秒,防 slowloris)
HTTPShutdownTimeoutSec 10 优雅停机 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 + AEAD NewKCPBuilder(port).WithAEADKey(key) ChaCha20-Poly1305 帧加密
踢人 / 重复登录 loginCoord 接口 Redis 锁 + 定向踢远端
健康心跳 WithHealthCheck(interval) F2 已接真实 Consul TTL check(Consul 开启且注册成功时默认 5s 自动启用,TTL=3×interval,节点宕机自动摘除)
单进程模式 WithSingleProcess() 反射直通,零 Consul

数据缓存

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

RPC 调用

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

可观测性

能力 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.md v2 完整架构图 + 关键包索引 + 流程说明
doc/migration-v1-to-v2.md v1 → v2 迁移指南 + 升级 checklist
doc/observability.md Prometheus / OpenTelemetry / Loki 接入指南
CHANGELOG.md 完整变更日志

外部链接


技术选型

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

类别 版本 用途
RPC thkhxm/rpcx fork 自 smallnest/rpcx,已迁移为自有 module path 直接 require 底层 RPC 引擎
服务发现 thkhxm/rpcx-consul fork 自 rpcxio/rpcx-consul,已迁移为自有 module path 直接 require Consul 适配
缓存 go-redis/v9 v9.7.0 Redis 客户端
分布式锁 bsm/redislock v0.9.4 基于 Redis 的锁
数据库 go-sql-driver/mysql v1.9.3 MySQL 驱动
日志 zap v1.27.1 结构化日志
日志切割 lumberjack.v2 v2.2.1 滚动归档
并发 ants/v2 v2.12.0 协程池
JSON sonic v1.15.0 高性能 JSON
线程安全集合 cornelk/hashmap v1.0.8 无锁 map
ID 生成 bwmarrin/snowflake v0.3.0 Snowflake
一致性哈希 edwingeng/doublejump v1.0.1 jump consistent hash
KCP(A8 新增) xtaci/kcp-go v5.4.20 可靠 UDP 传输
文件监听(C5 新增) fsnotify v1.9.0 配置目录 watcher
环境变量 godotenv v1.5.1 .env 文件加载
WebSocket gorilla/websocket v1.5.3 WS 服务端/客户端
Excel excelize/v2 v2.10.1 Excel 读写

社区与交流

  • 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

About

​ tgf框架是使用golang开发的一套游戏分布式框架.项目采用了rpcx做为底层rpc的通讯,consul提供服务注册发现.定义了一整套的模块开发规范.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors

Languages