ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Colyseus 与 Traefik 集成指南:基于 @colyseus/traefik 的动态负载均衡接入

Colyseus 与 Traefik 集成指南:基于 @colyseus/traefik 的动态负载均衡接入 后端游戏开发【免费下载链接】colyseus⚔ Multiplayer Framework for Node.js项目地址https://gitcode.com/gh_mirrors/co/colyseus点击查看免费下载本指南围绕 Colyseus 官方包colyseus/traefik位于仓库packages/traefik展开讲解如何把多进程 / 多节点的 Colyseus 游戏服务器自动注册到 Traefik 反向代理实现 WebSocket 与 HTTP 的动态负载均衡。读完本文你将掌握exposeServerToTraefik()的完整配置项、HTTP Provider 与 Redis Provider 两种接入方式的差异、publicAddress与internalAddress的解析规则以及通过 Redis 键空间通知或/__traefikHTTP 端点动态下发路由配置的落地方法。一、为什么需要 TraefikColyseus 的水平扩展场景Colyseus 是 Node.js 的多人在线游戏框架一个进程通常只能承载有限数量的房间。当需要横向扩容时多台服务器节点会各自监听不同端口或运行在不同主机上客户端必须知道该连哪台实例。Traefik 作为反向代理与负载均衡器负责把进入的请求按规则分发到正确的节点而colyseus/traefik包源码见 packages/traefik/src/index.ts负责把每一台 Colyseus 服务器的路由信息告诉 Traefik。从源码看这个包的核心职责非常聚焦调用exposeServerToTraefik()后它会在 Redis 中写入一组traefik/http/routers/*与traefik/http/services/*的键值对或在服务器上暴露一个/__traefikHTTP 端点两种方式都让 Traefik 能动态发现当前进程提供的服务见 exposeServerToTraefik 实现。包内自带的三个 Traefik 配置模板直观展示了三种集成形态见 packages/traefik 目录traefik-redis-provider.ymlRedis Provider路由信息由 Colyseus 直接写入 RedisTraefik 从 Redis 动态读取traefik-http-provider.ymlHTTP ProviderTraefik 轮询 Colyseus 的/__traefik端点获取配置traefik-manual-hardcoded.yml纯手工硬编码配置用于理解最终生成的配置长什么样也是对比动态 vs 静态的最佳参照。二、colyseus/traefik 包概览与版本演进2.1 包的基本信息依据 packages/traefik/package.json包名colyseus/traefik当前版本 0.18.3描述把 Colyseus 服务器暴露给 Traefik 作为负载均衡后端的工具运行时要求engines.node 22.x与 CHANGELOG 中 0.18.2 Requires Node 22 一致依赖colyseus/core与colyseus/redis-presenceworkspace 内联依赖这说明本包天然假定你的服务器已经启用RedisPresence导出方式同时提供 ESMbuild/index.mjs与 CJSbuild/index.cjs且require()与import解析到同一个 ESM 构建产物避免双加载。2.2 版本演进依据 packages/traefik/CHANGELOG.md0.18.3修复require()与import加载两份模块副本的问题对应 issue #979进程内两种引入方式共享同一构建0.18.2要求 Node 22 及以上0.17.7为internalAddress增加 IPv6 支持接受带方括号形式[::1]:2567与裸形式fd12::1并保证注册的 URL 正确加括号autoDetectInternalIP()在无可用 IPv4 路由时回退到第一个非内部、非链路本地link-local的 IPv6 地址——这正是为 Railway 等纯 IPv6 私有网络场景设计的0.17.6首个 changelog 条目。可见这是一个围绕自动探测 动态下发持续打磨的集成层IPv6 支持与双模块加载修复是最近几个版本的重点。三、核心 APIexposeServerToTraefik()完整配置说明函数签名与全部选项定义在 packages/traefik/src/index.ts#L5-L49。它接收一个TraefikOptions对象各字段如下配置项类型是否必填默认值说明serverServer必填无要暴露给 Traefik 的 ColyseusServer实例providerhttp \| redis可选redis配置下发方式经 Redis 直读或经/__traefikHTTP 端点mainAddressstring必填无主 Traefik 负载均衡器地址例如backend.yourgamedomain.cominternalAddressstring可选自动探测服务器内部地址端口可省略自动取服务器端口支持 IPv4 / IPv6redisRootKeystring可选traefikRedis 中 Traefik 配置的根键前缀healthCheckOptions{ path, interval, timeout }可选{ path: /__healthcheck, interval: 10s, timeout: 3s }健康检查选项仅在 redis provider 下写入3.1 必填项校验源码确认调用后函数会立即做一组前置校验见 index.ts#L70-L85不满足会抛出明确错误mainAddress缺失 →mainAddress is required. Use the Traefik load balancer address.server.options.publicAddress缺失 →publicAddress server option is required.内部端口无法确定 →port is required. Use process.env.PORT or call server.listen(port) before calling exposeServerToTraefik().matchMaker.presence不是RedisPresence实例 →presence must be using RedisPresence.使用 redis provider 时若 Redis 未开启键空间通知keyspace notifications→ 抛出错误提示参考 Valkey 官方通知配置文档。这意味着使用本包前你的服务器必须通过server.listen(port)或process.env.PORT确定端口、在Server选项中设置publicAddress并把presence换成RedisPresence。3.2 内部地址的优先级与自动探测内部地址解析顺序见 index.ts#L59-L61显式传入options.internalAddress未传时调用autoDetectInternalIP()实现见 index.ts#L234-L251优先取第一个非 internal 的 IPv4 地址没有路由 IPv4 时回退到第一个非 internal、非 link-local不以fe80开头的 IPv6 地址——对应 CHANGELOG 0.17.7 中提到的 Railway 等纯 IPv6 私有网络场景兜底为127.0.0.1。端口取值internalAddress中携带的端口优先否则回退到server[port]再回退到process.env.PORT。3.3 调用位置与生命周期调用时机应在server.listen(port)之后调用示例工程在 packages/example/src/app.config.ts#L372-L380 中展示了先listen再调用exposeServerToTraefik的注释示例优雅退出函数内部通过server.onShutdown(...)注册清理逻辑见 index.ts#L119-L134进程关闭时删除本节点对应的 router 与 service 键避免僵尸配置残留provider http 的额外行为会通过server.router.addEndpoint注册GET /__traefik端点见 index.ts#L136-L142供 Traefik 轮询。四、两种 Provider 的工作方式4.1 Redis Provider默认流程Colyseus 节点把自身路由写入 Redis → Traefik 通过 Redis Provider 读取并动态更新路由。写入的键结构以redisRootKey traefik为例traefik/http/routers/{subdomain}/rule→ 形如Host(\node-1.example.com)或附加PathPrefix(/2567) 的规则traefik/http/routers/{subdomain}/service→ 该节点的 service 名traefik/http/services/{subdomain}/loadbalancer/servers/{subdomain}/url→ 该节点的内部 URL如http://192.168.1.100:2567同时写入all-servers集合traefik/http/services/all-servers/loadbalancer/servers/{subdomain}/url把所有节点汇总到一个负载均衡组redis provider 下还会写入每个 service 的健康检查三项path、interval、timeout。对应 Traefik 侧配置见 traefik-redis-provider.yml其中providers.redis.rootKey: traefik必须与redisRootKey默认值一致endpoints指向 Colyseus 使用的同一 Redis。前提Redis/Valkey 必须开启键空间通知源码在调用前会用psubscribe(__keyevent0__:expired)并写入一个 1 秒过期的test键来探测见 index.ts#L300-L319超时 1100ms 未收到事件即判定未开启并抛错。4.2 HTTP Provider流程Colyseus 把同样的信息写入 Redis → 但由本包在服务器上暴露GET /__traefik端点把 Redis 中的键值组装成 Traefik 的 HTTP Provider JSON → Traefik 按pollInterval轮询该端点。配置示例见 traefik-http-provider.ymlproviders: http: endpoint: http://127.0.0.1:2567/__traefik pollInterval: 5s端点背后的组装逻辑在getTraefikConfigFromRedis()见 index.ts#L149-L214通过底层 ioredis 客户端的keys()与mget()读取全部traefik/*键按http.routers/http.services两类路径解析组装出形如{ http: { routers: { all-servers: { entryPoints: [web], rule: Host(backend.yourgamedomain.com), service: all-servers } }, services: { all-servers: { loadBalancer: { servers: [{ url: http://192.168.1.100:2567 }] } } } } }值得注意的是即使使用 HTTP providerRedis 依然承担中间存储的角色两者都依赖RedisPresence区别只在于 Traefik 获取配置的通道不同。健康检查选项在 HTTP provider 下通过options.healthCheckOptions注入到组装出的loadBalancer.healthCheck中。4.3 手工硬编码配置对照参考traefik-manual-hardcoded.yml 展示了不依赖本包时手工写死的路由node-1/node-2各自一个 serviceall-servers汇总两个节点的 URL。它与动态方式生成的结构完全对应适合理解最终目标形态或做小规模验证。五、subdomain 命名与路由规则生成5.1 subdomain 的推导publicAddress是Server选项格式形如node-1.example.com也可带路径如测试中的localhost/25678。源码取publicAddress后用.replace(/, _)把路径分隔符替换为下划线再按.切分取第一段作为 subdomain。例如node-1.example.com→node-1localhost/25678→localhost_25678。测试用例 packages/traefik/test/traefik.test.ts#L35-L40 验证了该规则publicAddress: localhost/25678时生成的 router 键为localhost_25678。该 subdomain 同时用作 router 名、service 名与 Redis 键中的服务器标识。5.2 Traefik 规则的构建buildTraefikRule()见 index.ts#L216-L227若地址不含://则自动补http://前缀规则 Host(\{hostname})若 URL 还有非根路径追加PathPrefix(\{pathname})两者用 连接。测试验证了两个典型产物见 traefik.test.ts#L30-L40mainAddress: localhost→Host(\localhost)publicAddress: localhost/25678→Host(\localhost) PathPrefix(/25678)。六、internalAddress解析规则与 IPv6 支持parseHostPort()见 index.ts#L267-L287支持的输入形态与 packages/traefik/test/traefik.test.ts#L56-L66 的用例一一对应输入解析结果host / port最终 URL假设端口 2567192.168.1.1192.168.1.1/ 无http://192.168.1.1:2567192.168.1.1:9999192.168.1.1/9999http://192.168.1.1:9999localhost:2567localhost/2567http://localhost:2567::1::1/ 无2 冒号视为纯 IPv6http://[::1]:2567fd12:3456:abcd::1host / 无http://[fd12:3456:abcd::1]:2567[::1]:9999::1/9999http://[::1]:9999[fd12:3456:abcd::1]:2567host /2567http://[fd12:3456:abcd::1]:2567关键规则以[开头时必须存在配对的]否则报Invalid bracketed address (missing ])2 个及以上冒号的裸地址按纯 IPv6 处理不拆分端口端口需用方括号包裹最终 URL 由buildInternalUrl()生成host 含冒号IPv6时用http://[host]:port包裹否则用http://host:port。这正是 CHANGELOG 0.17.7 提到的注册的 URL 正确加括号。七、健康检查配置默认值{ path: /__healthcheck, interval: 10s, timeout: 3s }见 index.ts#L66-L68。Redis provider直接以traefik/http/services/{service}/loadbalancer/healthcheck/{path|interval|timeout}三个键写入 Redis见 index.ts#L102-L110HTTP provider通过getTraefikConfigFromRedis()把healthCheckOptions注入到每个 service 的loadBalancer.healthCheck见 index.ts#L197-L203手工模式对应写法见 traefik-manual-hardcoded.yml#L43-L47 中被注释掉的healthCheck段。需要说明本包只负责把健康检查参数写入 Traefik 配置实际在/__healthcheck路径上返回健康状态的处理逻辑需要你在自己的服务器路由中实现例如此路径与 Colyseus 默认 health check 行为相关。八、完整接入步骤与最小示例8.1 环境准备Node.js 22一个已启用 RedisPresence 的 Colyseus 服务器presence: new RedisPresence()一个 Redis/Valkey 实例若使用 redis provider需开启键空间通知一台运行 Traefik 的代理节点。8.2 服务器侧接入HTTP Provider 示例参照测试中的用法traefik.test.ts#L10-L53import { Server } from colyseus/core; import { RedisPresence } from colyseus/redis-presence; import { WebSocketTransport } from colyseus/ws-transport; import { exposeServerToTraefik } from colyseus/traefik; const port 25678; const server new Server({ transport: new WebSocketTransport(), presence: new RedisPresence(), publicAddress: localhost/${port}, // 形如 node-1.example.com greet: false, }); await server.listen(port); await exposeServerToTraefik({ server, provider: http, // 或省略默认 redis mainAddress: localhost, // 负载均衡器入口地址 });调用后访问http://localhost:${port}/__traefik即可看到组装好的 JSON 配置测试中用它断言了http.routers、http.services、all-servers与localhost_25678的结构完整性。8.3 Traefik 侧配置Redis provider使用 traefik-redis-provider.yml并把providers.redis.endpoints指向同一 RedisHTTP provider使用 traefik-http-provider.ymlendpoint指向任意一个 Colyseus 节点的/__traefikpollInterval控制刷新频率两种配置都开启了 dashboardapi.dashboard: true、api.insecure: true入口点web: :80与websecure: :443。8.4 多节点扩展流程每台节点运行一个 Colyseus 进程各自server.listen(port)并设置publicAddress如node-1.example.com、node-2.example.com每台进程启动后调用exposeServerToTraefik({ server, mainAddress, provider })Traefik 侧自动出现每个节点的独立 router/service以及汇总的all-servers负载均衡组节点关闭时onShutdown清理对应 Redis 键或从/__traefik组装结果中消失Traefik 自动摘除后端。从源码结构可以推断all-servers的 router 规则只在第一个节点写入源码先get再按需set见 index.ts#L112-L117避免多节点重复写入这保证了主入口路由的幂等性。九、常见问题与注意事项presence必须是RedisPresence本包依赖matchMaker.presence读写 Redis使用LocalPresence会直接在校验阶段抛错。publicAddress不能省略它既用于生成 subdomain也用于构建 Traefik 的 Host 规则带端口/路径的形式如localhost/25678会转换成下划线命名并追加PathPrefix规则。Redis 必须开键空间通知redis provider否则初始化时探测失败并抛出异常HTTP provider 不依赖键空间通知但依赖 Redis 作为配置存储。IPv6 端口必须用方括号裸fd12::1:2567会被当作纯 IPv6 地址而非带端口地址带端口请写[fd12::1]:2567。调用顺序exposeServerToTraefik()需要在server.listen(port)之后调用否则无法确定内部端口。Node 版本colyseus/traefik0.18.x 要求 Node 22低于此版本会因engines约束无法正常使用。十、延伸阅读仓库内相关资源包源码与类型定义packages/traefik/src/index.ts集成测试覆盖 HTTP provider 与 IPv6 解析packages/traefik/test/traefik.test.ts三种 Traefik 配置模板traefik-redis-provider.yml、traefik-http-provider.yml、traefik-manual-hardcoded.yml版本演进记录packages/traefik/CHANGELOG.md示例工程中的调用位置注释形态packages/example/src/app.config.ts依赖的 Redis 实现packages/presence/redis-presence/src/index.ts结合本文与上述源码你可以在自己的多节点 Colyseus 部署中快速接入 Traefik实现节点自动注册、健康检查与优雅摘除的完整负载均衡链路。赞分享后端游戏开发【免费下载链接】colyseus⚔ Multiplayer Framework for Node.js项目地址https://gitcode.com/gh_mirrors/co/colyseus点击查看免费下载相关推荐Traefik 与 Docker基于容器标签的动态路由与负载均衡实战指南Traefik 与 Docker基于容器标签的动态路由与负载均衡实战指南 TraefikCloud Native Application Proxy最具代后端API网关负载均衡微服务网络云原生Traefik UDP Service 配置指南LoadBalancer 与 Weighted 负载均衡详解Traefik UDP Service 配置指南LoadBalancer 与 Weighted 负载均衡详解 UDP Service 是 Traefik 动态后端API网关负载均衡微服务网络云原生Wand-Enhancer5 步免费跑通 WeMod 本地增强与远程控制Wand Enhancer5 步免费跑通 WeMod 本地增强与远程控制 想调修改器参数却要离开沙发走到电脑前这事很常见。Wand Enhancer 是一桌面应用前端上一篇把PS Vita的内容管理主动权拿回来QCMA跨平台方案手记下一篇流放之路辅助工具 Lailloken-UI免费开源三分钟上手刷图效率真的能翻倍吗创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表