概念
API Gateway(API GW / API 网关),顾名思义,是企业 软件系统在系统边界上提供给外部访问内部接口服务的统一入口。网关并不是微服务所特有的,实际上网关在微服务之前就已经存在很久了,例如银行、证券等领域常见的前置机系统,它实际就是一个网关。
API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理、流量控制、日志、重试、熔断等。
在微服务场景下,网关的功能基本没有变化,即网关是微服务的入口,处理所有的非业务功能。
网关功能性需求
路由
对于微服务架构来说,一般都是由多个微服务共同对外提供服务,每个服务对外提供部分接口,这些接口提供的功能,共同组成完整的可用的系统功能。
当用户发送一个请求后,对于传统的单体架构来说,因为只有一个服务来对外提供服务(负载均衡见下文),所以根据请求的地址即可定位到对应的服务。但是对于微服务来说,因为有多个服务对外提供服务,所以系统需要有能力分辨出对应的请求应该委托给哪个具体的服务来处理,这就是路由的功能。
网关作为系统的入口,需要提供路由功能。同时考虑到,网关是整个系统的入口,一旦网关停止服务,则整个系统都无法对外提供服务。所以网关不能够频繁的启停,故路由模块需要能够动态的配置规则。
负载均衡
一般情况下,为了可用性,每个服务都需要做集群部署,即每个服务至少需要部署两个实例对外提供服务,避免单个实例时,由于服务本身的问题,导致该实例无法对外提供服务。
当一个服务进行了集群部署后,请求来访问时,需要确定由哪个服务来处理该请求,即负载均衡。
注意,此处「确定处理请求的服务」的逻辑和上面的路由逻辑不是一个概念。路由是根据请求来匹配到目标服务,此处是从多个不同功能的服务中确定服务;而负载均衡是在其之后,当匹配了目标服务后,由于有多个目标实例,需要从中选择一个来处理,此处是从多个相同功能的服务中选择一个来处理该请求。
对于网关来说,需要提供负载均衡的功能,至于是否需要支持动态负载均衡算法的调整,考虑到负载均衡算法确定后,一般不会变化,所以不需要动态调整负载均衡算法的功能。至于是否需要支持多种负载均衡算法,可以视具体情况而定。
聚合服务
上面的「路由」处理的是一个请求直接由对应服务来处理的场景。
前面说了,微服务中每个服务提供的是系统的一部分功能,所以可能一个完整的功能需要由多个微服务来提供服务,这可能就需要客户端为了完成某个功能发送多次请求。这会导致几个问题:
- 多次的网络请求会影响系统性能
- 客户端需要调用多个服务,对于前端开发人员来说,开发体验不够友好
所以,网关需要提供「聚合服务」的功能,即客户端只需要发送一个请求到网关,网关针对该请求,向多个目标微服务发送请求,将请求结果整合后返回给客户端。
服务聚合有如下优缺点:
优点:
- 解耦:服务聚合封装了应用的内部结构,客户端直接和网关通信,而不必关注特定的服务。当对应某个服务的接口发生了改变,客户端不需要调整,在网关进行调整即可
- 针对性优化:可以对每种客户端提供特定的优化API,例如:某个系统有PC和手机端,都有订单详情页面,但是手机端需要的信息要比手机端少很多,此时可以通过网关针对PC和手机端提供不同的API。对于手机端可以提供一个简化的API接口,提高访问性能。
- 简化客户端逻辑:原来需要客户端发送多个请求才能完成的功能,可以通过一个请求来完成,降低了客户端的开发复杂度。
- 性能优化:客户端发送的请求是公共网络请求,聚合服务后,公共网络请求变成了内部网络请求,性能相对提高了一些。
缺点:
- 需要开发:针对每个聚合服务API都需要进行开发,增加了额外的开发、测试、部署、管理成本。
- 影响高可用:聚合服务会从两个方面影响网关的可用性
- 由于需要发布新接口,需要频繁发布网关。上面说了,网关是系统的入口,频繁的发布可能会导致系统的可用性下降。需要考虑平滑发布或接口的热发布,这又增加了网关本身的开发难度。
- 同时,由于网关中包含了请求逻辑,代码逻辑错误可能也会降低网关的可用性。对于网关代码需要做较多的防御性编程保障。
具体哪些接口需要进行聚合,哪些直接进行委托,需要视具体接口而定。故网关,需要支持聚合服务的可编码功能。同时为了网关的稳定性,最好能支持聚合服务的动态发布。
认证授权
网关作为系统的入口,需要做好安全防护,否则后端的所有服务都会存在安全隐患。除了基本的网络安全防护外(算法签名,SSL 加密等),网关需要处理整个系统的认证(Authentication)和授权(Authorization)。
权限是资源的集合,在微服务里资源可以认为就是对外提供的接口服务。具体的权限配置上,可以将权限分为:操作权限和数据权限。
操作权限:用户在系统中的任何动作、交互都是操作权限,如增删改查等。
数据权限:一般系统,都有数据私密性的要求,即哪些人可以看到哪些数据,不可以看到哪些数据。例如:不同租户下的用户只能看到对应租户下的数据;相同租户下的不同角色看到的数据也有差异,比如:普通角色只能看自己的薪资信息,会计角色可以看到所有人的薪资信息。
如果对数据权限细化的话,还可以细分出一个「页面权限」:所有系统都是由一个个的页面组成,页面再组成模块,用户是否能看到这个页面的菜单、是否能进入这个页面就称为页面权限。
另外,操作权限还可以细化一个「菜单权限」:即哪些用户可以看到/操作哪些菜单。
对于网关来说,需要提供较完善的「认证」和「授权」功能,以保障整个系统的安全。
过载保护
系统在设计之初就会有一个预估容量,超过系统所能承受的容量阈值称为过载。长时间超过系统能承受的容量阈值,系统可能会被压垮,最终导致整个服务不可用。
为了避免这类情况的发生,需要对系统进行过载保护。一般方式有:流量控制、熔断和服务升降级。
流量控制
流量控制的目的是通过对「并发访问请求数量进行控制」或者「一个时间窗口内的的请求数量进行控制」来保护系统,一旦达到控制速率则可以拒绝服务、排队或等待。
流量控制可以针对整个系统,也可以针对单个接口来进行控制。
网关需要控制单位时间内接口允许被调用次数,以保护后端服务,实现用户分级。可以根据接口的重要程度来配置不同流控,从而保障重要业务的稳定运行;支持用户、应用和例外流控,可以根据用户的重要性来配置不同流控,从而可以保证大用户的权益;流控粒度:分钟、小时、天。
熔断
当一个服务对外无响应或者响应时间很长时,此种情况下可能会导致请求的大量积压,继而影响整个系统对外提供服务。熔断可以避免此类问题的发生。
当一个服务对外无响应或者响应时间过长时,对该服务进行熔断操作。即对该服务的请求立即返回特定的结果,避免请求积压。等一段时间后,恢复服务对外提供服务。如果服务还是无法对外服务,则再次触发熔断。
服务升降级
上面的流量控制和熔断都是相对比较「公平」的方法,主要是为了保证系统的可用性。在系统过载的情况下,无差别的对待所有的服务/接口。
不过对于一个系统来说,有些服务是核心服务而有些服务是非核心服务,对于核心服务来说,即使在系统过载的情况下也不能拒绝对外服务,否则这个系统实际就失去了它原有的价值。这个时候就需要非核心业务为核心业务让路,即在系统过载的时候,非核心服务让出系统资源,即服务降级,保障核心服务能稳定的对外提供服务。待系统负载正常后,再恢复非核心服务。
缓存
对于经常调用的接口,且结果基本不会出现变化的接口,可以对这些接口进行缓存。缓存后的接口,由于请求不会到达目标服务端,可以给系统带来如下好处:
- 减少了请求链路
- 降低了系统的响应时间
- 降低了微服务的负载
同时也带来了如下劣势:
- 需要同步缓存与接口结果,增加了开发难度
- 需要管理缓存,增加运维成本
在后端并发和处理能力不够的情况下,将缓存前置来提供更好的服务,而且是从网关层统一处理,可简化后端服务处理的复杂度。
服务重试
对于某些服务,可能会由于某些原因导致服务短时间内没有响应,例如网路波动。当出现这些情况的时候,默认情况下客户端会直接收到错误消息。对于某些服务,可以通过重试的方式来降低/避免此类问题。即如果某次请求,对应的服务在规定时间内,没有得到响应,则自动再尝试一次/n次,如果成功则返回结果。如果多次尝试后,依然失败,则再返回错误消息。
服务重试在某些情况下能提高系统的可用性。
日志
日志记录是对整个微服务的要求,需要记录请求访问日志,便于后期对请求访问的统计分析、问题定位。
管理
对于上面的功能,为了方便操作,最好能提高管理界面。例如:
- 路由配置界面
- 服务升降级界面
- 服务调用统计界面
- 服务发布管理界面
- ......
网关的非功能性需求
安全性
系统把服务暴露给外部使用时,首先要确保服务使用的安全,防止外部的恶意访问对业务的影响,特别是涉及交易方面的服务,更是要全面考虑安全性。为确保安全,需要考虑在通讯链路的建立、通讯数据的加密、数据的完整性、不可抵赖性等方面的安全。
性能
网关作为整个系统的入口,所有的请求都会先经过网关,或由网关直接处理、或从缓存获取数据、或转发给后面的微服务进行具体的业务处理、或转换为多个请求由服务处理后再整合结果。
可以看出,网关是整个系统中访问压力最大的组件,如果设计不当,无法保证高性能,则很容易成为整个系统的瓶颈。同时,为了保障系统容量,则可能需要投入大量的硬件设备,通过横向扩容的方式来提高网关层的容量。这无疑增加了系统的投入成本。
所以保障网关的高性能,是保证整个系统高性能的前提条件。
高可用
网关作为整个系统的入口,一旦发生问题,将造成这个系统的不可用。所以必须保障网关的高可用,可用性需要达到4个9以上,即99.99%以上。尽量达到5个9,即99.999%。
也就是说需要保障网关全年故障时间在50分钟以内,最好能达到5分钟以内,保证网关可用性不会影响整个系统的可用性。
扩展性
前面说到,网关需要提供例如日志、安全、负载均衡策略、鉴权等功能。对于这些功能,需要能方便的扩展,以适应业务的不断发展。同时由于这些功能会随着业务逻辑或规模的变化,不断进行强化与调整。以及系统的可用性考虑,建议网关层能提供热部署机制,使得可以灵活地进行这些调整和变化,而不用频繁对网关进行改动,确保网关的稳定性。
伸缩性
上面说了,网关是整个系统的入口,为了保证系统能快速的伸缩,网关必须要提供方便的伸缩能力,这就需要保证网关是无状态的。
服务监控
能够对服务接口进行监控,包括:调用量、调用方式、响应时间、错误率等。能够清楚的了解服务接口的运行状况和用户的行为习惯。
支持自定义报警规则,来针对异常情况进行报警,降低故障处理时间。提供可订阅的数据分析报表和智能分析。
需求优先级
网关作为整个系统的入口,核心功能包括:
- 路由
- 负载均衡
- 认证授权
- 过载保护
同时需要保障:
- 高性能
- 高可用
- 伸缩性
对于聚合服务,缓存,服务重试,扩展性(热加载)功能,管理等需求,是优化性需求,提高网关的易用性,可以延后实现。
对于日志、服务监控功能作为网关的基础支撑类需求,可以通过开源项目快速实现,后续迭代的方式进行改进。
总结
本文梳理了微服务网关的需求,下一篇将对微服务网关进行设计。
出处:https://www.toutiao.com/i6901239029547909643