如何构建一个可用的企业级API网关?
张嘉阳 talkwithtrend 今天
API网关(API Gateway),是分布式系统中为了保护内部服务而设计的一道屏障,可以提供高性能、高可用的API托管服务,从而帮助应用系统(服务)的开发人员通过API接口便捷地对外提供服务,而不用考虑安全控制、流量控制、审计日志等问题,统一在网关层将安全认证、流量控制、日志审计与IP黑白名单等实现。API网关的下一层,是企业的内部应用服务,应用服务只需关注具体业务相关功能的实现。API网关可以提供API接口发布、管理、统计、维护等主要功能。开发人员只需要简单的配置操作即可把自己开发的API服务发布出去,同时置于API网关的保护之下。
API网关使得搭建一个新的应用服务变得简单、快捷、高效,同时,开发人员可以将精力更多放在和业务紧密相关的工作中。
API网关的核心设计理念是使用一个轻量级的消息网关作为所有客户端的应用入口,并且在 API 网关层面上实现通用的非功能性需求。如下图所示:所有的服务通过 API 网关来暴露,这是所有客户端访问的唯一入口;如果一个服务要访问另一个服务,也要通过这个网关。
一旦 API 网关允许客户端消费一个受管理的 API,那么我们就可以以受管理的 API 形式使用它来暴露这个微服务所实现的业务逻辑。API 网关可以通过HTTP、HTTPS、RPC等方式来连接内部受管理的 API,以实现 API 网关的高并发。
(1)API网关层对应用进行了内外隔离,隐藏了服务的内部实现细节,在一定程度上保障了后台服务的安全性。
(2)对外访问控制由网络层面转换成了网关应用层面,减少变更的流程和错误成本。
(3)大大降低了客户端与应用服务的耦合度,服务可以独立运行,并通过网关层实现服务映射。
(4)通过网关层聚合,减少外部访问的频次,提升访问效率。
(5)有效的节约后端服务开发成本,减少上线风险。
(6)为超时处理、服务熔断、灰度发布与线上测试等提供简单的应用解决方案。
(7)便于进行应用层面的扩展。
(8)具有一定的高可用性,能够有效提高服务质量。
API网关架构
API网关为企业的应用提供统一的应用入口, API网关隐藏了企业内部应用系统的应用细节, 从一定程度上保证了企业内部应用的安全性。 API网关为各种应用场景提供支撑服务。
API网关的功能
企业级API网关应该提供下列的功能:
服务路由:外部服务访问接口映射到对应的内部服务访问接口。
认证授权:提供对用户身份的认证以及用户权限验证,包括用户身份的合法性、针对用户角色的访问授权验证、针对用户的访问授权验证、IP 黑名单验证等。
超时处理:当 API 网关调用的内部服务响应时间超过了在自主开发的 API 网关后台管理子系统中所设置的允许最长的超时时间时,API 网关会立即停止调用,并返回相关消息给你。
限流控制:当你通过 API 网关调用内部服务的频率达到在某个阈值时,API 网关会立即做断开链路处理。过了时间后,链路会自动闭合回去。
熔断处理:熔断处理对避免无谓的资源消耗特别有用,当通过 API 网关调用的内部服务出现异常的频率达到某个阈值时,那么 API 网关会做临时熔断处理即临时断开链路,暂时停止你对那个内部服务的调用。临时熔断后,过了一段时间后,链路会自动闭合回去。
日志信息记录:会记录客户 IP、客户请求参数、返回结果、异常信息等信息。
负载均衡: 提供API接口的负载均衡,能够处理API接口的高并发访问,防止服务雪崩。
安全防护:提供严格的认证服务,支持算法签名,用户使用 API 网关提供的密钥进行认证,没有被授予密钥的客户端无法调用业务 API接口,经过认证授权的请求才能到达后端应用服务。同时SSL 加密。
灰度发布:支持API接口线上灰度部署,减少应用版本切换风险。
设计一个企业级API网关时, 应该从功能需求、性能需求、高可用性、扩展性等方面进行综合考量, 覆盖企业的API应用场景,从而满足企业的业务需求。下面我们将从功能、性能、高可用性和扩展性四方面进行介绍。
6.1 功能需求
企业级API网关除了上述的服务路由、认证授权、超时处理、限流控制、熔断处理、日志记录、负载均衡、灰度发布等基础服务外,还需要提供以下的功能。
1)API 生命周期管理功能
覆盖API的设计规范、开发、测试、发布和下线的整个生命周期管理;
便捷的日常管理、版本管理,支持热升级和服务快速回滚;
能够提供API接口开发测试、预发布与生产发布等多种应用环境。
2)开发支持功能
提供页面调试工具,能够自动生成 API 文档和 SDK,这样可以大大降低人力成本。开源的API文档生成方案有Swagger等。
3)流量控制功能
可控制单位时间内 API 允许被调用次数;
用来保护企业的后端服务,实现业务分级和用户分级;
支持对API接口的流量控制,可以根据 API 的重要程度来配置不同流控,从而保障重要业务的稳定运行;
支持用户、应用和例外流控,您可以根据用户的重要性来配置不同流控,从而可以保证大用户的权益;
支持不同的流控粒度类型:分钟、小时、天。
4)请求管理功能
可根据配置进行参数类型、参数值(范围、枚举、正则、Json Schema)的校验,减少后端对非法请求、无效请求的资源消耗和处理成本;
可以在API网关中定义参数映射规则,网关通过映射规则将后端服务通过协议转换成相应的数据格式,以满足不同用户的不同需求,从而避免功能重复开发。
5)监控告警功能
提供实时、可视化的 API 监控,包括:调用次数、调用方式、响应时间、错误率,让企业能够清楚的了解 API 的运行状况和用户的行为习惯;
支持自定义报警规则,来针对异常情况进行报警,降低故障处理时间;
提供可订阅的数据分析报表和智能分析。
6.2 高性能设计
传统的基于线程的并发模型(Thread-based concurrency),为每一个请求分配一个线程或进程。这种模型编程简单,可以将处理一个完整请求的代码编写在一个代码路径中。这种模型的弊端是,随着线程(进程)数的上升,操作系统在这些线程(进程)之间的频繁切换,将急剧降低系统的性能。
API网关能够提供API接口服务的高并发调用,提供负载均衡、数据缓存、容错机制等功能来保证服务的高可用性。
6.3 高可用设计
1) 无状态设计原则
网关层为保证高可用、易于扩展、快速启动,需要设计成无状态的。用户的状态数据我们通常使用session对象来封装,网关层要设计成无状态的,也就是说,不能由网关来负责session的维护。那由谁来维护session相关的信息呢?我们是采用cookie+session服务器的方式;
a) 用户在登录页完成登录操作后,服务器会生成一个登录session信息,保存起来,设置个失效时间,并设置到用户的cookie里。
b) 用户后续的每次请求里会带着这个cookie信息,服务端会对这个cookie信息进行校验,通过了就认为是合法用户,执行请求操作。
也可以采用JWT认证方式, 由身份认证中心签发用户的访问Token,每次访问API接口时,每次请求都在请求头中带上Token验证头信息, 通过API网关对Token信息进行身份验证,确定其是否相应的访问权限。
2)优雅下线原则
当需要下线一个API接口服务时,不是直接结束网关进程,而是先关闭监听套接字(Socket),但是继续为当前连接的客户提供服务,所有客户端的服务完成后,再终止服务进程。
3)Slow Start特性
当API网关监听到有一个新的API服务注册时,考虑到有些服务启动后,刚开始会有许多初始化的工作,此时服务对请求的响应速度是比较慢的。如果一开始就给这个API接口服务分配太多的压力,有可能导致服务瞬间被压垮。为了避免这种情况,网关层需要考虑支持Slow Start(慢启动)特性。即,经过一段时间,逐渐把压力增加到预设的值。
4)业务拦截扩展
我们知道,网关对请求的处理,可以分为三个阶段:接受请求、路由并转发请求、接受服务的返回数据并返回给请求者,除此之外,还有一种情况是处理错误。所以我们也可以在这四个地方添加扩展点。
(1)接受到请求后;
(2)定位到一个服务,并准备转发之前;
(3)接受到服务的返回数据,返回给客户端之前;
(4)当服务调用失败后。
拦截器的处理顺序,可以分为两大类:
网关平台自带的拦截器,例如安全校验、日志记录等;
网关层逻辑开发的功能,例如格式转换等。
一般来说,网关先执行网关平台自带的拦截器,再执行为了业务逻辑编写的拦截器。当然,API网关也需要提供一种机制,可以比较容易地调整拦截器的执行顺序。最简单的一种方法,就是给每个拦截器定义一个优先级,网关按优先级顺序依次调用各拦截器。
对网关层来说,它接收和处理的数据都是业务请求(Request)对象,网关层在接收到请求后,把请求封装为Request对象,为了让后续的过滤器(Filter)能够获得这个对象,可以考虑把Request对象保存在线程变量中。
有些拦截器,例如一些调试日志的拦截器,通常情况下都是关闭的,只有在出现问题的时候才需要打开。为了保证网关的高可用,网关层必须具备在线启用或关闭拦截器的能力。一般,API网关需要提供RESTful接口方式来关闭和启用一个拦截器。
类似这样的命令:PUT /gateway/v1/filters/filterName?enable=value
5)API管理与动态发布设计
对服务管理来说,分为前端服务管理与后端服务管理。前端服务指的是网关层暴露给客户端使用的服务API,后端服务指的是服务层提供的业务服务API。一个服务暴露给客户端使用,除了网关层和服务层提供服务的代码外,还需要配置前端服务与后端服务的映射关系。
网关层API调用服务层API,有多种方式。例如,可以由按照服务层API的服务契约,生成一段客户端代码,发布给网关层使用。这种方式的弊端是,网关层代码依赖于服务层代码,服务层频繁修改和调整接口时,导致网关层的代码很难维护。
可以通过配置前后端服务映射的方式,解耦网关层对服务层的依赖。当服务层的API(例如服务名、参数名等)发生变化时,只需调整映射关系,无需对网关层的代码进行调整。网关层按照映射,自动装配服务层API所需要的数据格式。这样,网关层团队与服务层团队可以相互不受干扰地开发各自的服务。
6.4 可扩展性设计
从灵活性和扩展性方面来说,在设计API网关时应该考虑如何对API网关的功能进行扩展, 网关应该提供扩展插件机制, 企业可以根据业务应用需求对网关功能进行扩展。API网关管理平台可以对API网关业务扩展插件进行发布与下架操作。例如Kong网关可以通过plugin接口发布扩展插件,同时也可以通过接口下架某个插件。
总之,API网关作为企业业务能力开放的一个应用门户,除了具备基本的请求转发、认证授权、路由等功能,以及高性能和高可用性外,还需具备良好的扩展性,以便于API网关能力的不断增强。
推荐阅读: