云原生游戏网关架构:EKS + APISIX + Graviton 构建高性能游戏服务网关

前言

在现代游戏运营环境中,随着游戏服务器规模的不断扩大,传统的服务器代理方案面临着诸多挑战。本文将介绍如何使用 API Six 这一高性能网关来解决大规模游戏服务器代理的问题,特别是针对需要使用多个 Network Load Balancer (NLB) 的场景,提供一个更加优雅和高效的解决方案。 在游戏服务架构中,我们经常遇到以下几个关键挑战:

1、 服务器规模问题

  • 随着游戏的成功运营,服务器数量可能从最初的几台扩展到成百上千台
  • 传统的使用多个 NLB 进行代理的方案在管理和维护上变得越来越复杂
  • 成本问题:每增加一个 NLB 都会带来额外的费用支出

2、 安全性考虑

  • 游戏服务器需要防护各种网络攻击
  • 传统的 TCP 协议缺乏足够的安全保护机制
  • 需要在不影响性能的前提下提供安全保障

3、运维复杂性

  • 多个 NLB 的配置管理较为繁琐
  • 服务器扩缩容时需要频繁调整负载均衡配置
  • 监控和故障排查的难度随着规模增加而增加

面对这些挑战,我们需要一个更现代化的解决方案。API Six 作为一个高性能、可扩展的网关,结合 TLS 加密,能够很好地解决这些问题。在接下来的内容中,我们将详细介绍如何使用 API Six 构建一个高效、安全、易于管理的游戏服务网关系统。

📢限时插播:在本次实验中,你可以在基于 Graviton 的 EC2 实例上轻松启动 Milvus 向量数据库,加速您的生成式 AI 应用。

⏩快快点击进入《创新基石 ------ 基于 Graviton 构建差异化生成式AI向量数据库》实验

📱 即刻在云上探索实验室,开启构建开发者探索之旅吧

架构介绍

1. 架构整体说明

APIsix核心组件运行于 Amazon EKS(Elastic Kubernetes Service)集群内部。整个系统主要分为两大访问入口:运维(Ops)和玩家(Players),分别通过独立的 ELB(Elastic Load Balancer)接入.(在此建议咱们在部署环境前可以先手动创建ELB, 在EKS中通过TargetGroupBinding的方式来进行绑定服务,这样可以保证后续服务变更时前端接入ELB为同一个.)

2. 流量入口

  • Ops(运维)入口 运维人员通过 ELB 访问 EKS 集群中的 Admin API,实现对平台的管理和监控。
  • Players(玩家)入口 玩家流量同样通过独立的 ELB 进入 EKS 集群,主要访问 API Gateway,进而路由到具体的游戏服务(Game Server)或平台服务(Platform Service)。

3. EKS 集群内部结构

  • Admin API 层 提供管理接口,供运维人员操作和管理整个系统。
  • etcd 层 作为分布式键值存储,负责服务发现、配置管理等核心功能。Admin API 会将变更写入 etcd,API Gateway 通过 watch 机制实时感知服务变化。
  • API Gateway 层 这一层是玩家访问的主要入口,API Gateway 负责根据 etcd 的服务发现信息,将玩家请求路由到后端的具体服务(如 Platform Service 或 Game Server)。
  • 业务服务层 包含平台服务(Platform Service)和多个游戏服(Game Server1、Game Server2 等),这些服务是最终处理玩家请求的核心业务组件。

方案部署

下面我们将逐步来验证整个方案, 方案中我们将采用模拟TCP协议的游戏服务,通过ELB来实现不同游戏服的路由功能.首先我们需要创建一个实验EKS集群, 参考 EKS文档 创建EKS.

创建好EKS后, 添加用户权限

然后创建Access Entry

使用Helm来安装部署APISix

本文采用的部署目标服务器为亚马逊云科技Graviton机型,可以帮助我们发挥APISix的最大性能. 参考步骤如下:

1、添加相关helm库

csharp 复制代码
helm repo add apisix https://charts.apiseven.com
helm repo update

2、整理apisix-values.yaml

yaml 复制代码
# Tolerations for Graviton nodes (if needed)
tolerations:
  - key: "kubernetes.io/arch"
    operator: "Equal"
    value: "arm64"
    effect: "NoSchedule"

# Affinity to prefer Graviton nodes
affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      preference:
        matchExpressions:
        - key: kubernetes.io/arch
          operator: In
### values:
          - arm64

3、执行命令更新服务

css 复制代码
helm install apisix apisix/apisix --create-namespace --namespace ingress-apisix \
--values apisix-values.yaml

