本文节选自本人参与编写的《金融企业数字化中台》一书,感兴趣的朋友请自行查找。
要ESB还是要网关???
在互联网技术的引领下,微服务架构得以流行,对于服务集成相关工作,首当其冲就是由网关(API Gateway )负责。乍一看貌似没有ESB什么事儿,实则不然,金融企业IT建设起步早、规模大,数以百计的业务系统在运行,而且金融企业IT架构本身就是分布式的架构,也完全没有必要全部使用微服务相关技术栈全面改造,因此提全面微服务化那就是纸上谈兵。我们必须承认ESB在金融企业应用系统间的服务枢纽地位牢不可破,仍将持续发挥着重要的作用。是ESB曾经接过了EAI的枪,把系统间通过EAI Hub 和Agent数据集成的方式,转向了面向服务的标准化集成方式。金融企业内部的核心系统、管理系统、渠道类系统之间仍存在这技术和协议的差异,正是因为在SOA时代实施了ESB,系统间服务集成才得以统一成基于HTTP+XML协议的Web Service标准,变得标准化、规范化和可治理。
但我们通过这段从数据到服务集成的历史,更能够认识到企业和用户多年来不断变化和发展的需求。在已有业务系统之间服务打通仍是ESB的核心任务。面对新一代数字化转型中的业务的需求,需要能够围绕一个简单,灵活的标准协议对所有新应用进行连接,相对而言Web Service协议略显沉重,ESB由于其集中式枢纽的地位,快速响应变更对于它来说也不是很合适。轻量,快速响应变化且可配置的敏捷集成执行能力对于数字化企业至关重要。互联网类的业务率先开始采用微服务的技术栈建设,那么这就是API Gateway 网关的用武之地了,网关需要精心设计为数字业务转型加速,需要让应用集成更简单。网关使用了更轻量级的HTTP协议和RESTful 风格的API,可以更方便的打通移动端、物联网设备、云服务等等多渠道的应用。
因此我们的结论是,在数字化转型时代,在金融企业中 ESB 与API Gateway是共存的,都是IT系统之间的服务集成平台。ESB作为系统之间的服务集成的枢纽,网关则在微服务架构体系的业务领域内部进行系统之间集成通信。不论是ESB还是网关,作为服务集成平台的建设来说,重点应该关注的内容包含:身份验证、权限管控、服务路由能力增强等方面。复杂的服务组装、数据、协议转换工作通常需要编码开发,灵活度低,容易产生故障,不建议在服务集成平台中实施,这类工作建议交给负责交易流应用实施的平台负责。下面我们首先从身份验证说起。
服务集成平台应该负责身份验证
服务集成平台作为业务系统的API入口,当其面向外网的访问者时服务集成平台还是内外网的分界,访问令牌验证理应由服务集成平台负责,不应该将令牌验证的事情交给服务提供者,这样既能避免未经验证的请求进入内网,又能够简化服务提供端的代码,服务提供端无需处理不同类型客户端的验证。
身份验证方案分析
服务集成平台验证访问令牌有两种方案:服务集成平台委托认证服务验证、服务集成平台直接验证,说明如下:
- 方案一、服务集成平台委托授权服务验证:每次收到请求后,服务集成平台均将访问令牌发送到认证服务进行认证,认证通过后才允许继续访问。
上图为网关作为服务集成平台时,委托IAM进行身份令牌校验的示意图,说明如下:
- 客户端成功认证后,使用UUID类型的访问令牌调用服务集成平台上的服务
- 由于UUID类型令牌不包含客户端的信息,服务集成平台需要委托认证服务校验令牌
- 令牌检查合法后,将请求路由到服务提供者
- 应用中也无法解析令牌,需要根据UUID令牌到认证服务中获取用户信息
- 方案二(推荐)、服务集成平台直接验证身份:要求服务集成平台能识别认证服务颁发的令牌,这种模式推荐用 JWT令牌,服务集成平台需要具备解析校验JWT加密的访问令牌的能力。
上图为网关作为服务集成平台时,自身负责令牌校验的示意图,说明如下:
- 客户端成功认证后,使用JWT令牌调用服务集成平台上的服务
- 服务集成平台自己直接解密JWT令牌进行校验
- 令牌检查合法后,将请求路由到服务提供者
- 应用受到请求后,如果需要更多权限信息,如果可以根据Token去权限管理服务获取权限信息(非必须步骤,需要时添加)。
上述两方案中,方案一的令牌是无业务含义的身份标识字符串,每次收到请求服务集成平台都去认证服务器认证,对认证服务的性能压力较大。方案二中IAM颁发的令牌中包含部分客户端或用户信息,使用JWT加密,认证服务将验证方式或SDK提供给了负责认证的服务集成平台。对于认证服务器来说,减少了每次请求令牌认证带来的通信次数,负担变轻了。
推荐采用方案二实现令牌检查,需要注意的是方案二中的JWT令牌中仅包含必要的信息即可,不要放太多的角色权限信息。后续功能中需要额外的信息时,可以根据令牌再去认证服务中获取。如果令牌中存放了很多的权限数据,一旦后台的授权数据发生变化,令牌中的权限数据与实际认证服务的权限会存在不一致的问题,只能强制用户下线重新登录。
JWT令牌是防篡改的,但并不加密,如需要存储到浏览器存储中,建议采用JWT+JWE方式进行令牌加密。令牌中存放必要少量数据即可,避免滥用。多数服务器通常会对Http header、cookie长度做限制。
系统内部应用之间服务建议直通,无需经过服务集成平台
服务集成平台应该由独立团队负责运维管理,否则对于单个系统来说多维护一组服务集成服务过于繁琐。API变更发布、内部联调验证还得跨团队协调实在不可行。推荐系统内直通不经过服务集成平台,而跨系统访问必须走服务集成平台。要做到这一点,应用也需要识别请求来源,进行客户端认证,这种认证方案没必要太复杂,应用只应该允许信任的服务集成平台和系统内部应用程序访问其服务,不允许系统外部请求绕过服务集成平台直接调用,因此,需要在服务集成平台和系统内部应用之间这个小范围内建立信任,常见方案有两种:
- 方案一,系统保密令牌:系统内的应用在发布接口到务集成平台时,提供一个系统内部共享的令牌给服务集成平台和系统内所有应用,接收到请求时检查请求头中是否包含当前系统的专属令牌, 如果包含当前系统专属令牌,那么就允许访问,否则就拒绝
- 方案二,系统内保密令牌+务集成平台令牌单独认证:系统内用保密令牌交互就是方案一,方案二中重点是内部令牌不共享给服务集成平台,避免跨团队的令牌泄密。服务集成平台用公私钥证书签名方式与域内系统建立信任,由服务集成平台生成公私钥证书,颁发公钥给各个系统,服务集成平台调用服务提供者时,请求头中带上用私钥签名的“服务集成平台专属令牌”,应用收到请求以后用服务集成平台提供的公钥验证其令牌。
方案一优点是实现简单,缺点是安全级别略低,常见的企业架构中,服务集成平台和业务系统会是不同团队甚至不同的厂商负责开发维护,内部令牌共享给了其他团队负责的服务集成平台,存在一定的风险。方案二相比方案一略复杂一点,安全性更高,系统内互通用系统专属保密令牌,系统和服务集成平台认证使用了服务集成平台提供的安全令牌检查。两种方案可根据实际需求选择。
服务集成平台应该对API进行权限管控
我们先来看三个问题:
- 通过认证的API客户端能够访问服务集成平台开放的所有API吗?
- 通过认证的用户能够调用所有API吗?
- 通过认证的用户允许调用修改订单的接口,那么他能修改所有人的订单吗?
很显然绝大多数场景下上述三个问题答案都是"不能"。在绝大多数业务场景中除了对访问者的身份认证之外,我们还需要再进一步控制权限。
API Key与身份认证结合管控
如果访问者是API客户端时,API调用的权限需由服务集成平台进行控制。建议采用“消费者先订阅一组API,订阅成功后才允许访问”的授权模式,服务集成平台应该仅允许API客户端访问其订阅过的API 。 具体实现方法就是绝大多数服务集成平台都会提供的基于API Key控制API访问的方式。需要注意的是,仅使用API key的访问控制是不够的。API Key是在服务集成平台订阅API时生成的一串唯一编号,并不具备识别客户端身份的能力。就好比以前买火车票是不实名的,谁拿到火车票,都可以乘坐对应车次。火车票实名制之后,首先需要核验身份证,核验通过后才能购票乘车。如果证票不符,则不允许乘车。
将客户端认证和API Key配合进行访问认证和权限校验才是个更安全的方案。
上图为网关作为服务集成平台时,访问令牌结合API Key的认证鉴权示意图,说明如下:
- 客户端1获取了API Key 但其没有合法的访问令牌,如果不允许匿名访问,则网关会拒绝客户端1访问,返回错误码401表示客户端未通过认证;
- 客户端2拥有了合法的访问令牌,但其API Key不合法,网关在客户端2认证检查通过后,检查API Key,发现其权限不足,则返回错误码403表示客户端的权限不足;
- 客户端3拥有合法的客户端访问令牌和API Key访问网关上的服务,网关认证、鉴权通过之后,将请求路由到实际的服务提供端,最终发回正常响应数据。
用户权限服务集成平台管不管?
用户访问的功能权限或数据权限不建议交给服务集成平台管控,原因是服务集成平台仅能支持基于API Path授权,而实际需要控制的用户权限有很多,如菜单、功能、数据等。如果由服务集成平台控制用户权限,管少了不满足需求,管多了就要耦合太多应用数据。跨团队直接沟通协调、问题定位等分工责任也难界定。
因此推荐用户权限由业务应用自行管控。每个业务系统内部如果需要控制用户权限,可以将系统内部的权限在统一权限管理服务中配置。应用从权限中心获取数据进行用户权限控制。如没有权限中心,也可以由应用自身维护权限数据。对于权限管理是业务系统自治还是集中管控,一般根据企业自身的需求特点决定即可。
服务集成平台应提供更强大的请求路由能力
服务集成平台要能够融入到微服务生态中
建设服务集成平台要考虑的就是能够融入微服务生态中。与微服务基础服务中的注册中心、配置中心、监控中心、日志中心等基础组件集成,能够大大加强服务集成平台的服务治理、路由、运维等能力。
- 服务集成平台与注册中心集成:服务集成平台能够通过注册中心获取应用的实例信息,比如应用A有几个集群组?每个集群组中有哪些实例进程。让服务集成平台的路由、负载等等相关能力更强大。
- 服务集成平台与配置中心集成:服务集成平台能够通过配置中心在线动态修改配置,自动同步到服务集成平台,结合配置热更新能力,服务集成平台就可以做到不停机修改和调整相关的控制策略。更加灵活快速的响应变更。
- 服务集成平台与监控中心、日志中心集成:服务集成平台本身也是分布式部署的,可能不同渠道、不同业务域、甚至不同类型的客户端都会部署服务集成平台集群,集成了监控中心、日志中心后,分布式部署的服务集成平台也可以做到统一的监控和服务跟踪,在享受分布式架构好处的同时,还能有聚合监控的体验。
服务集成平台要支持应用分组路由(版本控制、灰度发布)
基于可靠性、性能方面考虑,通常一个服务提供者应用会以集群形式对外提供服务。随着快速响业务应变化的需求越来越多,应用通常会进行多版本并行迭代快速交付。比如说,某个应用在生产系统同时运行了两个集群,也就是说同样一个AppId 对应的多个进程实例,实际上再注册中心中划分为两个组,一组为之前上线运行的稳定版,另一组为新上线的版本。这种场景下,就要求服务集成平台能够支持对同一个AppId进行分组路由,不同组的应用API对应的版本不同。这个场景就是我们常说的通过服务集成平台进行API的版本控制,服务集成平台支持了应用分组路由的能力,也就意味着支持了应用灰度发布。
服务集成平台要支持动态负载均衡
一个服务提供者应用集群中会存在多个进程实例,这些进程实例会与注册中心通讯,报告自身的健康状况。而服务集成平台则须支持通过注册中心获取应用的实例列表信息,用以在服务路由过程中的负载均衡调用。借助了注册中心的能力,集群内的应用实例增加或减少,服务集成平台均可在段时间内获悉,因此这种模式下,服务集成平台对应用的动态负载均衡也能够很好的支持。
对于负载均衡策略服务集成平台应该支持常见的几种,如:轮循、随机、哈希、一致性哈希、权重比例等,还需要提供良好的扩展能力用以针对企业应用的特点进行扩展。
服务集成平台要具备熔断、降级、限流能力
服务熔断、降级、限流等概念均是从可用性和可靠性出发,为了防止系统崩溃而采用的一些保护性手段。对于服务消费端的体验是类似的,都是部分服务暂时不可用。不同的是这三者的触发时机有所不同。分别说明如下:
服务熔断:这个概念就出自电力设备保护的保险丝,顾名思义,服务熔断是指在应用集群内,如果某个应用发生了故障,则将其熔断,即:负载均衡时将其排除在可用列表之外。服务集成平台自身内部应该包含客户端路由的能力,一旦调用某个应用发生故障,应该随机记录在案,短期内将故障应用实例排除在路由目标范围之外,待其恢复之后,再次启用。这种熔断策略是被动触发的,能够有效的防止因为单点故障引发的连锁反应,甚至雪崩。
服务降级:与熔断不同的是,服务降级是在服务集成平台判断当前运行负载过高时,预防性的将一些优先级低的非核心服务调用请求主动舍弃,避免服务提供端压力过大导致崩溃。
服务限流:限流是针对服务消费者请求的限制手段,通常基于API访问次数的计量结果进行控制。静态限流模式类似流量套餐,如:按请求数量计费的模式,套餐限制一天内调用某一组API的次数不超过1000次,超过后服务集成平台就会阻止消费端的调用请求。动态限流模式可以跟服务降级类似,在运行负载高的时候,限制拒绝优先级低的客户端请求,将主通道让路给核心和重要业务运行。
转载本文需注明出处:网关(API Gateway)与ESB之争