写点什么

B 站游戏技术平台微服务通用网关实践

发布于: 2021 年 06 月 25 日
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 全生命周期管理平台。


作者:游戏事业部 技术部 基础架构团队

发布于: 2021 年 06 月 25 日阅读数: 17
用户头像

bilibili游戏技术 2021.05.20 加入

分享bilibili游戏技术干货

评论

发布
暂无评论
B 站游戏技术平台微服务通用网关实践