4、如果此处部署有问题,一定要关注一下当前的storageclass是否存在.

yaml 复制代码
etcd:
  persistence:
    storageClass: efs-sc # 请格外注意此处,否则可能方案部署失败.

另推荐一个小技巧,如果部署出现问题,可以使用Amazon Q CLI来做诊断,整个过程完全自动化,下面是我的步骤截图.

部署 游戏服务

模拟游戏服代码

python 复制代码
 # Bind to all interfaces
    server.bind(('0.0.0.0', port))
    server.listen(5)
    
    print(f"[*] {server_name} listening on 0.0.0.0:{port}")
    
    try:
        while True:
            client, addr = server.accept()
            client_handler = threading.Thread(target=handle_client, args=(client, addr))
            client_handler.daemon = True
            client_handler.start()
    except KeyboardInterrupt:
        print(f"[{server_name}] Shutting down server")
        server.close()

if __name__ == "__main__":
    start_server(9000)

模拟EKS中的服务部署代码: test-server-1.yaml

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-server-1
  namespace: game
  labels:
    app: test-server-1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-server-1
  template:
    metadata:
      labels:
        app: test-server-1
    spec:
      containers:
      - name: tcp-server
        image: python:3.9-slim
        command: ["python"]
        args: ["-u", "/app/tcp-echo-server.py", "test-server-1"]
        ports:
        - containerPort: 9000
        volumeMounts:
        - name: script-volume
          mountPath: /app
      volumes:
      - name: script-volume
        configMap:
          name: tcp-echo-server
          defaultMode: 0777
---
apiVersion: v1
kind: Service
metadata:
  name: gs-1
  namespace: game
  labels:
    app: test-server-1
spec:
  selector:
    app: test-server-1
  ports:
  - port: 9000
    targetPort: 9000
    protocol: TCP
  type: ClusterIP 
test-server-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-server-2
  namespace: game
  labels:
    app: test-server-2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-server-2
  template:
    metadata:
      labels:
        app: test-server-2
    spec:
      containers:
      - name: tcp-server
        image: python:3.9-slim
        command: ["python"]
        args: ["-u", "/app/tcp-echo-server.py", "test-server-2"]
        ports:
        - containerPort: 9000
        volumeMounts:
        - name: script-volume
          mountPath: /app
      volumes:
      - name: script-volume
        configMap:
          name: tcp-echo-server
          defaultMode: 0777
---
apiVersion: v1
kind: Service
metadata:
  name: gs-2
  namespace: game
  labels:
    app: test-server-2
spec:
  selector:
    app: test-server-2
  ports:
  - port: 9000
    targetPort: 9000
    protocol: TCP
  type: ClusterIP

部署服务

vbscript 复制代码
kubectl create namespace game
kubectl create configmap tcp-echo-server --from-file=tcp-echo-server.py --namespace game
kubectl apply -f test-server-1.yaml
kubectl apply -f test-server-2.yaml

配置证书

当使用TLS的SNI功能时,每个你想要使用SNI的域名或主机名都需要一个有效的证书。这是因为SNI允许从同一个IP地址和端口提供多个主机名服务,而证书用于验证服务器的身份并与客户端建立加密连接。使用OpenSSL为2个Game Server服务生成证书文件和密钥文件。

1、生成证书

csharp 复制代码
openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout gs-1.key -out gs-1.crt -subj "/CN=gs-1.com"
openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout gs-2.key -out gs-2.crt -subj "/CN=gs-2.com"

2、上传证书到apisix

javascript 复制代码
kubectl port-forward -n ingress-apisix svc/apisix-admin 9180:9180 &
sleep 3
curl  -X POST http://127.0.0.1:9180/apisix/admin/ssls -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -d '
{
    "cert": "'"$(cat gs-1.crt)"'",
    "key": "'"$(cat gs-1.key)"'",
    "snis": ["gs-1.com"]
}'
# Create SSL certificate for gs-2.com
curl -X POST http://127.0.0.1:9180/apisix/admin/ssls -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'  -d '
{
    "cert": "'"$(cat gs-2.crt)"'",
    "key": "'"$(cat gs-2.key)"'",
    "snis": ["gs-2.com"]
}'
kill %1

3、验证证书上传

ruby 复制代码
curl -X GET http://127.0.0.1:9180/apisix/admin/ssls -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' 

配置路由

下面我们基于已经配置好的证书来配置相关的路由信息, 也就是通常我们在平台服配置好证书后,可以调用相关API来配置路由,命令信息如下:

