Zuul作为微服务系统的网关组件,用于构建边界服务,致力于动态路由、过滤、监控、弹性伸缩和安全。

Zuul功能

  • 认证
  • 压力测试
  • 金丝雀测试
  • 动态路由
  • 负载削减
  • 安全
  • 静态响应处理
  • 主动/主动交换管理

为什么需要Zuul

   Zuul、Ribbon(Fegin)以及Eureka结合可以实现智能路由和负载均衡的功能;网关将所有服务的API接口统一聚合,统一对外暴露。外界调用API接口时,不需要知道微服务系统中各服务相互调用的复杂性,保护了内部微服务单元的API接口;网关可以做用户身份认证和权限认证,防止非法请求操作API接口;网关可以实现监控功能,实时日志输出,对请求进行记录;网关可以实现流量监控,在高流量的情况下,对服务降级;API接口从内部服务分离出来,方便做测试。

       Zuul通过Servlet来实

现,通过自定义的ZuulServlet来对请求进行控制。核心是一系列过滤器,可以在Http请求的发起和响应返回期间执行一系列过滤器。Zuul采取了动态读取、编译和运行这些过滤器。过滤器之间不能直接通信,而是通过RequestContext对象来共享数据,每个请求都会创建一个RequestContext对象。

  Zuul生命周期如下图。 当一个客户端Request请求进入Zuul网关服务时,网关先进入”pre filter“,进行一系列的验证、操作或者判断。然后交给”routing filter“进行路由转发,转发到具体的服务实例进行逻辑处理、返回数据。当具体的服务处理完成后,最后由”post filter“进行处理,该类型的处理器处理完成之后,将Request信息返回客户端。 

  Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器.

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-zuul</artifactId>

</dependency>

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

  

   引入spring-cloud-starter-netflix-eureka-client的目的是本身通过url映射的方式来实现zuul的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了。实际上在实现微服务架构时,服务名与服务实例地址的关系在eureka server中已经存在了,所以只需要将Zuul注册到eureka server上去发现其他服务,就可以实现对serviceId的映射。

  加入yml的配置文件,主要用来连接eureka,及配置网关路由规则

  server: port: 8088

  spring.application.name: startGateway

  eureka: client:

    service-url:

      defaultZone: http://root:root@localhost:10000/eureka

  zuul.routes.three.path: /three/**

  zuul.routes.three.service-id: three

  zuul.routes.three.stripPrefix: false

  zuul.routes.five.path: /five/**

  zuul.routes.five.service-id: five

  zuul.routes.five.stripPrefix: false

这边有个坑:

设置 zuul.prefix 可以为所有的匹配增加前缀, 例如 /api,代理前缀默认会从请求路径中移除(通过 zuul.stripPrefix=false 可以关闭这个功能).

  1. 反响代理配置  
  2. 这里的配置类似nginx的反向代理  
  3. 当请求/api/**会直接交给listOfServers配置的服务器处理  
  4. 当stripPrefix=true的时候 (http://127.0.0.1:3333/api/user/list -> http://192.168.1.100:8080/user/list)  
  5. 当stripPrefix=false的时候(http://127.0.0.1:5555/api/user/list -> http://192.168.1.100:8080/api/user/list)  
  6. zuul.routes.api.path=/api/**  
  7. zuul.routes.api.stripPrefix=false  
  8. api.ribbon.listOfServers=192.168.1.100:8080,192.168.1.101:8080,192.168.1.102:8080

  你也可以在指定服务中关闭这个功能:

zuul.routes.five.path: /five/**
zuul.routes.five.service-id: five
zuul.routes.five.stripPrefix: false
  在这个例子中, 请求"/five/a"将被跳转到"five"服务的"/five/a"上.如果不配置 stripPrefix: false的话就会默认路由到/a上,忽略/five这个前缀,导致404找不到资源
package cn.chinotan;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; /**
* @program: test
* @description: 启动类
* @author: xingcheng
* @create: 2018-12-9 15:39
**/
@SpringCloudApplication
@EnableEurekaClient
@EnableZuulProxy
public class StartGateway { public static void main(String[] args) {
SpringApplication.run(StartGateway.class, args);
} }

  就完成了一个简单的网关路由

  其中@EnableZuulProxy是@EnableZuulServer的加强,@SpringCloudApplication会包含@EnableEurekaClient,所以其实@EnableEurekaClient不需要写

之后在写两个测试controller进行路由判断:、

package cn.chinotan.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* @program: test
* @description: zuul测试控制器
* @author: xingcheng
* @create: 2018-12-08 18:09
**/
@RestController
@RequestMapping("/five")
public class ZuulTestFiveController { @GetMapping("/hello/{name}")
public String ZuulTestFive(@PathVariable("name") String name) {
return "hello " + name + " this is ZuulTestFive";
}
}
package cn.chinotan.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* @program: test
* @description: zuul测试控制器
* @author: xingcheng
* @create: 2018-12-08 18:09
**/
@RestController
@RequestMapping("/three")
public class ZuulTestThreeController { @GetMapping("/hello/{name}")
public String ZuulTestFive(@PathVariable("name") String name) {
return "hello " + name + " this is ZuulTestThree";
} }

服务过滤

Zuul还有一个主要的功能,便是服务过滤,比如,用户在登录前,可以将服务请求过滤到指定的页面去。 
  其中,filterType方法,返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:pre:路由之前

routing:路由之时 
       post: 路由之后 
       error:发送错误调用 
       filterOrder:过滤的顺序 
       shouldFilter:这里可以写逻辑判断,是否要开启过滤 
       run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。
      一般我们在使用时,不手打“pre”这些类型,而是通过调用Zuul中已写好的FilterConstants类,其中封装了所有的过滤器类型。这样可以避免打错字符而导致错误的发生。

  类似的过滤器很多,我们可以自定义,从而实现统一的网关控制、监控、跨域、流量控制、负载均衡,身份认证,服务降级等等。

