您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

B站 API 网关的发展

时间:2022-08-25 10:58:11  来源:  作者:高可用架构

本期作者

周佳辉

哔哩哔哩资深开发工程师

2017 年加入 B 站,先后从事账号、网关、基础库等开发工作。编码 C/V 技能传授者,技术文档背诵者。

开源社区爱好者,安全技术爱好者,云计算行业活跃用户,网络工程熟练工。史诗级 bug 生产者,熟练掌握 bug 产生的各类场景。

始终以简单为核心设计理念,追求极致简单有效的后端架构

背景

如果你在 2015 年就使用 B 站,那么你一定不会忘记那一年 B 站工作日选择性崩溃,周末必然性崩溃的一段时间。也是那一年 B 站投稿量激增,访问量随之成倍上升,而过去的 php 全家桶也开始逐渐展露出颓势,运维难、监控难、排查故障难、调用路径深不见底,而也就是在这一年,B 站开始正式用 Go 重构 B 站。

B站第一个 Go 项目:bilizone 由冠冠老师(一个周末)编码完成。

commit 4ccb1497ca6d94cec0ea1b2555dd1859e6f4f223Author: felixhao <g******1@gmAIl.com>Date: Wed Jul 1 18:55:00 2015 +0800 project initcommit 6e338bc0ee638621e01918adb183747cf2a9e567Author: 郝冠伟 <h*******@bilibili.com>Date: Wed Jul 1 11:21:18 2015 +0800 readme

bilizone 其实还是一个大而全的应用,bilizone 在当时重构的主要意义是将谁也理不清的 PHP 逻辑梳理成了一个比较标准的 Go 应用。

bilizone 在当时最大的意义就是为用户终端提供了基本稳定的数据结构、相对可靠的接口和比较有效的监控。但因 bilizone 依旧是一个单体应用,所以它依旧继承了单体应用所具有的缺点:

  • 代码复杂度高

    方法被滥用、超时设置混乱、牵一发而动全身

  • 一挂全挂

    最常见的:超时设置不合理,goroutine 大量堆积,雪崩

  • 测试及维护成本高

    小改动都需要测试所有 case,运维发布胆战心惊

所以此时B站的崩溃频率虽然已经有所降低,但一炸全炸的问题依旧是一个心腹大患。

而再接下来的一次重构,B站微服务的全局面貌就将初具雏形。

为了实现微服务模式下的 bilibili,我们将一个 bilizone 应用拆分成多个独立业务应用,如账号、稿件、广告等等,这些业务通过 SLB 直接对外提供 API。

当时的调用模式如下图所示:

但是随着功能拆分后,我们对外暴露了一批微服务,但是因为缺乏统一的出口而面临了不少困难:

  • 客户端与微服务直接通信,强耦合

  • 需要多次请求,客户端聚合数据,工作量巨大,延迟高。

  • 协议不利于统一,各个部门间有差异,反而需要通过客户端来兼容。

  • 面向“端”的 API 适配,耦合到了内部服务。

  • 多终端兼容逻辑复杂,每个服务都需要处理。

  • 统一逻辑无法收敛,比如安全认证、限流。

基于上述问题和我们想要将对端的处理进行内聚的想法,我们自然的而然的就想到在客户端与后端服务之间加一个 App-interface 的组件,这就是接下来的 BFF(Backend for Frontend)模式。

app-interface 的工作模式如下图所示:

有了这个 BFF 之后,我们可以在该服务内进行大量的数据聚合,按照业务场景来设计粗粒度的 API,给后续服务的演进带来的很多优势:

  • 轻量交互:协议精简、聚合。

  • 差异服务:数据裁剪以及聚合、针对终端定制化 API。

  • 动态升级:原有系统兼容升级,更新服务而非协议。

  • 沟通效率提升,协作模式演进为移动业务和网关小组。