vbnet 复制代码
kubectl port-forward -n ingress-apisix svc/apisix-admin 9180:9180 &
sleep 3
curl -i -X POST http://127.0.0.1:9180/apisix/admin/stream_routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -d '{
  "upstream": {
    "nodes": {
      "gs-1.game.svc.cluster.local:9000": 1
    },
    "type": "roundrobin"
  },
  "sni": "gs-1.com"
}'

curl -i -X POST http://127.0.0.1:9180/apisix/admin/stream_routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -d '{
  "upstream": {
    "nodes": {
      "gs-2.game.svc.cluster.local:9000": 1
    },
    "type": "roundrobin"
  },
  "sni": "gs-2.com"
}'

测试基于SNI的访问

首先获取对应APIsix服务的ALB地址

arduino 复制代码
> kubectl get svc -n ingress-apisix apisix-gateway
NAME             TYPE           CLUSTER-IP      EXTERNAL-IP                                                                     PORT(S)                       AGE
apisix-gateway   LoadBalancer   10.100.xxxx.12   k8s-ingressa-apisixga-xxxxxxx-xxx.elb.us-east-1.amazonaws.com   80:30496/TCP,8888:30694/TCP   3d2h

通过上面返回获取的ALB的地址

arduino 复制代码
openssl s_client -connect k8s-ingressa-apisixga-xxxxx.xxxx.elb.ap-northeast-1.amazonaws.com:8888 \
-servername gs-1.com -quiet
openssl s_client -connect k8s-ingressa-apisixga-xxxx.xxxx.elb.ap-northeast-1.amazonaws.com:8888 \
-servername gs-2.com -quiet

至此可以看到通过不同的SNI我就可以访问到不同的游戏服了,也就解决了使用同一个NLB+APIsix的访问不同的游戏服了.

APISix dashboard访问 (Optional)

我们也可以通过Dashboard来访问当前的APIsix系统,查看相关的配置数据. 不过这里需要我们确认一下ALB的certificate ARN 是不是正确.

kubectl get ingress -n ingress-apisix

APISix 部署亚马逊云科技最佳实践

在生产环境中部署 Apache APISIX 时的关键最佳实践,帮助提升稳定性、性能与可维护性。

核心架构与组件分离

为了保证系统可扩展与高可用,推荐将 APISIX 各核心组件解耦部署:

  • 控制平面(etcd):使用单独部署的 etcd 集群存储路由与插件配置,建议在部署APISix的时候直接指向预先部署好的etcd,至少部署 3 节点,开启数据持久化与快照备份,防止单点故障。
  • 数据平面(APISIX 节点):外部请求由多个 APISIX 实例处理,按需水平扩容。每个实例仅负责流量转发与插件执行,配置从 etcd 动态拉取。
  • 运维监控(Prometheus & Grafana):部署专用的监控系统,采集 APISIX 及 etcd 的指标与日志,实时告警与可视化。

部署模式与扩展策略

  • 无状态部署 APISIX 实例本身应保持无状态,所有动态配置均存储在 etcd。容器化或虚拟机化均可,借助 Kubernetes 等平台实现自动伸缩与滚动升级。
  • 水平扩展 根据 QPS 与响应延迟指标,动态扩缩容。建议在 Kubernetes 中配置 HPA(Horizontal Pod Autoscaler),结合自定义指标(如 CPU、内存或请求速率)自动调整实例数。
  • 灰度发布与回滚 配合 Kubernetes Deployment 或其它发布工具,利用 canary 发布策略逐步下发新版本。在出现问题时,可快速回滚至稳定版本,且不中断大部分流量。
bash 复制代码
lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "sleep 15 && apisix quit"]

网络与安全

  • 高性能网络 采用 L4 负载均衡(如 Nginx Stream、LVS)将流量分发至 APISIX,避免在 L7 层引入过多额外延迟。
  • TLS 终端 如需 HTTPS 支持,推荐在边缘层(L4)终端 TLS,再以 HTTP 通信至 APISIX;或直接在 APISIX 上使用 ssl 插件终端 TLS,并结合 Cert-Manager 自动续签证书。
  • 访问控制与认证 启用 IP 黑白名单、ACL 插件,并根据业务需求接入 JWT、OAuth2 等认证插件,确保后端服务安全。

配置管理与版本控制

  • 基础配置与热更新 把路由、上游服务、插件配置以 YAML/JSON 格式存储于代码仓库,结合 CI/CD 流水线自动同步至 etcd,实现配置即代码(Configuration as Code)。
  • 版本管理 每次配置变更都需打 tag 并在流水线中校验(lint、单元测试、灰度发布),确保变更可追溯、可回滚。
  • 选择稳定版本,并及时跟进社区的更新.
  • 升级版本时需要进行完整的回归测试,保证新版本的兼容性问题.