@Component
public class MyFilter extends ZuulFilter {
  @Override
  public String filterType() {
    return FilterConstants.PRE_TYPE;
  }

  @Override
  public int filterOrder() {
    return 0;
  }

  @Override
  public boolean shouldFilter() {
    return true;
  }

  @Override
  public Object run(){
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();
    Object accessToken = request.getParameter("token");
    if(accessToken == null) {
      ctx.setSendZuulResponse(false);
      ctx.setResponseStatusCode(401);
      try {
        ctx.getResponse().setHeader("Content-Type", "text/html;charset=UTF-8");
        ctx.getResponse().getWriter().write("登录信息为空!");
      }catch (Exception e){}
        return null;
      }
        return null;
      }
  }  

SpringCloud-技术专区-Zuul-使用指南的更多相关文章

  1. Springcloud技术分享

    Springcloud技术分享 Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来 ...

  2. SpringCloud学习之zuul

    一.为什么要有网关 我们先看一个图,如果按照consumer and server(最初的调用方式),如下所示 这样我们要面临如下问题: 1. 用户面临着一对N的问题既用户必须知道每个服务.随着服务的 ...

  3. springcloud 实战 网关zuul使用中遇到的相关问题

    springcloud 实战  网关zuul使用中遇到的相关问题 1.网关zuul使用时,跨域问题在网关中配置pre过滤器: response.setHeader("Access-Contr ...

  4. SpringCloud解析之Zuul(二)

    本文基于Spring Cloud Edgware.SR6,Zuul版本1.3.1,解析Zuul的请求拦截机制,让大家对Zuul的原理有个大概的认识和了解.如有不对的地方,欢迎指正. 在上一期的Spri ...

  5. 基于SpringCloud搭建项目-Zuul篇(六)

    本文主要介绍zuul的基本原理和在sprngcloud服务下如何使用 一.简单介绍 Zuul 是 Netflix OSS 中的一员,是一个基于 JVM 路由和服务端的负载均衡器.提供路由.监控.弹性. ...

  6. 【SpringCloud技术专题】「Gateway网关系列」(3)微服务网关服务的Gateway全流程开发实践指南(2.2.X)

    开发指南须知 本次实践主要在版本:2.2.0.BUILD-SNAPSHOT上进行构建,这个项目提供了构建在Spring生态系统之上API网关. Spring Cloud Gateway的介绍 Spri ...

  7. SpringCLoud之搭建Zuul网关集群

    1.使用技术 Springboot,SpringCloud,Zuul,Nignx 2.目的 使用Zuul搭建微服务高可用的网关 3.项目创建 3.1 创建注册中心(略) 3.2 创建一个hello-s ...

  8. SpringCloud技术涵盖简介

    SpringCloud是微服务架构的集大成者,云计算最佳业务实践. 我们平常使用的Spring和他们的关系,对Spring,springboot , SpringCloud 的 概念区分,上图: Sp ...

  9. SpringCloud学习之Zuul统一异常处理及回退

    一.Filter中统一异常处理 其实在SpringCloud的Edgware SR2版本中对于ZuulFilter中的错误有统一的处理,但是在实际开发当中对于错误的响应方式,我想每个团队都有自己的处理 ...

  10. SpringCloud之网关 Zuul(四)

    一 Zuul简介 zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用. Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.Z ...

随机推荐

  1. linux装mysql

    1.对于MySQL-5.6.35-1.el6.x86_64.rpm-bundle.tar来说 2.命令: rpm -Uvh MySQL-*.rpm 3.将my.cnf复制到/etc下 4.记得关掉se ...

  2. 西里尔字 俄语 - Cyrillic

    https://zh.wikipedia.org/wiki/%E8%A5%BF%E9%87%8C%E5%B0%94%E5%AD%97%E6%AF%8D 其他编码[编辑] 其他适用西里尔字母的字符编码系 ...

  3. reduce 好东西

    reduce()方法可以搞定的东西,for循环,或者forEach方法有时候也可以搞定,那为啥要用reduce()?这个问题,之前我也想过,要说原因还真找不到,唯一能找到的是:通往成功的道路有很多,但 ...

  4. java的BigDecimal比较大小

    java的BigDecimal比较大小 //前提为a.b均不能为null if(a.compareTo(b) == -1){ System.out.println("a小于b"); ...

  5. 【leetcode】989. Add to Array-Form of Integer

    题目如下: For a non-negative integer X, the array-form of X is an array of its digits in left to right o ...

  6. shell倒计时下班时间

    #!/bin/sh offWorkTime="19:00:00" offWorkHour=${offWorkTime::} offWorkMinute=${offWorkTime: ...

  7. STM32串口USART通信总结

    一.GPIO设置USART的初始化 /**************************实现函数******************************************** *函数原型: ...

  8. 低价购买 (动态规划,变种最长下降子序列(LIS))

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  9. layui多图上传加隐藏域

    我的情况是,通过layui上传图片调用后端,后端将图片上传后返回图片路径,上传成功后将图片在页面显示出来(避免用户网速不稳定,图片其实还没上传成功就进行下一步操作),然后同步每个图片增加隐藏域,最终表 ...

  10. BZOJ5484: [Usaco2018 Dec]Sort It Out

    5484: [Usaco2018 Dec]Sort It Out https://www.lydsy.com/JudgeOnline/problem.php?id=5484 Sol. 考虑没有在被喊叫 ...