架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?

目录

日均数十亿访问,个推API网关如何架构?

API网关之源起

1、个推早期API网关

2、个推自研API网关

2.2 技术选型

2.3 设计与实现

个推 API 网关总结


日均数十亿访问,个推API网关如何架构?

近期,个推的服务端技术大师李白受邀参与了 SegmentFault D-Day 在线技术直播活动,与来自知名互联网公司后端技术专家们共同探讨了“后端架构的演变之路”。李白以“API 网关的演变之路”为主题,分享了个推基于golang进行API网关建设的实践经验和深度思考

API网关之源起

API 网关是一种随着“微服务”理念而崛起的架构模式。

在微服务拆分过程中,庞大的单体应用和业务系统被拆分成许多微服务系统进行独立维护和部署,导致 API 数量大幅增加,API 治理的难度也逐渐加大。

同时,子系统通过 API 对外提供服务时,还存在通用能力重复建设的问题。因此,使用API网关统一发布和管理API逐渐成为一种架构趋势。

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第1张图片

在个推,消息推送、金融风控等业务核心系统均采用微服务架构,部分系统也拥有自建的网关模块。随着各个系统之间的依赖关系日益增多,高效进行接口治理的需求日益迫切。因此,个推早期就引入了统一的 API 网关,以解决权限控制、流量控制、服务降级、灰度发布、版本管理等一系列问题。

1、个推早期API网关

2015年,SpringCloud 的诞生极大促进了微服务架构的发展和流行。个推也是在这一时期,依赖于SpringCloud gateway构建了自己真正意义上的API网关。

SpringCloud 在生态系统方面相对友好,有许多可以即插即用的监控和容错组件,但由于不支持流量和安全治理,因此无法很好地满足公司后续进行 API 治理的需求;尤其是个推后来建设数据中台,更亟需一个统一的API网关来承担数据中台的入口流量

此外,在开发语言上,SpringCloud 仅支持 Java,适用性有限,且存在性能不佳、运维难度大等问题。

因此,为了实现更强大的 API 治理能力、简化接入和运维方式,同时也为了更好地满足公司数据中台建设需求,个推决定自主研发 API 网关。

2、个推自研API网关

2.1 自研目标

个推建设API网关的几个关键目标包括:

1)要能够对API完整生命周期进行统一治理

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第2张图片

例如,在API设计上,要统一规范,确保 API 具有归属服务和标签,实现 API 设计上的隔离;

设计完成后,能够直接进行调试,并自动生成测试代码;

发布时,对 API 流量进行精细化控制,支持服务的灰度发布

在 API 运行过程中,全方位监控 API 调用情况并告警,对出现问题的服务能够及时地熔断隔离;下线后能够及时回收资源。

2)需要有完善的功能组件,来处理再一次请求过程

在整个请求链路中,我们设计实现了链路追踪、日志、鉴权、限流、熔断、插件等一系列核心功能。

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第3张图片

3)保证“三高”的同时,用户迁移和接入要简单

这意味着 API 网关易于运维和使用,提供各种指标检测功能,且支持自动容错和弹性扩容

2.2 技术选型

基于以上的目标设计和技术调研之后,我们选择将 golang 作为自研 API 网关的主要开发语言。

选择 golang 的原因有:

1)个推在做多机房容灾建设和数据拆分迁移过程中,设计了gproxy-codis和gproxy-es,并已搭建了一套 proxy 集群来路由不同的用户。这些 proxy 运行良好,一些大的集群单机 QPS 超过 6W。在这些项目的开发过程中,我们积累了许多开发经验和基础组件,其中的许多轮子可以直接复用。

因此,我们使用 golang 并基于现有的这些组件,开发一套 gproxy-http 相对轻松。

2)golang 语言本身就支持高并发,开发速度快,最重要的是节省机器成本

3)作为云原生框架中使用最广泛的编程语言,golang 的技术沉淀也是为个推云原生建设铺路

2.3 设计与实现

确认目标和技术选型之后,接下来就是一些具体的设计与实现。

1)整体架构

个推API网关的整体架构设计,如图所示:

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第4张图片

首先,这是一个Web管理平台,这个平台负责所有 API 的创建、发布以及后续管理,用户可以在上面进行相应的配置。

配置完成后,通知配置中心,网关就会定时拉取全量的 API 配置。

接下来是网关的核心组件,例如插件引擎,主要是执行配置的一些插件。

