网关作用

网关分为两类

  • 入口网关 入口网关将一些服务共有的功能整合在一起,独立部署为单独的一层,用来解决一些服务治理的问题。可以把网关看作系统边界,它可以对出入系统的流量进行统一的管控。网关提供客户端一个统一的接入地址,API网关可以将用户的请求动态路由到不同的业务服务上,并且做一些必要的协议转换工作。

在服务系统中对外暴露的协议可能不同,如http服务,rpc服务等等,甚至有些历史遗留的服务。API网关可以很好的对客户端屏蔽这些服务的地址以及协议细节,给客户端接入带来极大的便捷。 在API网关中可以加入一些服务治理策略,如服务熔断、降级、流量控制、分流等。对于客户端等认证、鉴权也可以放在API网关中。另外还可以配合黑白名单,如设备ID、用户ID等维度策略。在网关中还可以很方便的做一些统计工作,如访问订单服务、商品服务等等。

  • 出口网关 出口网关,在实际的系统开发过程中,会依赖很多外部的三方服务,如三方账号登录、三方支付服务等。所以开发者可以在自身服务和三方服务之间部署出口网关,在出口网关中对外调用外部的API做统一的认证、授权、审计和权限访问。

实现注意细节

  • 性能 API网关承接所有从客户端的所有流量,假如业务处理需要10ms,在API网关处理需要1ms,那么相当于每个API的响应时间需要增加10%,无疑在对性能影响是重大的。提升API网关的性能很重要的一部分在于I/O模型。Netfix开源的API网关Zuul中采用I/O多路复用的模型处理接入的I/O请求,并且使用非阻塞的调用方式。除此之外,API网关中执行动作有些是可以预先定义好的,如黑白名单、接口动态路由等等。API网关在设计的时候需要注意拓展性,方便开发者随时在网关上增加一些逻辑或者下掉一些逻辑。 一般来说,可以把每一个操作定义为一个filter过滤器,然后使用责任链模式将这些过滤器串起来。责任链可以动态的组织这些过滤器,解偶过滤器之间的关系,无轮增加还是减少都对其他过滤器无任何影响。(过滤器通常分为三种过滤器:1. 路由前过滤器 2. 路由过滤器 3. 路由后过滤器)

WechatIMG8

  • 线程隔离/保护 为了提升网关的并行处理能力,一般使用线程池来执行请求。当在后端服务响应缓慢的时候,线程池中线程就会被后端的缓慢服务消耗殆尽,那么其他服务的请求就会受到影响,所以我们要针对不同的服务做线程隔离或者保护。 以下两种方法:
    • 如果后端的服务拆分的不多,可以针对不同的服务采用不同的线程池,这样发生故障的服务就不会影响其他正常的服务了
    • 线程池内部可以针对不同服务甚至不同的接口做线程保护。如线程池的最大线程是1000,那么可以给每个服务设置一个最多的使用配额。(在golang中可以适当的控制携程数量,来达到控制线程数的相同目的)

如何引用API网关

用电商应用举个例子,在服务层和客户端之间有一层Web层,这个Web层主要做两个方面的事情:

  1. 对服务层接口数据的聚合。如商品详情页的接口可能聚合到服务层总,获取商品信息、用户信息、店铺信息以及用户评论等多个服务的接口数据。
  2. Web层可能需要将Http请求转换成RPC请求,且对某些请求添加黑名单功能等。因此我们在做改造的时候可以先将API网关先从Web层中独立出来,将协议转换、限流、黑明单等功能搬到API网关中来处理,形成独立的入口网关

针对服务接口数据聚合的操作一般两种解决思路是:

  • 独立一组网关专门做聚合、超时控制方面的事情,前一种网关称作流量网关,后一种称作业务网关
  • 抽取独立的服务层,做门做接口聚合操作。这样服务层就大概分为原子服务层和聚合服务层。

接口数据聚合是业务操作,与其放在通用网关来实现不如放在更贴近业务的服务层来实现

WechatIMG7