在微服务架构下,服务拆分会让API的规模成倍增加,使用API网关来管理API逐渐成为一种趋势。美团统一API网关服务Shepherd就是在这种背景下应运而生,适用于美团业务且彻底自研,用于替换传统的Web层网关应用,业务研发人员经过配置的方式便可对外开放功能和数据。本文将介绍美团统一API网关诞生的背景、关键的技术设计和实现,以及API网关将来的规划,但愿能给你们带来一些帮助或者启发。
API网关是随着微服务(Microservice)概念兴起的一种架构模式。本来一个庞大的单体应用(All in one)业务系统被拆分红许多微服务(Microservice)系统进行独立的维护和部署,服务拆分带来的变化是API的规模成倍增加,API的管理难度也在日益增长,使用API网关发布和管理API逐渐成为一种趋势。通常来讲,API网关是运行于外部请求与内部服务之间的一个流量入口,实现对外部请求的协议转换、鉴权、流控、参数校验、监控等通用功能。html
在没有Shepherd API网关以前,美团业务研发人员若是要将内部服务输出为对外的HTTP API接口。一般要搭建一个Web应用,用于完成基础的鉴权、限流、监控日志、参数校验、协议转换等工做,同时须要维护代码逻辑、基础组件的升级,研发效率相对比较低。此外,每一个Web应用都须要维护机器、配置、数据库等,资源利用率也很是差。前端
美团内部一些业务线苦于没有现成的解决方案,根据自身业务特色,研发了业务相关的API网关。放眼业界,亚马逊、阿里巴巴、腾讯等公司也都有成熟的API网关解决方案。算法
所以,Shepherd API网关项目正式立项,咱们的目标是为美团提供高性能、高可用、可扩展的统一API网关解决方案,让业务研发人员经过配置的方式便可对外开放功能和数据。数据库
从业务研发人员的角度来看,接入Shepherd API网关,能带来哪些收益呢?简而言之包括三个方面。后端
提高研发效率跨域
下降沟通成本缓存
提高资源利用率安全
咱们先来看看Shepherd API网关的总体架构,以下图所示:网络
Shepherd API网关的控制面由Shepherd管理平台和Shepherd监控中心组成。管理平台主要完成API的全生命周期管理以及配置下发的工做,监控中心完成API请求监控数据的收集和业务告警功能。数据结构
Shepherd API网关的配置中心主要完成控制面与数据面的信息交互,经过美团统一配置服务Lion来实现。
Shepherd API网关的数据面也就是Shepherd 服务端。一次完整的API请求,多是从移动应用、Web应用,合做伙伴或内部系统发起,通过Nginx负载均衡系统后,到达服务端。服务端集成了一系列的基础功能组件和业务自定义组件,经过泛化调用请求后端RPC服务、HTTP服务、函数服务或服务编排服务,最后返回响应结果。
下面咱们将针对这三个主要模块作详细的介绍。
使用API网关的控制面,业务研发人员能够轻松的完成API的全生命周期管理,以下图所示:
业务研发人员从建立API开始,完成参数录入、DSL脚本生成;接着能够经过文档和MOCK功能进行API测试;API测试完成后,为了保证上线稳定性,Shepherd管理平台提供了发布审批、灰度上线、版本回滚等一系列安全保证措施;API运行期间会监控API的调用失败状况、记录请求日志,一旦发现异常及时发出告警;最后,对于再也不使用的API进行下线操做后,会回收API所占用的各种资源并等待从新启用。
整个生命周期,所有经过配置化、流程化的方式,由业务研发人员全自助管理,上手时间基本在10分钟之内,极大地提高了研发效率。
API网关的配置中心存放API的相关配置信息——使用自定义的DSL(Domain-Specific Language,领域专用语言)来描述,用于向API网关的数据面下发API的路由、规则、组件等配置变动。
配置中心的设计上使用统一配置管理服务Lion和本地缓存结合的方式,实现动态配置,不停机发布。API的配置以下图所示:
API配置的详细说明:
API路由
API网关的数据面在感知到API配置后,会在内存中创建请求路径与API配置的路由信息。一般HTTP请求路径上,会包含一些路径变量,考虑到性能问题,Shepherd没有采用正则匹配的方式,而是设计了两种数据结构来存储。以下图所示:
一种是不包含路径变量的直接映射的MAP结构。其中,Key就是完整的域名和路径信息,Value是具体的API配置。
另一种是包含路径变量的前缀树数据结构。经过前缀匹配的方式,先进行叶子节点精确查找,并将查找节点入栈处理,若是匹配不上,则将栈顶节点出栈,再将同级的变量节点入栈,若是仍然找不到,则继续回溯,直到找到(或没找到)路径节点并退出。
功能组件
当请求流量命中API请求路径进入服务端,具体处理逻辑由DSL中配置的一系列功能组件完成。网关提供了丰富的功能组件集成,包括链路追踪、实时监控、访问日志、参数校验、鉴权、限流、熔断降级、灰度分流等,以下图所示:
协议转换&服务调用
API调用的最后一步,就是协议转换以及服务调用了。网关须要完成的工做包括:获取HTTP请求参数、Context本地参数,拼装后端服务参数,完成HTTP协议到后端服务的协议转换,调用后端服务获取响应结果并转换为HTTP响应结果。
上图以调用后端RPC服务为例,经过JsonPath表达式获取HTTP请求不一样部位的参数值,替换RPC请求参数相应部位的Value,生成服务参数DSL,最后借助RPC泛化调用完成本次服务调用。
Shepherd API网关做为接入层的基础组件,高可用性一直是业务研发人员很是关心的部分。接下来。咱们就来探索一下Shepherd在高可用设计方面的实践。
一个高可用的系统,预防故障的发生,首先要排除性能隐患,保证高性能。
Shepherd对API请求作了全异步化处理,请求经过Jetty IO线程异步提交到业务处理线程池,调用后端服务使用RPC或HTTP框架的异步方式,释放了因为网络等待引发的线程占用,使线程数再也不成为网关的瓶颈。下图是使用Jetty容器时,服务端的请求线程处理逻辑:
咱们经过域名压测网关单机的端到端QPS,发现QPS在超过2000时,会出现不少超时错误,而网关的服务端负载与性能却很是富余。调研发现,公司内其余的Web应用都存在这个问题,与Oceanus团队进行联合排查后,发现是Nginx与Web应用之间的长链接功能没有打开,且没法配置。Oceanus团队通过紧急排期,研发并上线长链接功能后,Shepherd端到端的QPS成功提高到了10000以上。
另外,咱们对Shepherd服务端进行了API请求预热的优化,使得网关启动时能马上达到最佳性能,减小毛刺的发生。而后,经过压测时的CPU热点排查,将性能瓶颈找出,减小主链路上的本地日志打印,对请求日志进行异步化、远程化改造。Shepherd端到端的QPS再次提高30%以上。
在Shepherd服务上线稳定运行一年之后,咱们再次对性能进行优化,而且作了一次网络框架升级,将Jetty容器全面替换为Netty网络框架,性能提高10%以上,Shepherd端到端的QPS成功提高到15000以上。下图是使用Netty框架时,服务端的请求线程处理逻辑:
集群隔离
借鉴公司缓存、任务调度等成熟组件的经验,Shepherd在设计之初,就考虑了按业务线维度进行集群隔离,也支持重要业务独立部署。以下图所示:
请求隔离
服务节点维度,Shepherd支持请求的快慢线程池隔离。快慢线程池隔离主要用于一些使用了同步阻塞组件的API,例如SSO鉴权、自定义鉴权等,可能致使长时间阻塞共享业务线程池。
快慢隔离的原理是统计API请求的处理时间,将请求处理耗时较长,超过容忍阈值的API请求隔离到慢线程池,避免影响其余正常API的调用。
除此以外,Shepherd也支持业务研发人员配置自定义线程池进行隔离。具体的线程隔离模型以下图所示:
Shepherd提供了一些常规的稳定性保障手段,来保证自身和后端服务的可用性。以下图所示:
请求安全是API网关很是重要的能力,Shepherd集成了丰富的安全相关的系统组件,包括有基础的请求签名、SSO单点登陆、基于SSO鉴权的UAC/UPM访问控制、用户鉴权Passport、商家鉴权EPassport、商家权益鉴权、反爬等等。业务研发人员只须要简单配置,便可使用。
API网关做为请求入口,每每肩负着请求流量灰度验证的重任。
灰度场景
Shepherd在灰度能力上,支持灰度API自身逻辑,也支持灰度下游服务,也能够同时灰度API自身逻辑和下游服务。以下图所示:
灰度API自身逻辑时,经过将流量分流到不一样的API版本实现灰度能力;灰度下游服务时,经过给流量打标,分流到指定的下游灰度单元中。
灰度策略
Shepherd支持丰富的灰度策略,能够按照比例数灰度,也能够按照特定条件灰度。
立体化监控
Shepherd提供360度的立体化监控,从业务指标、机器指标、JVM指标提供7x24小时的专业守护,以下表:
监控模块 | 主要功能 | |
---|---|---|
1 | 统一监控Raptor | 实时上报请求调用信息、系统指标,负责应用层(JVM)监控、系统层(CPU、IO、网络)监控 |
2 | 链路追踪Mtrace | 负责全链路参数透传、全链路追踪监控 |
3 | 日志监控Logscan | 监控本地日志异常关键字:如5xx状态码、空指针异常等 |
4 | 远程日志中心 | API请求日志、Debug日志、组件日志等可上报远程日志中心 |
5 | 健康检查Scanner | 对网关节点进行心跳检测和API状态检测,及时发现异常节点和异常API |
多维度告警
有了全面的监控体系,天然少不了配套的告警机制,主要的告警能力包括:
告警类型 | 触发时机 | |
---|---|---|
1 | 限流告警 | API请求达到限流规则阈值触发限流告警 |
2 | 请求失败告警 | 鉴权失败、请求超时、后端服务异常等触发请求失败告警 |
3 | 组件异常告警 | 自定义组件处理耗时长、失败率高告警 |
4 | API异常告警 | API发布失败、API检查异常时触发API异常告警 |
5 | 健康检查失败告警 | API心跳检查失败、网关节点不通时触发健康检查失败告警 |
Shepherd服务端接入了弹性伸缩模块,可根据CPU等指标进行快速扩容、缩容。除此以外,还支持快速摘除问题节点,以及更细粒度的问题组件摘除。
对于一些已经在对外提供API的Web服务,业务研发人员为了减小运维成本和后续的研发提效,考虑将其迁移到Shepherd API网关。
对于一些非核心API,能够考虑使用Oceanus的灰度发布功能直接迁移。可是对于一些核心API,上面的灰度发布功能是机器级别的,粒度较大,不够灵活,不能很好的支持灰度验证过程。
解决方案
Shepherd为业务研发人员提供了一个灰度SDK,接入SDK的Web服务,可在识别灰度流量后转发到Shepherd API网关进行验证。
灰度哪些API、灰度百分比能够在Shepherd管理端动态调节,实时生效,业务研发人员还能够经过SPI的方式自定义灰度策略。灰度验证经过后,再把API迁移到Shepherd API网关,保障迁移过程的稳定性。
灰度过程
灰度前:在Shepherd管理平台建立API分组,域名配置为目前使用的域名。在Oceanus上,原域名规则不变。
灰度中:在Shepherd管理平台开启灰度功能,灰度SDK将灰度流量转发到网关服务,进行验证。
灰度后:经过灰度流量验证Shepherd上的API配置符合预期后再迁移。
Shepherd API网关的功能强大且复杂,易用性对业务研发人员来讲相当重要,咱们着重来看下自动生成DSL、API操做提效的解决方案。
业务研发人员在实际使用网关管理平台时,咱们尽可能经过图形化的页面配置来减轻DSL的编写负担。但服务参数转换的DSL配置,仍然须要业务研发人员手工编写。通常来讲,生成服务参数DSL的流程是:
整个过程很是繁琐,且容易出错。若是须要录入的API多达几十上百个,所有由业务研发人员手工录入的效率是很是低下的。
解决方案
那么能不能将服务参数DSL的生成过程给自动化呢? 答案是能够的,业务RD只需在网关录入API文档信息,而后录入服务的Appkey、服务名、方法名信息,Shepherd管理端会从最新发布的服务框架控制台获取到服务参数的JSON Schema信息,JSON Schema定义了服务参数的类型和结构信息,管理端可根据这些信息,自动生成服务参数的JSON Mock数据。结合API文档的信息,自动替换参数名相同的Value值。 这套DSL自动生成方案,使用过程当中对业务透明、标准化,业务方只需升级最新版本服务框架便可使用,极大提高研发效率,目前受到业务研发人员的普遍好评。
快速建立API
API网关的核心能力是创建在API配置的基础上的,但提供强大功能的同时带来了较高的复杂性,很多业务研发人员吐槽API配置太繁琐,学习成本高。快速建立API的功能应运而生,业务研发人员只须要提供少许的信息就能够建立API。快速建立API的功能当前分为4种类型(后端RPC服务API、后端HTTP服务API、SSO CallBack API、Nest API),将来会根据业务应用场景的不一样,提供更多的快速建立API类型。
批量操做
业务研发人员在API网关上,须要管理很是多的业务分组,每一个业务分组,最多能够有200个API配置,多个API可能有不少相同的配置,如组件配置,错误码配置和跨域配置的。每一个API对于相同的配置都要配置一遍,操做重复度很高。所以Shepherd支持批量操做多个API:勾选多个API后,经过【批量操做】功能可一次性完成多个API配置更新,下降业务重复配置的操做成本。
API导入导出
Shepherd提供在不一样研发环境相互导入导出API的能力,业务研发人员在线下测试完成后,只须要使用API导入导出功能,便可将配置导出到线上生产环境,避免重复配置。
一个设计良好的基础组件,除了能提供强大的基础能力,还须要有良好的扩展能力。 Shepherd的可扩展性主要体如今:支持自定义组件、服务编排的能力。
Shepherd提供了丰富的系统组件完成鉴权、限流、监控能力,可以知足大部分的业务需求。但仍有一些特殊的业务需求,如自定义验签、自定义结果处理等。Shepherd经过提供加载自定义组件能力,支持业务完成一些自定义逻辑的扩展。
下图是自定义组件实现的一个实例。getName中填写自定义组件申请时的名称,invoke方法中实现自定义组件的业务逻辑,如继续执行、进行页面跳转、直接返回结果、抛出异常等。
目前Shepherd经过自定义组件已经成功支持了美团优选、外卖、餐饮、打车等重要业务,接入的自定义组件数量有200多个。
通常状况下,网关上配置的一个API对应后端一个RPC或者HTTP服务。若是调用端有聚合和编排后端服务的需求,那么有多少后端服务,就必须发起多少次HTTP的请求调用。由此就会带来一些问题,调用端的HTTP请求次数过多,效率低,在调用端聚合服务的逻辑太重。
服务编排的需求应运而生,服务编排是对既有服务进行编排调用,同时对获取的数据进行处理。主要应用在数据聚合场景:一次HTTP请求返回的数据须要调用多个或屡次服务(RPC或HTTP)才能获取到完整的结果。
通过前期调研,公司已经有一套成熟的服务编排框架,由客服团队开发的海盗组件(参见《海盗中间件:美团服务体验平台对接业务数据的最佳实践》一文),也是美团内部的公共服务。
所以咱们与海盗团队合做,设计了Shepherd的服务编排支持方案。海盗经过独立部署的方式提供服务编排能力,Shepherd与海盗之间经过RPC进行调用。这样能够解耦Shepherd与海盗,避免因服务编排能力影响集群上的其余服务,同时多一次RPC调用并不会有明显耗时增长。使用上对业务研发人员也是透明的,很是方便,业务研发人员在管理端配置好服务编排的API,经过配置中心同时下发到Shepherd服务端和海盗服务上,便可开始使用服务编排能力。总体的交互架构图以下:
目前接入Shepherd API网关的API数量超过18000多个,线上运行的集群数量90多个,日均总调用次数在百亿以上。随着Shepherd API网关业务规模的不断增加,对咱们的可用性、易用性、可扩展性必将提出更高的要求。将来一年,Shepherd的规划重点包括有云原生架构演进、静态网站托管、组件市场等。
Shepherd API网关的云原生架构演进有三个目标:简化接入网关步骤,提高业务研发人员的研发效率;减少服务端War包大小,提高安全性和稳定性;接入Serverless弹性,下降成本,提升资源利用率。
为了实现这个三个目标,咱们计划总体迁移网关服务到公司的Serverless服务Nest(参见《美团Serverless平台Nest的探索与实践》一文)上,同时经过抽取Shepherd核心功能到SDK的方式集成到业务的网关集群,业务研发人员能够只选择本身须要使用的自定义组件,从而大幅减少服务端的War包大小。
依托Shepherd API网关实现静态网站托管的目标是:建设通用的静态网站托管解决方案,为开发者提供便捷、稳定、高扩展性的静态网站托管服务。
静态网站托管解决方案能为业务研发人员提供的主要功能包括:托管静态网站资源,包括存储及访问;管理应用生命周期,包括自定义域配置以及身份验证和受权;CI/CD集成等。
Shepherd API网关组件市场的目标是:合做双赢,造成开发生态,业务研发人员可将开发的自定义组件提供给其余有须要的业务研发团队使用。
咱们但愿让业务研发人员参与到自定义组件的开发,完善使用文档后设置为公共组件,开放给全部使用Shepherd的业务研发人员使用,避免重复造轮子。
充泽、志洋、李敏等,均来自美团基础技术部-基础架构团队。
美团基础技术部-基础架构团队诚招高级、资深技术专家,Base北京、上海。咱们致力于建设美团全公司统一的高并发高性能分布式基础架构平台,涵盖数据库、分布式监控、服务治理、高性能通讯、消息中间件、基础存储、容器化、集群调度等基础架构主要的技术领域。欢迎有兴趣的同窗投送简历至:edp.itu.zhaopin@meituan.com。
阅读美团技术团队更多技术文章合集
前端 | 算法 | 后端 | 数据 | 安全 | 运维 | iOS | Android | 测试
| 在公众号菜单栏对话框回复【2020年货】、【2019年货】、【2018年货】、【2017年货】等关键词,可查看美团技术团队历年技术文章合集。
| 本文系美团技术团队出品,著做权归属美团。欢迎出于分享和交流等非商业目的转载或使用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者使用。任何商用行为,请发送邮件至tech@meituan.com申请受权。