BFF 可以认为是一种适配服务,将后端的微服务为客户端的需要进行适配(主要包括聚合裁剪和格式适配等逻辑),向终端设备暴露友好和统一的 API,方便无线设备接入访问后端服务,在其中可能还伴随有埋点、日志、统计等需求。

这个时期的 BFF 还有一个致命的一个问题是整个 app-interface 属于 single point of failure,严重代码缺陷或者流量洪峰可能引发集群宕机所有接口不可用。于是我们在上述基础上进一步迭代,将 app-interface 进行业务拆分,进而多套 BFF 的模式横空出世:

由此模式开始,基本确定了 B 站微服务接口的对接模式,这套模式也随之在全公司内推广开来。

垂直 BFF 时代 2016-2019

接上文当 B 站网关的架构发展为多套垂直 BFF 之后,开发团队围绕该模式平稳迭代了相当长的一段时间。而后随着B站业务的发展,团队人员的扩充和几次组织架构调整,此时开始出现直播、电商等独立业务,这些业务的发展我们之后再细说。而在这些调整之后,有一个团队的职责越来越清晰:主站网关组。

主站网关组的主要职责就是维护上述各类功能的 BFF 网关,此时 bilibili 的主要流量入口为粉板 App,这里可以简单细说一下粉板 App 上的所有业务组成:

主站业务

  • 网关组维护的 BFF,如推荐、稿件播放页等

  • 业务层自行维护的 BFF,如评论、弹幕、账号等

独立业务

  • 电商服务

  • 直播服务

  • 动态服务

主站业务的 BFF 其实被分为两类,一类是由网关组负责的 BFF,另一类是业务自行维护的 BFF。

而这两类 BFF 的技术栈其实基本一致,基本功能职责也相差不多,如此划分的原因是让网关组可以更专注于迭代客户端特性功能,免去理解部分独立业务场景的接口,如登陆页应该让对安全更专业账号的同学自行维护。在这里我们也可以简述一下一个新需求应该如何决定参与的 BFF :

  • 如果这个功能能由业务层的业务 BFF 独立完成,则网关组不需介入。

  • 如果该功能是一个客户端特性需求,如推荐流等复合型业务,需要对接公司大量部门时,则由网关同学参与开发 BFF。

当时主站技术部的后端同学遵循以上两个规则,基本能够满足业务的快速开发和迭代。

我把这段时间称为垂直 BFF 时代,因为基本主站每个业务或多或少都有各种形式的网关存在,大家通过这个网关向外提供接口,该网关和 SLB 进行直接交互。

再谈一谈电商、直播和动态

电商和直播其实并不是同一时期衍生的,直播在主站 PHP 时期就诞生了,而电商相对更晚一些。

当时直播的技术栈组成有 C++、PHP、Go,其中早期大部分业务逻辑由 PHP 和 C++ 实现,稍晚一些也开始逐步试用主站的 Go 实现部分业务逻辑。其中 PHP 负责对终端提供接口,C++ 主要实现核心业务功能。因此我们可以简单理解为直播使用由 PHP 编写的 BFF 网关。

动态团队其实派生自直播团队,因此技术栈和直播当时基本一致,这里可以简单省略。

而众所周知,大部分电商团队的技术栈都是 JAVA 和 Spring 或 Dubbo。

因这几个业务实现上几乎没有相似的地方,且大家对 gRPC 协议逐渐地认同,因此技术栈上大家基本没有大一统的想法,互相能调通即可。

而随着 B 站团队进一步的壮大、流量持续的增长,进而经历了诸多线上故障、事故分析之后,大家慢慢发现了这套架构下的问题:

  • 单个复杂模块也会导致后续业务集成的高难度,根据康威法则,复杂聚合型 BFF 和多团队之间就出现不匹配问题,团队之间沟通协调成本高,交付效率低下。

  • 很多跨横切面逻辑,比如安全认证,日志监控,限流熔断等。随着时间的推移,功能的迭代,代码变得越来越复杂,技术债越堆越多。

