Nakama × Kubernetes:构建高可用游戏服务器集群的完整实战
2026/9/12 1:48:22 网站建设 项目流程

Nakama × Kubernetes:构建高可用游戏服务器集群的完整实战

【免费下载链接】nakamaScalable open-source game backend server: multiplayer, matchmaking, leaderboards, chat, and social features for games.项目地址: https://gitcode.com/GitHub_Trending/na/nakama

开服当天,连接池先炸了

新游戏 10 点开服,第一小时在线数翻了前三倍。VM 上那个单进程 Nakama 开始陆续拒绝 WebSocket 连接,数据库连接池告警刷屏,扩容还得手动把二进制拷到另一台机器再调流量。Nakama 是开源游戏服务器后端,如果你希望它随流量弹性伸缩,就得在 Kubernetes 上以集群方式跑起来。这场线上事故的解法,就是本文要展开的全部内容:把扩容、自愈、观测交给平台,开服不再靠人肉。

单机形态为什么撑不住:三个瓶颈对比

瓶颈可以归纳成三条。

  1. 横向扩容难。Nakama 的计算部分本身是无状态的——玩家状态都落在数据库里——但单机部署意味着进程 CPU/内存就是容量上限,加机器=重新部署。
  2. 数据库与应用强耦合。按 docker-compose.yml 那种单机编排思路,数据库和应用同机起停,数据库抖一下全链路跟着抖,也无法独立升级。
  3. 没有自愈机制。进程 OOM 或 panic 后没人拉起,只能等 oncall 发现。

📊 两种形态放在一起看差异更清楚:

维度单机进程K8s 集群
横向扩容手工迁移、改配置Deployment 副本数 + HPA 自动
数据库与同机应用绑定独立 CockroachDB 三副本,解耦部署
故障恢复人工重启探针判定 + 自动重建 Pod
发布需要停服窗口滚动更新,流量不中断
流量入口单 IP + 手工反代Service + Ingress 声明式
可观测性看日志文件9100 端口暴露 Prometheus 指标

集群拓扑:数据面与观测面两个平面

把整个部署切成两个平面来理解:数据面负责玩家流量,从入口到 Nakama 副本池再到数据库;观测面不承载业务,只负责从每个副本的 9100 端口拉指标。

数据面的关键是副本池里的每个 Pod 都可以随时被替换,因为会话 token、存储对象这些状态全部落在 CockroachDB 里;观测面独立部署,Nakama 挂了也能看到它是怎么挂的。

分层落地:从存储到观测

存储层:用 Helm 拉起三副本 CockroachDB 集群

CockroachDB 兼容 PostgreSQL 协议,官方 chart 已经处理好 StatefulSet、持久化和副本同步,我们只负责选参数。下面这条命令部署三副本集群,参数含义如下:--set statefulset.replicas=3保证数据库自身多副本、无单点;--set storage.persistentVolume.size=100Gi为每副本预留数据卷空间;--namespace nakama-system让数据库与应用共用命名空间,简化网络策略。

helm repo add cockroachdb https://charts.cockroachdb.com/ helm install cockroachdb cockroachdb/cockroachdb \ --set statefulset.replicas=3 \ --set storage.persistentVolume.size=100Gi \ --namespace nakama-system

计算层:把 Nakama Pod 做成标准件

配置先外置成 ConfigMap,副本里只保留四个关键项——数据库地址、会话 token 有效期、指标端口、日志级别。这份 docker-compose.yml 里以命令行参数下发的配置,在这里全部挪进配置文件,方便后续用 K8s 手段统一变更。

apiVersion: v1 kind: ConfigMap metadata: name: nakama-config namespace: nakama-system data: nakama.yaml: | database: address: "root@cockroachdb-public:26257" session: token_expiry_sec: 7200 metrics: prometheus_port: 9100 logger: level: "DEBUG"

🖥️ Deployment 部分体现"标准件"思路:容器启动时先执行数据库迁移再拉起服务,保证每个副本的 schema 版本一致;liveness 探针负责"死了就重启",readiness 探针负责"没准备好就不接流量",两者配合实现自愈。

apiVersion: apps/v1 kind: Deployment metadata: name: nakama namespace: nakama-system spec: replicas: 3 selector: matchLabels: app: nakama template: metadata: labels: app: nakama spec: containers: - name: nakama image: registry.heroiclabs.com/heroiclabs/nakama:3.30.0 command: ["/bin/sh", "-c"] args: - | /nakama/nakama migrate up --database.address $(DB_ADDRESS) && exec /nakama/nakama --config /config/nakama.yaml env: - name: DB_ADDRESS value: "root@cockroachdb-public:26257" ports: - containerPort: 7350 # API - containerPort: 7351 # 控制台 - containerPort: 9100 # Prometheus 指标 volumeMounts: - name: config-volume mountPath: /config livenessProbe: exec: command: ["/nakama/nakama", "healthcheck"] initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: exec: command: ["/nakama/nakama", "healthcheck"] initialDelaySeconds: 5 periodSeconds: 5 volumes: - name: config-volume configMap: name: nakama-config