转发引擎也是API网关的核心模块,个推的转发引擎支持 http、grpc,还有个推自研的 gcf 协议,在数据中台的业务场景下,也支持了 kafka 的数据推送能力。

2)插件服务

从图中可以看到,个推 API 网关的整体架构中有一个独立的插件服务。

这个设计的主要原因是 golang 是类 C 语言,打包后是可执行文件,由于 Golang 的原生插件是直接编译好的,它们不支持更新和卸载,因此也无法在界面上直接实现新增和更新插件的功能

为了解决这个问题,我们选择使用 Java 来开发插件服务。借助 Java 的动态语言特性,我们可以灵活地支持插件的新增、更新和卸载。然而,网关通过 gRPC 与插件服务进行通信,这可能会导致一定的性能损耗。

为了尽可能减少这种性能损耗,我们将加密和特定序列化相关的插件都使用 Golang 的一个原生插件来完成。对于一些业务定制较强的组件,我们建议使用 Java 插件服务。

3)资源隔离

资源隔离是实现系统高可用的常用手段,在隔离设计上主要有集群和线程池的隔离。

API网关主要支持服务集群隔离,通过这种集群级别的隔离,在上层可以支持多租户,如果再彻底一点,在 LB 层面可以把网关集群也隔离出去。

另外,服务的灰度发布也是通过网关这种集群隔离来实现的。具体过程是,在升级时,用户可以在界面上配置流量转发规则和集群,通过流量回放,将部分测试流量导入到灰度集群,或把线上真实流量按比例转发给灰度集群,确保没有问题后再全量发布。

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第5张图片

线程的隔离主要体现在数据服务上,其主要功能是将数据 API 化

这意味着通过简单的配置,在界面上就可以将 MySQL、ES、Hbase 的数据通过 API 提供出去,无需开发人员编写 CRUD 或客户端代码,非常便捷。

目前,个推数据中台业务场景的大部分流量都是请求数据服务,因此我们设计了普通线程池、慢线程池和自定义配置的线程池等三类线程池

当请求时长超过慢阈值后,接口会被分配到慢线程池处理,防止慢请求拖垮整个服务。

4)服务编排

服务编排是 API 网关需要满足的常见需求之一,主要是将多个 API 进行聚合调用,大幅度减少调用延迟

过去,这部分功能是在网关上实现的,网关支持的服务编排相对基础,能够支持 API 的并发聚合调用,不过,在处理复杂的业务组合,特别是涉及到事务的编排场景时,然而表现并不理想。

所以,将这部分功能独立出来,作为一个独立的服务,后续的链路网关将直接访问服务编排模块,从而保证网关整体保持相对轻量。

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第6张图片

5)性能优化

针对 API 网关的性能,我们进行了一系列压力测试和优化,例如,用开源函数替代或重写内部大量使用的序列化、加解密等函数;大量使用 Sync.Pool 复用对象,对其内部逻辑进行纯异步处理;自主研发 gnet,替换原生 net 框架,优化网络模型等。

从线上实际运行结果来看,目前个推数据中台中的 API 平台每天调用量超过 10 亿次,单机 QPS 峰值在 2W 左右,整体性能损耗在 10%+,性能表现超过预期。

6)易用性设计

通过上述插件机制、隔离手段和性能上的极致优化,我们确保建设的 API 网关平台整体是高可用且易扩展的。而平台搭建好后,还需便于用户接入和使用以及运维。

架构设计内容分享(五十六):日均数十亿访问,个推API网关如何架构?_第7张图片

因此,为了提升易用性,我们选用了纯Web的界面设计,并内置了多个API模板。用户只需执行简单的配置,便可生成一个 API,如接口授权有效期、QPS、限额等权限设置,都能通过可视化界面进行操作;创建完成后,用户还可以直接在界面上进行调试。

同时,在对外提供API的场景下,用户可以批量导出某个服务下的API文档,非常方便。个推API平台还实现了监控和统计的功能,例如提供 API 被调用的走势、整个服务中 API 调用量和错误统计等数据,对运营和研发人员十分友好。

个推 API 网关总结

总的来看,个推 API 网关基于 golang 独立开发,实现全 Web 化配置,使得所有 API 接口标准化且可视化;除了满足网关的基本需求外,还支持插件热更新、多协议转换、数据推送、集群级别资源隔离等高级功能。

个推 API 网关不仅能够整合到系统微服务架构中,还可作为公司数据中台的流量入口,日均承担数十亿级的访问量。

你可能感兴趣的:(架构设计,内容分享,API网关,内容分享,架构,java,云计算,API网关)