此时我们可能还需要一个能协调横跨切面的组件,将路由、认证、限流、安全等组件全部上提,能够统一更新发布,把业务集成度高的 BFF 层和通用功能服务层进行分层,进而大家开始引入「统一 API 网关」

在新的架构中,统一网关承担了重要的角色,它是解耦拆分和后续升级迁移的利器。在统一网关的配合下,单块 BFF 实现了解耦拆分,各业务线团队可以独立开发和交付各自的微服务,研发效率大大提升。另外,把跨横切面逻辑从 BFF 剥离到网关上去以后,BFF 的开发人员可以更加专注业务逻辑交付,实现了架构上的关注分离(Separation of Concerns)。

从多个网关到最后一个统一网关 2022-至今

在这两三年的时间里,各个业务团队或多或少都有自己业务网关组建独立的维护团队,也为网关的功能作出过相当多的投入。但随着 B 站业务的发展,公司级中间件功能的不断更替演进,如果将对接各个中间件的工作在每个网关上都实现一次的话带来的人力投入和沟通成本会相当巨大,且实现标准不统一、运营方式不统一无法起到 API 网关所带来的最佳收益。

因此微服务团队开发了一款 B 站内部意义上的标准 API 网关,该 API 网关汇集以往各型网关中流量治理的优秀经验,对相关功能做出完善设计改进。该 API 网关的目前的主要功能除了常规的限流、熔断、降级、染色外,还会基于这些基础功能和公司各类中间件的基础上,提供了:

  • 全链路灰度

  • 流量采样分析、回放

  • 流量安全控制

  • ...

等等进阶型 API 质量治理的相关功能,这些功能业务团队在接入 API 网关后都可以一并获得,为业务的迅速迭代做出力所能及的保障。

不仅仅是 API 网关

在开发 API 网关的同时,我们也会更进一步关注业务团队开发、对接 API 时的体验,我们将以网关作为统一标准 API 规范的起点,为业务团队提供更有效的 API 开发生态,如:

  • 规划 API 业务域,简化 SRE 运维

  • 标准 API 元信息平台

  • 精确的 API 文档和调试工具

  • 类型安全的 API 集成 SDK

  • API 兼容性保障服务

API 网关是我们 API 治理生态中的一个标志性里程碑,我们希望在 API 网关的开发中能够多多倾听大家的意见,希望能有更多的声音来帮助我们理清思路。本次 API 网关也以开源形式进行开发,在这里欢迎大家指导:
https://Github.com/go-kratos/gateway

本文由高可用架构翻译。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。

高可用架构

改变互联网的构建方式



