• API网关服务:Spring Cloud Zuul

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

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

  首先,对于路由规则与服务实例的维护问题。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文件中引入相关依赖:

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,然后启动该服务。在网关服务的启动类中,添加如下代码:

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

  • 网关总结

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

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

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

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

Spring Cloud学习笔记-009的更多相关文章

  1. Spring Cloud学习笔记--Spring Boot初次搭建

    1. Spring Boot简介 初次接触Spring的时候,我感觉这是一个很难接触的框架,因为其庞杂的配置文件,我最不喜欢的就是xml文件,这种文件的可读性很不好.所以很久以来我的Spring学习都 ...

  2. Spring Cloud 学习笔记 (一)-- Eureka 服务器

    开局一张图,截取了本人学习资料中的一张图,很好地展示了Eureka的架构. Eureka服务器 管理服务的作用.细分为服务注册,服务发现. 所有的客户端在Eureka服务器上注册服务,再从Eureka ...

  3. Spring Cloud 学习笔记(二)——Netflix

    4 Spring Cloud Netflix Spring Cloud 通过自动配置和绑定到Spring环境和其他Spring编程模型惯例,为Spring Boot应用程序提供Netflix OSS集 ...

  4. Spring Cloud 学习笔记(一)——入门、特征、配置

    [TOC] 0 放在前面 0.1 参考文档 http://cloud.spring.io/spring-cloud-static/Brixton.SR7/ https://springcloud.cc ...

  5. Spring Cloud学习笔记-006

    服务容错保护:Spring Cloud Hystrix 在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调 ...

  6. Spring Cloud学习笔记-005

    服务消费者 之前已经搭建好了微服务中的核心组件——服务注册中心(包括单节点模式和高可用模式).也有了服务提供者,接下来搭建一个服务消费者,它主要完成两个目标,发现服务以及消费服务.其中,服务发现的任务 ...

  7. Spring Cloud学习笔记-002

    搭建Spring Cloud注册中心:Eureka 服务注册:在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号.版本号.通信协议等一些附加信息告诉注 ...

  8. Spring Cloud学习笔记-007

    声明式服务调用:Spring Cloud Feign Feign基于Netflix Feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两 ...

  9. Spring Cloud学习笔记-008

    继承特性 通过上节的示例实践,当使用Spring MVC的注解来绑定服务接口时,几乎完全可以从服务提供方的Controller中依靠复制操作,构建出相应的服务客户端绑定接口.既然存在这么多复制操作,自 ...

随机推荐

  1. 自己开发的 vue 滑动按钮组件 vue-better-slider

    写在前面的 这个人第一次尝试开发并发布一个 vue 的组件,该组件实现了类似 ios 手机淘宝客户端 -> 消息界面中消息的滑动删除功能等,如下为该组件的文档. 一个 Vue 的滑动按钮组件,有 ...

  2. Java多线程:线程池

    一. 背景 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池可以对线程进行统一的分配.调优和监控,并有以下好处:     第一:降低资源消耗.通过重复利用已 ...

  3. /etc/nginx/nginx.conf配置文件详解

    user nginx; #数值和cpu核数个数一致worker_processes 8; #worker与cpu绑定 worker_cpu_affinity 0001 0010 0100 1000 1 ...

  4. bug单的生命周期

    测试工程师发现了软件的缺陷(bug),那修复bug的整个流程是怎么样的呢? 1.发现bug 2.和开发确认是否是bug 3.如果是bug则提bug单到测试经理,如果不是则放过 4.测试经理把bug单走 ...

  5. Jquery瀑布流布局,jQuery Wookmark Load 示例

    瀑布流布局非常适合大量图片的展示,一改过去裁剪图片尺寸同意的排版,每张图片都能完全展示,并错落有致,让人眼前一亮. 注意事项:img元素的width和weight属性需要写,否则定位会不准确. 查看j ...

  6. MySQL数据库操作类(PHP实现,支持连贯操作)

    <?php /** * Author: suvan * CreateTime: 2018/2/27 * description: 数据库操作类(仅对接MySQL数据库,主要利用MySQLi函数) ...

  7. 2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

    2017-2018-1 20155306 <信息安全系统设计基础>Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解 ...

  8. 记一次jar包冲突

    题记:永远不要在同一个项目中,引用不同版本的两个jar包,否则,这可能就是一个大坑. 在做网校项目的时候,帮助中心要使用lucene,所以就引入了lucene-5.5.1的包,删掉了原先存在于项目中的 ...

  9. linux的脚本应用for循环答应变量

    #!/bin/bash for var in A B C ; do echo "var is $var" done

  10. Eclipse常用快捷键总结

    Eclipse常用快捷键总结 CTRL+C(复制).CTRL+X(剪切).CTRL+Z(撤销).CTRL+F(查找).CTRL+H(搜索文件或字符串).CTRL+Y(重做).CTRL+/(双斜杠注释) ...