背景
在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的服务他们自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest Api 风格的接口来被 H5, Android, IOS 以及第三方应用程序调用。消息队列是方便服务与服务之间的通信解耦。,如下图所示:
那么这时候问题来了,如果一个外部的应用(浏览器、App)要去访问这个大应用怎么办? 很简单啊,直接通过HTTP请求不就完了?
问题
假设我们要使用微服务架构构建一个电商平台,以下可能是一些潜在的服务:
购物车服务
订单服务
商品服务
评论服务
库存服务
等等,客户端应该怎么访问这些服务呢?原来单体应用的情况我们都知道,都在一个服务器上部署,直接访问IP+端口+服务前缀即可,现在微服务架构下,每个服务都可以独立部署,并且是由不同的开发团队开发的,难道我们要这样访问吗?
理论上每个服务都有端点可以访问,但是客户端就需要记录所有服务的端点,发起5次请求,现在还是5个服务,如果之后扩展多了呢?对客户端来说就是一个灾难,随之带来的就是安全性问题、扩展性问题等,所以这种客户端直接与每个服务交互是不可取的,通常,更好的方式是使用 API 网关。
1、不同的客户端设备可能需要不同的数据。Web,H5,APP,需要单独写一套API。
2、用户请求一个页面的数据,会涉及到与多个服务器进行交互,通信成本比较大且用户体验不佳。
3、对于API的鉴权,限流,安全等控制,需要每个微服务去自己实现,增加了微服务的复杂性,同时也违反了微服务设计的单一职责原则。
这样显然是不好的设计,因此API网关出现了。
API网关
API 网关是客户端访问服务的统一入口,API 网关封装了后端服务,还提供了一些更高级的功能,例如:身份验证、监控、负载均衡、缓存、多协议支持、限流、熔断等等,API 网关还可以针对不同的客户端定制不同粒度的 API,上面例子中修改架构后如下:
所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。其出现也是侧面贯彻了软件工程中"高内聚,低耦合"的思想。
核心作用
API 网关负责请求路由、API组合和协议转换。来自外部客户端的所有API请求首先会先转到API网关,后者再将请求路由到相应的服务。API网关使用API组合模式处理其他请求,调用多个服务并聚合结果。同时他还可以在客户端友好的协议(例如HTTP)与客户端不友好的协议之间进行转换。
请求路由
当API网关收到请求时,随机会查询路由映射,该映射将指定请求路由到哪个服务。例如,路由映射可以将HTTP方法和路径映射到服务的HTTP URL,这一点和Nginx提供的反向代理的功能是一样的,后面我们也会对其进行一个比较。 既然有路由映射,那存放在哪就是一个问题了,我们需要为API网关设置一个路由映射的存储位置,通过可能会用zookeeper等作为注册中心来使用,文末我们也会提一下弊端。
API组合
除去反向代理这个功能外,API网关还提供了API组合的操作。以上面的淘宝详情页为例,如果我们单独获取视频、商品价格、商品评论等信息,需要发多个请求(getVideo,getPrice,getComments)。有了API网关后我们就可以将API接口组合起来,通过一次请求(getItemDetail)来获取需要的信息,如下图所示,这样可以极大的改善由于网络延时导致的差用户体验。
协议转换
API网关可以为外部客户端提供RESTful API,即使内部的服务使用混合的通信协议,例如REST、gRPC等。这样做的好处是,对于外部客户端而言,服务端更像是一个不可见的黑盒。
API 网关的优缺点
-
优点
封装了应用程序的内部结构。客户端只需要同网关交互,而不必调用特定的服务。API 网关为每一类客户端提供了特定的 API ,从而减少客户端与应用程序间的交互次数,简化客户端代码的处理。 -
缺点
增加了一个必须开发、部署和维护的高可用组件。还有一个风险是 API 网关变成了开发瓶颈。为了暴露每个微服务,开发人员必须更新 API 网关。API 网关的更新过程要尽可能地简单,否则为了更新网关,开发人员将不得不排队等待。不过,虽然有这些不足,但对于大多数现实世界的应用程序而言使用 API 网关是合理的。
在计算机网络中,网关(Gateway)是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。
在微服务的架构模式下,客户端与微服务直接通信很少是合理的,更好的方法是使用 API 网关,由 API 网关作为后端服务系统的唯一入口。它封装了系统内部架构,为每个客户端提供一个定制的 API 。由它负责服务请求路由、组合及协议转换。有的 API 网关还有其它职责,如身份验证、监控、负载均衡、缓存。