B 站游戏技术平台微服务通用网关实践
1. 背景
随着 B 站游戏业务不断快速发展,对业务系统的稳定性、快速迭代能力有了更高的要求。因此我们对游戏技术平台进行了技术升级改造, 引入了微服务架构。
众所周知在微服务架构体系下,应用程序会按照业务或功能模块被划分为可以单独部署、升级和替换的小型独立服务。这些服务可以依据业务特点使用不同的语言、不同的协议构建,极大增强可业务开发的灵活性。但同时我们也会面临非常多的问题,如服务访问、分布式事务、微服务划分等等。本文主要聚焦于微服务架构下,服务如何对外提供服务。
在游戏业务场景下,该问题具化为:游戏客户端如何与后端业务微服务进行通信?如游戏客户端直接与每个微服务直接进行通信,我们将面临如下一些挑战:
· 微服务存在多种通信协议,游戏客户端需要支持多种协议。
· 游戏客户端接入成本、复杂度剧增。
· 每个微服务都需要实现过载保护、身份验证、接口签名校验、灰度发布等通用功能。
为解决上述挑战,我们引入了一个中间层,该中间层位于游戏客户端和微服务之间。它为底层微服务 API 提供了一个单一入口,充当微服务 的反向代理服务,即为微服务通用网关。
2. 目标
结合游戏业务延迟敏感、规律性流量尖刺等特点,同时我们希望降低游戏接入复杂度;因此我们的微服务通用网关应具备以下能力:
· 接入成本足够低、甚至零成本接入。
· 高性能、高稳定性。
· 支持多种协议。
· 支持协议转换。
· 支持复杂路由策略、过载保护、熔断降级、灰度发布、身份验证、接口签名校验等功能。
· 完善的监控体系。
3. 解法
从零自研还是借助于开源社区的力量?
B 站游戏技术平台是一个开放、务实的团队,相比于完全重新招轮子,我们更倾向于借助社区的力量并与社区共建的方式。且在开源社区 已有许多成熟度高、社区活跃的网关系统。因此我们决定借助于开源社区项目构建微服务通用网关。
3.1. 技术选型
对于流量网关技术选型,目前开源方案众多。按技术体系大致可分为以下四大类:
1. Spring Cloud:在 Java 生态中,Spring Cloud 体系提供网关组件:
· 有 Netflix 贡献的: ZUUL1.x、ZUUL2.x 系列
· Spring 官方维护的: Spring Cloud Gateway
2. Golang:目前开源社区,有非常多给予 Golang 语言开发的网关系统,常见的有:
· TykTechnologies 提供的:tyk
· Traefixlabs 提供的:traefix proxy
· Eolinker 提供的:goku API Gateway
3. Service Mesh:
· Istio 数据面板,CNCF 项目:Envoy
· CNCF 项目,Linkerd 提供的:Linker2-proxy
4. OpenResty:
· Kong 提供的:Kong Gateway
· Apache 顶级项目:Apache APISIX
结合 B 站游戏业务特点,我们基于以下几点思考最终选择了 Apache APISIX。
· 优异的性能;
· 足够的稳定;
· 非常扩展容易;
· 学习成本低;
· 尽量少的依赖,尽量简洁的架构。
下面将介绍 B 站游戏技术平台是如何使用 Apache APISIX 搭建通用网关的。
3.2. 架构设计
我们先看看基于 Apache APISIX 的通用网关架构设计:
通过网关的架构足够简洁,仅对 etcd 存在强依赖关系。同时支持基于 Prometheus + Grafana 的服务状态监控,以及基于 Skywalking 的全链路监控系统。简洁的架构 降低服务的运维成本,完善的监控体系提升了服务的可观测性。
接来我们将介绍,基于 APISIX 的通用网关系统落地过程和对 APISIX 做的增强以及落地过程中都遇到了一些坑。
3.3. 落地过程
3.3.1. 与现有基础服务整合
这部分我们主要有两项工作:接入现有服务发现系统和集成 CI/CD 工具。通过接入现有服务发现系统并配合我们现在的容器环境,通用网关可具备发现上游微服务 的能力。集成 CI/CD 系统后,便可实现通用网关快速升级发布的需求。
1. 接入现有“服务发现”系统
我们接入服务发现接入方案具备以下一些特点,这些特点提高了服务发现效率及稳定性,同时降低了接入的成本和复杂度。
· 多级缓存机制。
· 微服务节点信息的可观测性。
· 动态拉取和自刷新机制。
2. 集成 CI/CD 工具
为了更好的支持通用网关快速升级发布的需求,我们主要做了以下两项工作。实现了服务一键编译,一键发布/回滚等功能。
· 定制 APISIX 的编译及运行环境。
· 基于公司现有 CI/CD 工具,优化编译/发布流程。
3.3.2. 魔改 APISIX
为了满足我们业务需求,我们基于 APISIX 做了一些定制开发。主要有以下一些内容:
· 增强流量管控功能,实现 Region、Zone 级别的摘、接流控制。
· 增强路由转发功能,新增了”流量单元”概念。
· 新增 API 签名验证功能。
· 增强 grpc 协议转换功能,支持默认路径匹配功能。
· 丰富 prometheus 数据采样,满足我们业务对流量观测需求。
· 增强日志记录能力,默认将日志上报至 Skywalking。
· 增强控制面板,新增服务发现模块。
3.3.3. 与开源社区保持版本同步
APISIX 还在快速迭代升级中,与社区保持版本和功能同步,是非常必要的工作。我们设计了通用网关 git 分支工作流,保持定期同步社区版本。对于我们增加的 一些通用功能,在公司政策允许的情况下,我们也将尝试反馈回社区。
3.3.4. 性能情况
在通用网关上线前,我们对其进行了一系列压测。性能虽和官方数据有一定差距,但也达到了我们设计期望的。
4. 踩过的坑
1. nginx resolve 不会解析本地 Hosts 文件。常见的解决方式是使用 dnsmasq 搭建私有的 DNS 服务。但出于维护成本等角度考虑我们并没有采取这种方式,而是使用调用“curl”命令替代“resty.http”的方案。
2. etcd 出现“etcdserver: mvcc: database space exceeded”异常。第一版的服务发现集成方案(也是官方方案)是每个 nginx work process 都会通过服务发现拉取服务实例信息,而在我们的设计中是会将实例信息写回 etcd 中。 这就会导致 etcd 存在大量的写操作,从而引起该问题。我们最终采用了多级缓存机制避免每个 nginx work process 都会拉取服务实例,同时也对写会操作进行 了优化。
3. APISIX “error-log-logger”插件的异常。APISIX V2.3 版本中,“error-log-logger”插件存在 bug,我们解决了该 bug。社区在新版本中也将这个问题解决了,这里赞一下社区的速度。
5. 总结
在实施过程中遇到一些挑战,但在团队努力下都得到有效的解决。通用网关上线后完美达到我们的设计目标,降低了业务系统的开发复杂度,同时进一步加强了系统的稳定性,鲁棒性。为业务高速发展提供了技术支撑和保障。
6. 后续计划
1. 支持业务系统单元化升级,实现单元化流量治理。
2. 自动化全链路压测。
3. 混沌工程。
4. 一站式 API 全生命周期管理平台。
作者:游戏事业部 技术部 基础架构团队
版权声明: 本文为 InfoQ 作者【bilibili游戏技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/95c80dcb18ebc2c26237868f3】。未经作者许可,禁止转载。
评论