Spring Cloud学习笔记-009

API网关服务:Spring Cloud Zuul

  API网关是一个更为智能的应用服务器,它的定义相似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面同样,全部的外部客户端访问都须要通过它来进行调度和过滤。它除了要实现请求路由、负载均衡、校验过滤等功能以外,还须要更多能力,好比与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。设计模式

  在Spring Cloud中提供了基于Netflix Zuul实现的API网关组件——Spring Cloud Zuul。api

  首先,对于路由规则与服务实例的维护问题。Spring Cloud Zuul经过与Spring Cloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中得到了全部其余微服务的实例信息。这样的设计很是巧妙地将服务治理体系中维护的实例信息利用起来,将维护服务实例的工做交给了服务治理框架自动完成,再也不须要人工介入。而对于路由规则的维护,Zuul默认会将经过以服务名做为ContextPath的方式来建立路由映射,大部分状况下,这样的默认设置已经能够实现咱们大部分的路由需求,除了一些特殊状况(好比兼容一些老的URL)还须要作一些特别的配置。可是相比于以前架构下的运维工做量,经过引入Spring Cloud Zuul实现API网关后,已经可以大大减小了。浏览器

  其次,对于相似签名校验、登陆校验在微服务架构中冗余问题。理论上来讲,这些校验逻辑在本质上与微服务应用自身的业务并无多大的关系,因此它们彻底能够独立成一个单独的服务存在,只是它们被剥离和独立出来以后,并非给各个微服务调用,而是在API网关服务上进行统一调用来对微服务接口作前置过滤,以实现对微服务接口的拦截和校验。服务器

1. 首先,搭建几个用于路由和过滤使用的微服务应用,但是使用以前的注册中心和demo-member、demo-customer-feign,分别启动三个应用。架构

2. 建立maven工程,骨架选择quickstart,命名为:demo-api-gateway。并发

3. 在pom.xml文件中引入相关依赖:app

4. 建立启动类:负载均衡

5. 在src\main\resources目录下建立application.yml文件:框架

6. 进入注册中心,观察启动的服务:运维

7. 在demo-api-gateway的pom.xml文件中添加Eureka依赖,并在application.yml文件中指定Eureka位置和进行路由的配置:

8. 启动demo-api-gateway服务,分别向网关发起下面请求:

  ◆http://localhost:5217/api-a/member:该url符合/api-a/**规则,由api-a路由负责转发,该路由映射的serviceId为member-service,全部最终/member请求会被发送到member-service服务的某个实例上去。

  ◆http://localhost:5217/api-b/getMember:该url符合/api-b/**规则,由api-b路由负责转发,该路由映射的serviceId为customer-service-feign,全部最终/getMember请求会被发送到customer-service-feign服务的某个实例上去。

  经过面向服务的路由配置方式,咱们不须要再为各个路由维护微服务应用的具体实例的位置,而是经过简单的path与serviceId的映射组合,使得维护工做变得很是简单。这彻底归功于Spring Cloud Eureka的服务发现机制,它使得API网关服务能够自动化完成服务实例清单的维护,完美地解决了对路由映射实例的维护问题。

请求过滤

  Zuul容许开发者在API网关上经过定义过滤器来实现对请求的拦截与过滤,只须要继承ZuulFilter抽象类并实现它定义的4个抽象方法就能够完成对请求的拦截和过滤了。

  下面实现一个简单的Zuul过滤器,它实现了再请求被路由以前检查HttpServletRequest中是否有token参数,如有就进行路由,若没有就拒绝访问,返回401 Unauthorized错误。

1. 定义AccessFilter类,集成ZuulFilter:

名词解释:

◆filterType:该方法须要返回一个字符串来表明过滤的类型,而这个类型就是在HTTP请求过程当中定义的各个阶段。在Zuul中默认定义了4种不一样的生命周期的过滤器类型:

  ■pre:能够在请求被路由以前调用。

  ■routing:在路由请求时被调用。

  ■post:在routing和error过滤器以后被调用。

  ■error:处理请求时发生错误时被调用。

◆filterOrder:经过int值来定义过滤器的执行顺序,数值越小优先级越高。

◆shouldFilter:返回一个boolea值来判断该过滤器是否要执行。能够经过此方法来指定过滤器的有效范围。

◆run:过滤器的具体逻辑,在该方法中,能够实现自定义的过滤逻辑,来肯定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果以后,对处理结果作一些加工等。

2. 实现了自定义过滤器以后,并不会直接生效,还须要为其建立具体的Bean才能启动该过滤器,在启动类中添加以下内容:

3. 重启网关项目,并发起以下请求,对上述定义的过滤器作一个验证:

  ◆http://localhost:5217/api-a/member:返回401错误。

  ◆http://localhost:5217/api-a/member?token=123:正确路由到member-service的/member接口,并返回相应内容。

其余

  经过Eureka与Zuul的整合已经省去了维护服务实例清单的大量配置工做,剩下只须要再维护请求路径的匹配表达式与服务名的映射关系便可。可是在实际运用过程当中会发现,大部分的路由配置规则几乎都会采用服务名做为外部请求的前缀,例如上述的member-seriver,而对应的服务名称也是member-service

  对于这样具备规则性的配置内容,咱们老是但愿能够自动化地完成。Zuul正好默认实现了这样的功能,当Spring Cloud Zuul构建API网关服务引入Spring Cloud Eureka以后,它为Eureka中的每一个服务都自动建立一个默认路由规则,这些默认规则的path会使用serviceId配置的服务名做为请求前缀,如上述的路由配置规则,能够直接注释掉:

  重启网关服务,就可使用服务名做为前缀进行服务的调用:

  对于版本的管理,当微服务有不一样的版本的时候,例如memberservice-v1,固然能够经过微服务名称来区分不一样的版本,从而调用各个版本的服务,可是这样生成出来的表达式规则较为单一,不利于经过路径规则来进行管理。一般的作法是为这些不一样版本的微服务应用生成以版本代号做为路由前缀定义的路由规则,好比/v1/meberservie/。这时候,经过这样具备版本号前缀的URL路径,咱们就能够很容易地经过路径表达式来归类和管理这些具备版本新的微服务了。

  具体操做方法是,首先中止member-service服务,并将其服务名称改成memberservice-v1,而后启动该服务。在网关服务的启动类中,添加以下代码:

  从新启动网关服务,在浏览器中访问测试:

网关总结

◆它做为系统的统一入口,屏蔽了系统内部各个微服务的细节。

◆它能够与服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发。

它能够实现接口权限校验与微服务业务逻辑的解耦。

◆经过服务网关中的过滤器,在各生命周期中去校验请求的内容,将本来在对外服务层作的校验前移,保证了微服务的无状态性,同时下降了微服务的测试难度,让服务自己更集中关注业务逻辑的处理。

相关文章
相关标签/搜索