性能优化与插件治理

  • 实例选择 优先选择Graviton类型主机,经过多轮测试发现Graviton的机型相对于x86机型可以提供至少2两倍的性能提升,具体请参考社区 Benchmark 链接:.
  • 插件开关粒度

仅在需要的路由上启用插件,避免全局加载过多插件导致请求路径冗余执行。

  • 缓存与限流 利用 proxy-cache 插件对静态或可缓存响应进行本地缓存,减轻后端压力;结合 limit-req、limit-count 插件防止流量突发与恶意攻击。
  • 日志与追踪 启用 skywalking、zipkin 或 opentelemetry 插件,将请求链路与指标上报至分布式追踪系统,快速定位性能瓶颈。

监控告警与健康检查

  • 健康探针 在 Kubernetes 中配置 LivenessProbe 与 ReadinessProbe,APISIX 节点异常时可自动剔除。
  • 关键指标 重点监控请求速率、响应延迟、错误率,以及 etcd 的延迟与 leader 选举状态。根据阈值配置告警规则,保证故障可被及时发现与响应
  • 在实际生产中,如果service数量比较多以及并发大的情况下,需要对netfilter.nf_conntrack_max进行调整。建议结合prometheus和grafana进行告警,及时发现问题并优化相关参数。我们也可以通过采用类似C7gn的机型来提升网络吞吐。

灾备与高可用设计

  • 跨可用区部署 将 etcd 和 APISIX 实例分布在多个可用区或机房,保证单区故障时仍有服务可用。
  • 定期备份 对 etcd 数据进行周期性全量与增量备份,并在异地存储;同时验证备份可用性与恢复流程。

通过上述最佳实践,可以构建一套 高可用、可扩展、易运维 的 APISIX 服务部署体系,满足业务在复杂流量下的稳定运行与快速迭代需求。

总结

借助以上方案通过将所有玩家和运维流量先汇聚到单个NLB,再由部署在 EKS 集群内的 Apache APISIX 按 TLS SNI 把请求精准分发到各游戏服,从而用最少的负载均衡实例实现统一路由、动态服务发现和全链路加密,不仅显著降低 NLB 成本和配置复杂度,还能在服务器扩缩容时保持流量无感知切换,成为高并发游戏场景下经济、高效且易维护的网关架构,同时,借助Graviton,APISix能够实现极高的性价比。

参考内容

api7.ai/blog/api7-l... apisix.apache.org/blog/2022/0...

本篇作者

本期最新实验为《创新基石 ------ 基于 Graviton 构建差异化生成式AI向量数据库

✨ 在本次实验中,你可以在基于 Graviton 的 EC2 实例上轻松启动 Milvus 向量数据库,加速您的生成式 AI 应用。基于 Graviton 的 EC2 实例为您提供极佳性价比的向量数据库部署选项。

📱 即刻在云上探索实验室,开启构建开发者探索之旅吧!

⏩[点击进入实验] 构建无限, 探索启程!

相关推荐
翔云 OCR API2 小时前
NFC护照鉴伪查验流程解析-ICAO9303护照真伪查验接口技术方案
开发语言·人工智能·python·计算机视觉·ocr
艾莉丝努力练剑2 小时前
【自动化测试实战篇】Web自动化测试实战:从用例编写到报告生成
前端·人工智能·爬虫·python·pycharm·自动化·测试
Mintopia2 小时前
💥 Trae Solo 编程 vs. Cursor:新机遇与新挑战
前端·人工智能·trae
Mintopia2 小时前
🌌 长上下文 AIGC 的性能瓶颈:Web 端技术的突破与妥协
前端·人工智能·trae
xuehaikj2 小时前
【甲状腺病理AI】基于YOLO11-SOEP的甲状腺乳头状癌病理特征识别与分类系统研究
人工智能·分类·数据挖掘
愿没error的x2 小时前
深度学习基础知识总结(二):激活函数(Activation Function)详解
人工智能·深度学习
阿巴~阿巴~2 小时前
NumPy数值分析:从基础到高效运算
人工智能·python·numpy
aneasystone本尊3 小时前
LiteLLM 快速入门
人工智能
大模型实验室Lab4AI3 小时前
【Github热门项目】DeepSeek-OCR项目上线即突破7k+星!突破10倍无损压缩,重新定义文本-视觉信息处理
人工智能·ocr·deepseek-ocr