API Gateway

Posted 田攀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了API Gateway相关的知识,希望对你有一定的参考价值。

一、为什么需要API网关?

在微服务架构下,所有的后端服务都变成了一个个微小的API,外部客户端的一次业务请求,可能需要调用内部多个服务接口才能完成,如果让客户端与各个微服务直接通信,会有如下问题:

  • 客户端多次请求不同的微服务,增加了客户端设计与维护的复杂性;

  • 认证复杂,每个服务都需要独立认证;

  • 难以重构。随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会变得很难实施。

二、什么是API网关?

API网关介乎于客户端与服务端之间,是客户端访问业务系统的唯一入口。API网关的存在,让微服务更加专注于考虑业务逻辑,而安全、性能、监控等公共服务则交由API网关实现,例如:统一认证、负载均衡、服务熔断、流量控制、灰度发布、日志统计等。其实,在微服务概念流行之前,API网关的实体就已经诞生了,例如,银行、证券等领域常见的前置机,它就是为了解决访问认证、报文转换、访问统计等问题而出现的。

关于API网关的职能,有人做了这样一个形象的类比,还是非常形象:

假如有一家企业,这家企业的办公场所入口有一个门卫,日常情况下,门卫会对出入企业的人员进行身份确认,有访客拜访的时候会帮助提供位置指引服务,在企业举办活动的时候协助人员限流管理等。

API网关承载的角色就相当于一个门卫,商品、库存、订单、评论等服务都属于后端内部微服务,由各个业务团队独立维护,相当于企业的各个业务部门,当发生外部请求时,API网关首先对这个请求进行认证和鉴权,然后再将这个请求分发到后端对应的微服务,倘若外部请求出现流量突发,则对这些请求进行负载分担和流量控制。

 

三、API网关能干什么?

1、反向代理

反向代理是API网关的基本功能。当外部请求进来之后,如何找到内部具体的微服务?API网关的重要职责之一就是将外部请求映射到内部微服务上,例如,“/catalog” 映射到商品分类服务上,“/inventory”映射到商品清单上,“/cart”映射到购物车服务上,“/order”映射到订单服务上。

 

2、认证鉴权

单体应用体系下,请求一般会通过一个权限拦截器进行权限校验,在登录时将用户信息缓存到会话Session中,后续访问则从会话中获取用户信息。

而在微服务架构下,一个应用被拆分为若干个微服务,每个微服务都需要明确当前访问用户及其权限,单体应用架构下的鉴权方式就不适合了。API网关作为服务访问的统一入口,所有用户请求都经过API网关,很适合用来做认证鉴权这类切面型服务。

API网关拦截用户请求,获取请求中附带的用户身份信息,调用认证授权中心的服务,对请求者做身份认证,即确认当前访问者确实是其所声称的身份,检查该用户是否有访问该后台服务的权限。

 

目前主流的认证鉴权方案有两种:

  • 引入Redis做分布式会话。即用户登录成功后,将用户身份、权限信息存入Redis,以一个唯一ID作为Key,并设置信息在Redis里的失效时间。这个唯一ID的Key将返回给客户端,客户端可以存放在Cookie或sessionStorage等本地存储。下次访问的时候,将这个唯一ID放入请求参数中一起发送(一般放入Header)。服务端通过检查Redis里有无这个ID来判断用户是否登录,获取用户身份和权限信息。客户端如果长时间没有操作,则存储在Redis里会话信息过期自动删除。客户端每访问一次服务端,需刷新一次会话信息的过期时间,避免固定过期时间带来的低用户体验。

  • JWT,即Java Web Token。用户登录成功后,服务端向客户端返回的唯一ID不再是无意义的字符串,而是包含了用户身份、权限、失效时间等信息的加密字符串,并且这个字符串包含数字签名,服务端可对这个字符串做数字签名验签,确保该字符串未经篡改和伪造。相比分布式会话方案,JWT虽省去了Redis存储,但是每次访问都要做数字签名验证,增加了CPU的资源损耗。

3、服务聚合

通过API Gateway的聚合服务,减少了客户端与各个微服务之间的交互次数。

 

4、负载均衡(Load Balancer,LB)

在实际的应用部署中,当应用系统面临业务峰值,访问流量过高时,我们通常会横向扩展服务数量,使用集群负载均衡来提高系统的业务响应能力。