运行时模块目录如果需要持久化(Lua 脚本、Go 模块等),再挂一个 PVC 到/nakama/data/modules即可:

volumes: - name: modules persistentVolumeClaim: claimName: nakama-modules volumeMounts: - name: modules mountPath: /nakama/data/modules

接入层:API 与控制台为什么要拆两个域名

7350 是玩家 API,高并发、面向公网;7351 是运维控制台,低频但敏感(账户管理、ACL、MFA)。拆两个域名后,控制台可以单独收紧访问来源、上更严格的限流和认证策略,不会被玩家流量策略牵连。Service 只负责按标签转发,Ingress 负责按域名分发。

apiVersion: v1 kind: Service metadata: name: nakama namespace: nakama-system spec: selector: app: nakama ports: - port: 80 targetPort: 7350 name: api - port: 7351 targetPort: 7351 name: console --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nakama namespace: nakama-system annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: api.nakama.example.com http: paths: - path: / pathType: Prefix backend: service: name: nakama port: name: api - host: console.nakama.example.com http: paths: - path: / pathType: Prefix backend: service: name: nakama port: name: console

弹性与观测层:HPA 双指标 + ServiceMonitor

弹性(HPA,HorizontalPodAutoscaler,即根据指标自动加减副本)和观测放在同一层,因为扩缩容的输入就是指标。HPA 这里配了双指标:CPU 利用率 70% 是兜底,防止"会话少但计算重"的场景扩不动;nakama_active_sessions是业务指标,每个 Pod 平均 1000 个会话就触发扩容,直接对齐玩家规模。

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nakama namespace: nakama-system spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nakama minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Pods pods: metric: name: nakama_active_sessions target: type: AverageValue averageValue: 1000

📈 ServiceMonitor 是 Prometheus Operator 的 CRD,作用是声明"去哪抓指标",比手写 scrape 配置更贴合 K8s 标签体系。Nakama 的指标路径是/,端点对应 9100 端口:

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: nakama namespace: monitoring spec: selector: matchLabels: app: nakama endpoints: - port: metrics path: / interval: 15s

指标落到 Prometheus 后接上 Grafana,副本数、会话数、错误率就都有了面板,集群的高可用不再停留在设计图上。

验收:健康检查 + 1000 并发压测

部署完成后按顺序做两步验收。第一步,在任意一个 Nakama Pod 里跑健康检查,确认服务与数据库链路都通了:

kubectl exec -it <nakama-pod-name> -n nakama-system -- /nakama/nakama healthcheck

预期输出:

OK: Nakama server is healthy

第二步,用官方压测工具对集群做 1000 并发验证:

go install github.com/heroiclabs/nakama-cli/v2@latest nakama-cli loadtest --address api.nakama.example.com --concurrency 1000 --duration 5m

🚀 压测时重点盯nakama_active_sessions:它必须随并发量爬升(说明指标真实),且在 HPA 的 averageValue=1000 附近触达时副本数应当自动增长;同时看 API 响应 P99 延迟是否保持在可接受区间。控制台侧也可以在 API 页面交叉核对调用统计。

排障手册:两个高频事故

症状:健康检查不过 → 动作:先查数据库连通性

healthcheck 失败绝大多数情况是到 CockroachDB 的链路问题(网络策略、DNS、端口),而不是 Nakama 本身。起一个临时 Pod 做连通性自查:

kubectl run test --image=postgres:14 -it --rm -- psql -h cockroachdb-public.nakama-system -U root -p 26257

连不上就先查 NetworkPolicy 和 Service DNS,连得上再回头查 Nakama 日志。

症状:跨实例会话不一致 → 动作:确认共享密钥已统一

多实例部署下,会话 token 的加解密密钥必须由所有副本共享,否则 A 实例签发的 token 到 B 实例验不过。自查当前 ConfigMap 里的配置:

kubectl -n nakama-system get cm nakama-config -o yaml | grep encryption_key

若缺失,把session.encryption_key加进 ConfigMap(所有副本使用同一个值),再滚动重启 Deployment。

演进路线:集群跑起来之后的四件事

  • 蓝绿 / 金丝雀发布:用两套副本集加流量切分,把"停服更新"变成"无感切换"。
  • 数据库读写分离:分析型查询(排行榜聚合、审计)走从库,降低主库压力。
  • 服务网格(如 Istio):在 Pod 之间加细粒度流量控制、超时与重试。
  • CI/CD 流水线:镜像构建、migrate 灰度、滚动发布全部自动化。

可以马上做的两件事:把 HPA 的minReplicas按你的玩家基线调到 3 以上并kubectl apply;为 9100 端口补一条告警规则(指标 5 分钟无数据即触发),观测面从此闭环。后续版本演进与破坏性变更以 CHANGELOG.md 为准,升级前逐条过一遍。更多能力背景可回看 官方 README。

【免费下载链接】nakamaScalable open-source game backend server: multiplayer, matchmaking, leaderboards, chat, and social features for games.项目地址: https://gitcode.com/GitHub_Trending/na/nakama

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询