近日,个推服务端技术专家李白受邀参加SegmentFault D-Day 线上技术直播流动,与来自头部互联网企业的后端技术专家们共探 “后端架构演进之路”。李白以“API网关演进之路”为主题,分享了个推基于golang进行API网关建设的实践经验和深度思考。
★以下为李白演讲干货整顿:
API网关之源起
API网关是随“微服务”概念而衰亡的一种架构模式。在微服务拆分过程中,本来宏大的单体利用和业务零碎被拆分成许多微服务零碎进行独立保护和部署,导致API规模成倍增长,API治理难度日益减少;同时,子系统通过API对外提供能力时,还会存在通用能力反复建设的问题。因而,应用API网关对立公布和治理API逐步成为一种架构趋势。
在个推,公司的音讯推送、金融风控等业务外围零碎均是基于微服务架构,局部零碎也存在自建的网关模块。随着不同零碎之间的依赖越来越多,高效进行接口治理的需要日益迫切。因而,个推很早就引入了对立的API网关,来解决权限管制、流控、服务降级、灰度公布、版本治理等一系列问题。
1、个推晚期API网关
2015年,SpringCloud的诞生极大促成了微服务架构的倒退和风行。个推也是在这一时期,依赖于SpringCloud gateway构建了本人真正意义上的API网关。
SpringCloud在生态上比拟敌对,有很多能够开箱即用的监控和容错组件,但因为不反对流量和平安治理,所以无奈很好地满足后续公司进行API治理的需要;尤其是个推起初建设数据中台,更亟需一个对立的API网关来承当数据中台的入口流量。此外,在开发语言上,SpringCloud只反对Java,适用性无限;且存在性能不现实、运维难度大等有余。
因而,为了实现更弱小的API治理能力、简化接入和运维形式,同时也为了更好地适应公司数据中台建设需要,个推抉择自研API网关。
2、个推自研API网关
2.1 自研指标
个推建设API网关的几个要害指标:
✦ 1) 要可能对API残缺生命周期进行对立治理
比方,在API设计上,要对立标准,规定API必须有归属服务和标签,做到API设计上的隔离;设计实现后要可能间接调试,主动生成测试代码;公布时,对API流量要做到精细化管制,反对服务的灰度公布;在API运行过程中,要可能对API调用状况进行全方位的监控和告警,对呈现问题的服务可能及时地熔断隔离;下线后可能及时回收资源。
✦ 2)须要有欠缺的性能组件,来解决再一次申请过程
在整个申请链路中,咱们设计实现了链路追踪、日志、鉴权、限流、熔断、插件等一系列外围性能。
✦3)保障“三高”的同时,用户迁徙和接入要简略
这一点其实是说API网关要便于运维和应用,同时要提供各种指标检测性能,且反对主动容错和弹性扩容。
2.2 技术选型
基于以上的指标设计和技术调研之后,咱们抉择将golang作为自研API网关的主力开发语言。之所以抉择golang,有以下几个起因:
✦ 1)个推在做多机房容灾建设和数据拆分迁徙过程中,设计了gproxy-codis和gproxy-es,并曾经搭建了一套proxy集群来路由不同的用户。这些proxy到目前为止运行良好,一些大的集群单机QPS超过6W。在这些我的项目的开发过程中,咱们积攒了不少的开发教训和根底组件,外面的很多轮子都是能够间接复用的。因而,咱们应用golang并基于现有的这些组件,开发一套gproxy-http就绝对省力得多。
✦ 2)golang语言自身人造反对高并发,开发速度快,最重要是节俭机器老本。
✦ 3 )golang作为云原生框架应用最多的语言,golang上的技术积淀也是为个推云原生建设铺路。
2.3 设计与实现
确认指标和技术选型之后,接下来就是一些具体的设计与实现。
✦ 1) 整体架构
个推API网关的整体架构设计,如图所示:
首先是一个Web治理平台,API的创立、公布和后续治理都可在治理平台上配置实现;配置实现后,会下发到配置核心告诉到网关,同时网关也会定时拉取全量的API配置;而后是网关的一些外围组件,比方插件引擎,次要是执行配置的一些插件。转发引擎也是API网关的外围模块,个推的转发引擎反对http、grpc,同时还有个推自研的gcf协定,而在数据中台的业务场景下,也反对了kafka的数据推送能力。
✦ 2) 插件服务
从图中能够看到,个推API网关整体架构里有一个独立的插件服务。这个设计的外围起因是golang是类C语言,打包后是可执行文件,而golang的原生插件是间接编译好的,不反对更新和卸载,所以也不能在界面上间接新增和更新插件。基于此起因,咱们应用Java开发了一个插件服务,利用Java动静的语言个性,以灵便地反对插件的新增、更新和卸载。
网关通过grpc与插件服务通信,性能上有肯定损耗。为了尽可能减少性能的损耗,咱们把加密、特定的序列化相干插件都应用golang的一个原生插件去实现,一些业务自定义比拟强的组件则举荐应用Java插件服务。
✦ 3) 资源隔离
资源隔离是实现零碎高可用的罕用伎俩,在隔离设计上次要有集群和线程池的隔离。
API网关次要反对服务集群隔离,通过这种集群级别的隔离,在下层能够反对多租户,如果再彻底一点,在LB层面能够把网关集群也隔离进来。另外,服务的灰度公布也是通过网关这种集群隔离来实现的。具体过程是,在降级时,用户能够在界面上配置流量转发规定和集群,通过流量回放,将局部测试流量导入到灰度集群,或把线上实在流量按比例转发给灰度集群,确保没有问题后再全量公布。
线程的隔离次要体现在数据服务,次要性能是把数据API化,也就是在界面通过简略的配置就能够把MySQL、ES、Hbase的数据通过API提供进来,不必开发人员入手写CRUD或者客户端代码,十分不便。目前个推数据中台业务场景的大部分流量都是申请数据服务,因而咱们设计了一般线程池、慢线程池和自定义配置的线程池等三类线程池。当申请时长超过慢阈值后,接口会被调配到慢线程池解决,防止慢申请拖垮整个服务。
✦ 4) 服务编排
服务编排也是API网关须要满足的一个常见需要,次要是将多个API做聚合调用,大幅升高调用提早。这部分性能之前是在网关上的,在网关层面反对的服务编排相对来说较为根底,可能撑持API的并发聚合调用,但难以解决简单的业务组合,特地是波及到事务的编排场景。因而,咱们决定将这部分性能,抽取进来做独立服务,而后续的链路网关会间接拜访服务编排模块,这样也保障了网关整体绝对轻量。
✦ 5) 性能优化
针对API网关性能,咱们也做了一系列压测和优化,比方,应用开源函数代替或重写外部大量应用的序列化、加解密等函数;大量应用Sync.Pool复用对象,对其外部逻辑进行纯异步解决;自研gnet,替换原生net框架,对网络模型进行优化等。从线上理论运行后果来看,目前个推数据中台中的API平台每天调用量超过10亿次,单机QPS峰值在2W左右,整体性能损耗在10%+,性能体现超过预期。
✦ 6) 易用性设计
通过上述插件机制、隔离伎俩和性能上的极致优化,咱们确保建设的API网关平台整体是高可用且易扩大的。而平台做好当前,还要不便用户接入应用和运维。
因而,为了晋升易用性,咱们采纳纯Web的界面设计,并内置了多个API模板。用户通过简略的配置,就能够创立一个API,例如接口受权有效期、QPS、限额等权限配置,都能通过可视化界面操作实现;创立好API之后,用户还能够间接在界面上调试。
同时,在对外提供API的场景下,用户能够批量导出某个服务下的API文档,十分不便。个推API平台还实现了监控和统计的性能,比方提供API被调用的趋势、整个服务下API调用量和谬误统计等数据,对经营和研发人员比拟敌对。
总结
综上,个推API网关基于golang自主研发,全Web化配置,实现了所有API接口的标准化、可视化;除解决网关根底需要外,也反对了插件热更新、多协定转换、数据推送、集群级别资源隔离等进阶需要。除了整合到零碎微服务架构中,个推API网关同时也作为公司数据中台流量入口,日均承当数十亿级的访问量。目前个推API网关新版集群曾经稳固运行一年以上,在保障系统稳固运行的同时还在继续进化。将来,咱们还将围绕云原生摸索更多的可能性,为业务提供稳固高效的根底平台。