API 网关简介
API 网关是一个系统对外提供服务的单一入口。从设计模式的角度来看,API 网关很像外观模式。API 网关封装系统内部的结构并对外提供统一的接入方式。API 网关还拥有其他功能,比如权限管理、SSL、监控(流控)、负载均衡、缓存、协议转换和静态数据响应等等【1 / 2】
API 网关在对外提供接口的时候有两种形式。一种如下图所示,所有调用方都使用相同的 API 网关服务。还有一种形式,不同类型的客户端调用不同的接口,这种方式可参考 Pattern: API Gateway / Backends for Frontends,本文不做介绍
网关的优点
API 网关的优点如下:
- 通过减少 endpoints 的个数降低客户端代码复杂度;同时降低客户端和服务端的耦合程度
- 一些场景下由网关封装客户端对服务端的多次请求,以减少耗时
- 减少服务端和客户端因通信协议不同造成的不便。一般情况下 API 网关只对外提供一种通信协议,比如 HTTP/WebSocket 等
- 网关可以通过各种策略保护后端服务,比如流控,鉴权等等
- 其他
网关职能示例
- SSL 验证 / web app 防火墙 / 静态文件服务
- 参数校验 / 鉴权 / IP 黑白名单 / 用户黑白名单
- 协议转换 / 客户端限流 / 日志与监控 / Mock 测试 / 超时控制
- 返回值缓存 / 返回值压缩 / 熔断 / 降级
- 沙箱测试 / AppKey&签名校验
- 其他
网关相关技术
接入服务的统一访问方式(非必须)
根据 API 网关的特点,网关调用下游服务时需要使用统一的接口,比如 invoke
如果需要接入网关的服务没有提供服务的统一调用接口,那么网关在接入新服务时就需要引入特定服务的依赖,比如新的 jce/tars 文件或者 jar 包
对于通用网关而言统一的访问方式是必须的,但对于只针对某些特殊场景的网关而言,因为接口变化并不频繁,所以服务没有或者不使用通用访问方式也是可以接受的
对于推荐而言,几乎所有服务对外接口的形式都是一致的,所以推荐网关对外接口可以直接使用现有推荐接口
同步与异步调用
网络服务的编程模式按照其发展可以分为同步(IO/worker 阻塞),半异步(非阻塞 IO、阻塞worker)和全异步(非阻塞 IO/worker)这几种方式。网关一般需要同时支持多个不同的下游服务,为了减少下游服务之间的相互影响,网关一般推荐使用全异步实现方式
在网关中使用同步调用的优点和缺点都十分明显,优点是简单。缺点也很明显,在网关线程数量有限的前提下,一个下游服务的超时抖动会明显影响线上其他服务的耗时。通过给同步调用设置超时时间可以减少异常服务对网关的影响,但超时时间的设置相对比较麻烦,需要一定的经验
异步调用可以通过设置一个通用的超时时间,一个服务的超时会在一个时间段内积累大量的超时访问,通过一定的手段(比如计数,并设置单位时间内超时访问数上限)触发降级,从而降低异常服务对网关和其他服务的影响
配置中心与本地配置缓存
网关的一些基础功能(比如限流)需要实时配置与更新,这就需要一个高可用配置中心(比如 redis/mysql/zk)。为了高可用性,在配置中心失效时服务依旧可以使用本地缓存的历史配置启动,这就需要网关服务实现配置的本地缓存功能(比如 序列化/levedb)
责任链模式(Pipe)
网关除分流功能外还有很多基础功能,如下图中间所示(API GATEWAY),网关中需要处理的这些任务可以使用 PipeTask 进行抽象与组合。这些 task 是顺序处理的,类似于责任链模式,又因为执行流程类似于 linux 下的管道命令,所以一些资料将整个流程抽象为管道(pipe)