负载均衡分为集中式负载均衡和进程内负载均衡。

  • 集中式负载均衡在访问者和目标服务之间架设LB硬件(例如F5)或者软件中间件(例如Ngnix)。客户端请求首先发送到负载均衡服务器,负载均衡服务器根据某种设定的均衡算法,将请求转发给后端服务器中的一个。服务端负载均衡技术成熟,效率也高,但是,后端服务器变动(扩容或缩容)需要修改负载均衡的配置,可维护性稍差,且需要对负载均衡本身实现高可用,增加了部署和维护成本。

  • 进程内负载均衡有所不同,后端服务器的地址列表不再由负载均衡服务器存储和维护,而是将LB逻辑集成在客户端。后端服务器启动时自动向注册中心注册服务,服务下线时自动向服务注册中心注销服务。客户端建立对服务注册中心的长监听,每当后端服务发生变化,注册中心自动通知客户端更新本地缓存的服务器列表。客户端访问后端服务的时候,从服务注册中心获取哪些地址可用,然后根据负载均衡算法从这些地址中选择一个合适的服务器。进程内负载均衡的好处是方便,后端服务变化对客户端是透明的。

 

5、灰度发布

软件版本在迭代升级发布过程中,由于新版本没有接受过真实环境、真实数据、真实用户的考验,因此,将新版本全部部署在生产环境是非常危险的。

灰度发布是一种多版本共存的发布方式,产品发布者根据设定的某种规则,让一部分用户继续使用老版本A,另一部分用户开始使用新版本B,在过渡过程中,及时发现和修改新版本B的问题,保证新版本上线的影响最小化和整个业务系统的平滑升级过渡。

在灰度发布的时候,在API网关上对服务提供权重路由,例如,90%的流量使用老版本A,10%的流量使用新版本B。

 

6、流量控制

流量控制的主要目的是防止短时间内的大并发请求被转发至后端导致业务过载,比较典型的就是DDoS(Distributed Denial of Service,分布式拒绝服务攻击)攻击,恶意攻击者操控大量僵尸机器,持续向目标服务器发送大量请求,让服务器忙于应付而无暇处理正常用户的请求,达到业务系统瘫痪的目的。为了防止这种情况出现,API网关可以对外部请求做限流。

常见的限流算法包括计数器算法、漏桶算法和令牌桶算法。

  • 计数器算法是一种简单粗暴的限流算法,它的设计思想是限制一秒内允许通过的最大请求数,例如,设置限流QPS(Queries Per Second,每秒请求数)为100,那么,从第一个请求到来开始计时,在接下去的1s内,每来一个请求,就把计数加1,如果累加的数字达到100,后续的请求就会被全部拒绝。等到1s结束后,计数器重置为0,重新开始计数。计数器算法有一个弊端:如果在单位时间1s内的前10ms,已经通过了100个请求,那么,后面的990ms将拒绝所有到来的请求,我们把这种现象称为“突刺现象”。

  • 为了消除“突刺现象”,出现了漏桶算法。漏桶算法内部有一个“容器”,类似生活中用到的漏斗。当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终保持不变,每10ms处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃。漏桶算法也存在弊端:无法应对短时间的突发流量。

  • 令牌桶算法是对漏桶算法的一种改进,漏桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用的平均速率的同时,还允许一定程度的突发调用。在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则就等待可用的令牌,或者直接拒绝。放令牌这个动作持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这时进来的请求就可以直接拿到令牌执行,比如设置QPS为100,那么限流器初始化完成1s后,桶中就已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。

 

7、服务熔断

在实际生产环境中,一些服务很有可能因为某些原因发生故障而不可用,比如服务内部错误、网络延迟等,如果放任故障服务不管,可能会因为级联故障导致“雪崩效应”,使得整个系统瘫痪。例如,服务A调用服务B,服务B再调用服务C,如果服务C变得不可用,阻塞了大量上游请求,服务B的请求线程也将随之阻塞,紧接着,服务A也将变得不可用,整个调用链路被拖垮。

 

熔断机制是应对雪崩效应的一种微服务链路保护机制。我们在各种场景下都会接触到熔断这两个字。高压电路中,如果某个地方的电压过高,熔断器就会熔断,对电路进行保护。股票交易中,如果股票指数过高,也会采用熔断机制,暂停股票的交易。同样,在微服务架构中,熔断机制也是起着类似的作用。当调用链路中的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

 

参考

微服务架构深度释疑(一):为何需要API网关?

初识API网关 / API Gateway

从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析

https://www.cnblogs.com/kirito-c/p/12394038.html

『互联网架构』软件架构-API接口安全网关《service变controller》

Optimizing the Netflix API

 

以上是关于API Gateway的主要内容,如果未能解决你的问题,请参考以下文章

502 Bad Gateway (too big header) on Elastic Beanstalk Nginx with Rails 5 App in Production

0601-Zuul构建API Gateway-API gateway简介

Krakend api-gateway的连接被拒绝错误?

CPNtools协议建模-----门卫过滤两种帧存储方式

如果在 Terraform 模块中创建了 aws_api_gateway_integration,如何在 aws_api_gateway_deployment 资源上填充depends_on?

api-gateway实践(14)新服务网关 - 业务场景验证api-gateway-engine携带有效token访问SvcApp (未完!!!!!!!!!!)