Tags:API 网关   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
五 种 API 网关技术选型,yyds
本文准备围绕七个点来讲网关,分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关对比,对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分...【详细内容】
2023-11-07  Search: API 网关  点击:(309)  评论:(0)  加入收藏
负载均衡器、反向代理、API 网关区别
简介您是否理解负载均衡器、反向代理和 API 网关等多样组件之间的差异?不确定哪个组件最适合您的 Web 应用程序?这些关键组件在现代 Web 架构中发挥着至关重要的作用,了解它们...【详细内容】
2023-09-27  Search: API 网关  点击:(281)  评论:(0)  加入收藏
深入探究微服务架构下 API 网关的发展趋势
网关作为应用系统的流量防卫兵,可以说在保障整个系统的稳定运转过程中发挥着不可或缺的作用。不管未来的技术形态如何演进,不管是否能出现云原生架构全面取代传统的部署模式,可...【详细内容】
2023-09-03  Search: API 网关  点击:(243)  评论:(0)  加入收藏
云原生时代,API 网关为何如此重要?
【CSDN 编者按】API是Application Program Interface,应用程序连接接口的缩写,作为数据传输流转的重要通道,API网关更成为云原生时代的重要入口。作者 | 温铭,Apache APISIX PMC...【详细内容】
2022-10-18  Search: API 网关  点击:(393)  评论:(0)  加入收藏
B站 API 网关的发展
本期作者周佳辉哔哩哔哩资深开发工程师2017 年加入 B 站,先后从事账号、网关、基础库等开发工作。编码 C/V 技能传授者,技术文档背诵者。开源社区爱好者,安全技术爱好者,云计算...【详细内容】
2022-08-25  Search: API 网关  点击:(426)  评论:(0)  加入收藏
API 网关选型及包含 BFF 的架构设计
一 背景介绍下图是我从网络上找到的一个微服务架构的简单架构图,如图可见 API Gateway 在其中起到一个承上启下的作用,是关键组件。图片来源于网络在更通用的场景下我们会使用...【详细内容】
2020-10-14  Search: API 网关  点击:(905)  评论:(0)  加入收藏
API网关:API 网关从入门到放弃
前言假设你正在开发一个电商网站,那么这里会涉及到很多后端的微服务,比如会员、商品、推荐服务等等。 那么这里就会遇到一个问题,APP/Browser怎么去访问这些后端的服务? 如果...【详细内容】
2020-04-11  Search: API 网关  点击:(307)  评论:(0)  加入收藏
Java 界最好的 API 网关 Soul
soul网关发布2.1.0版本 (做Java界最好的API-Gateway) 这是soul网关开源以来的最大的一次更新,收集了很多社区反馈的问题,进行了更新. 之前的文档不是很完善,使用成本较高,这里先...【详细内容】
2019-12-27  Search: API 网关  点击:(442)  评论:(0)  加入收藏
Java后端精选技术:谈谈 API 网关
背景理论上,客户端可以直接向微服务发送请求,每个微服务都有一个公开的URL,该URL将映射到微服务的负载均衡器,由它负责在可用实例之间分发请求。但这种方式存在如下缺陷:1. 客户...【详细内容】
2019-08-03  Search: API 网关  点击:(1158)  评论:(0)  加入收藏
▌简易百科推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  步步运维步步坑    Tags:架构   点击:(5)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27    InfoQ  Tags:架构模式   点击:(13)  评论:(0)  加入收藏
哈啰云原生架构落地实践
一、弹性伸缩技术实践1.全网容器化后一线研发的使用问题全网容器化后一线研发会面临一系列使用问题,包括时机、容量、效率和成本问题,弹性伸缩是云原生容器化后的必然技术选择...【详细内容】
2024-03-27  哈啰技术  微信公众号  Tags:架构   点击:(10)  评论:(0)  加入收藏
DDD 与 CQRS 才是黄金组合
在日常工作中,你是否也遇到过下面几种情况: 使用一个已有接口进行业务开发,上线后出现严重的性能问题,被老板当众质疑:“你为什么不使用缓存接口,这个接口全部走数据库,这怎么能扛...【详细内容】
2024-03-27  dbaplus社群    Tags:DDD   点击:(12)  评论:(0)  加入收藏
高并发架构设计(三大利器:缓存、限流和降级)
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。引言1.高并发背景互联网行业迅速发展,用户量剧...【详细内容】
2024-03-13    阿里云开发者  Tags:高并发   点击:(6)  评论:(0)  加入收藏
如何判断架构设计的优劣?
架构设计的基本准则是非常重要的,它们指导着我们如何构建可靠、可维护、可测试的系统。下面是这些准则的转换表达方式:简单即美(KISS):KISS原则的核心思想是保持简单。在设计系统...【详细内容】
2024-02-20  二进制跳动  微信公众号  Tags:架构设计   点击:(36)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  ijunfu  今日头条  Tags:SpringBoot   点击:(18)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  547蓝色星球    Tags:架构   点击:(115)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11    王建立  Tags:Spring Boot   点击:(124)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  互联网架构小马哥    Tags:Spring Boot   点击:(118)  评论:(0)  加入收藏
站内最新
站内热门
站内头条