理解WEB API网关
隐藏细节
现实生活中有很多隐藏细节的案例,比如我们平时用的电脑,当我们按电源按钮后电脑就自动开始启动了,对用户来讲很简单只需要知道按按钮就行。但电脑内部的工作原理其实是很复杂的一个流程,这里不多说。
如果不隐藏细节会怎样?
我想可能的结果就是电脑只能是特别特别的专业人员才能操作,永远无法像现在一样成为大家的必备工具。对大多数用户来讲他们根本不知道知道什么CPU,内存,硬盘,显卡相互之间是如何配合工作的,只关心打开电脑后能够正常使用软件完成他们的任务即可。
门面模式
在面向对象设计中,GOF有个门面模式就是对客户端隐藏细节的一个典型应用,也可以看看我早几年前的笔记:门面模式。
WEB API网关
通常WEB API网关是系统的唯一入口,它封装了系统内部架构,为客户端统一提供服务。有一些与业务无关的公共逻辑可以抽象到网关中实现,比如客户端的认证,访问控制,监控,缓存等,示意图如下。
-
客户端认证
无论是对内网还是外网的接口都是需要做用户身份认证的,而用户认证在一些规模大点的公司都会有统一的单点登录系统,如果每个微服务系统都是做对接单点登录系统的工作,那么显然比较浪费资源,开发效率低。可以将认证的部分抽取到网关层,然后微服务系统无需关注认证的逻辑只关注自身业务即可。 -
访问控制
对一些特定的接口设置白名单,访问次数,访问频率等各类设置。而这些非业务功能的配置以及变更不会影响微服务的实现可以在网关层单独做操作。 -
负载均衡
可以灵活的在网关层制定负载均衡策略。 -
安全
可以统一在网关层增加一个额外的保护层来防止恶意攻击,如果客户端直连微服务的话,每个暴露的微服务都需要面临安全问题。
WEB API网关在设计上与上面提供到门面模式是相当的,也是对客户端隐藏细节。除了上面提供的那些常见公共功能外,还有如下一些实用的功能:
限流
对于大型互联网项目还会有限流的需求。为了防止站点不被未知的大流量冲跨,有可能会采取限流的策略,网关配置一个阀值,当请求数超过阀值时就直接返回错误而不会走剩下的逻辑。
限流如何实现?限流的方案有很多:
- 在网关层可以利用hystrix来实现。
- 如果是针对待定的客户端也可以利用nginx的限流。
- guava提供了一个RateLimiter,它是基于令牌桶的算法实现,以固定的速率往队列中放令牌,可以结合它自己实现限流可以结合它自己实现限流。
可兼容更多的协议
比如有些服务是SOAP,基于二进制的Thrift,还有DUBBO这类RPC实现,可以统一转换成HTTP来对外提供。
微服务带来的问题
随着业务的发展,原来简单的系统会变得越来越复杂,一个团队变成多个团队,多个团队同时在一个系统中开发会存在各种各样的问题,数据量的增长也会使单库的性能越来越慢,所以随其自然的会按业务对系统进行垂直划分,比如:
- 产品系统
- 价格系统
- 促销系统
- 订单系统
- 库存系统
- 评论系统
- 推荐系统
- 用户系统
这些系统当下比较流行的是以微服务的形式存在,暴露一批细粒度的接口给其它系统调用。
前端系统如何调用微服务?
比如用户查看一个产品的明细页面,它会包含产品基本信息,价格信息,促销信息,推荐信息,评论信息等,美国大学排名2019按上面的微服务组成,前端系统想拿到产品的所有数据需要调用众多的微服务,这在要求性能的互联网项目上是不太可行的,光http请求就比之前增加多倍,而且也会增加客户端的复杂度,它需要知道所有这些微服务的详细信息。
不要让前端知道微服务的存在
即使系统从业务领域的层次上被划分成多个独立的微服务,但对于前端系统还是应该隐藏细节,提供粗粒度的接口。
系统架构
这里回顾下以前我参与的一个跨境电商系统,从架构来看还是做的比较标准的。前端是APP以及H5,对接一个mobile api,mobile api内部包含各类子服务。
其实我们是针对项目的,电商系统对接mobile api,另外一个线下店的APP对接的新开发的store api。这两个api是完全独立的,并不是一个公司一个web api,所以说我们这两web api是项目级别的网关,而有些公司可能会提供公司级别的网关。
架构简要说明:
- 前端是APP+H5
- H5站点是通过Nginx做反向代理去执行js,不懂APP,所以略过。
- Mobile API,H5以及APP唯一对接后端的入口,采用Spring MVC实现。里面包含了所有前端需要用到的接口。
- 微服务,DUBBO实现的RPC,数据库中间件mybatis。
- 缓存,基于Spring Cache+redis。
- 检索系统,基于elasticsearch。
- 消息系统,RabbitMQ。上图中没有体现,是将业务数据更新到检索系统的一个broker。
未用到限流,当时数据量太小,担心的不是服务器被冲跨是担心没人冲。
也不包含一些并行请求合并的高级用法,可以理解成一个高内聚的服务。
WEB API网关的优点
- 隐藏细节,对客户端友好
- 简化了客户端开发复杂度
- 降低了客户端与服务端交互交互
- 可统一做切面任务,避免每个子系统各自为营,五花八门
- 使客户端与服务端解耦,容易构造异构系统
WEB API网关的缺点
- 需要增加一个高可用伸缩性强的站点。
- WEB API网关项目在开发上是个串行任务,每暴露一个接口都需要去更新WEB API网关,如果同时有不同部门的需求去更新就会存在排队更新的情况。