Spring Cloud Zuul学习笔记(一)

2018-11-27  本文已影响0人  会飞的三文鱼

Zuul 属于Netflix旗下一款产品,而Spring很好对其做了整合

Zuul是一个边缘服务,提供动态路由、监控、弹性、安全性等等。相关的用法、信息、操作方式等 请查看WIKI https://github.com/Netflix/zuul/wiki

Spring Cloud Netflix的文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.M3/single/spring-cloud-netflix.html

一、Getting Start最简单的配置
java文件
@EnableZuulProxy
public class ZuulConfig {

}
yml文件
zuul:
  routes:
    pltf-client:
      path: /pltf/client/**
      service-id: pltf-client
二、对于yml的改进
1、最传统的路由
zuul.routes.client.path=/client/**
zuul.routes.client.url=http://localhost:1166/
2、面向服务的路由

如果每次都要写一串url的话感觉很繁琐,所以用service-id来代替,这里的service-id就是注册服务当中的 service-id

zuul.routes.client.path=/client/**
zuul.routes.client.service-id=client
3、通配符路由

有这样一个场景,由于业务的扩展,版本的升级,服务存在不同的版本。比如我们有这样的命名:client-v1、client-v2,默认情况下,Zuul自动为服务创建的路由表达式会采用服务名做前缀,针对client就会产生/client-v1,/client-v2两个路径来做映射,但这样生成的表达式规则较为单一,不利于路径规则的管理。通常,对于上面这种情况,我们希望是生成的路径为/v1/client,/v2/client。我们可以通过自定义路由规则来实现,具体代码如下:

@Bean
public PatternServiceRouteMapper serviceRouteMapper(){
  return new PatternServiceRouteMapper(
    "(?<name>^.+)-(?<version>v.+$)",
    "${version}/${name}");
}
4、Zuul的过滤器

四种过滤器:

  • PRE:该类型的filters在Request routing到源web-service之前执行。可以进行一些权限认证,日志记录,或者额外给Request增加一些属性供后续的filter使用
  • ROUTING: 该类型的filters用于把Request routing到源web-service,源web-service是实现业务逻辑的服务。这里使用HttpClient请求web-service
  • POST: 该类型的filters在ROUTING返回Response后执行。用来实现对Response结果进行修改,收集统计数据以及把Response传输会客户端;
  • ERROR: 上面三个过程中任何一个出现错误都交由ERROR类型的filters进行处理。

Zuul过滤器具有以下关键特性:

  • Type(类型):Zuul过滤器的类型,这个类型决定过滤器在哪个阶段执行,例如:pre,post等阶段;
  • Execution Order(执行顺序):规定了过滤器的执行顺序,Order的值越小,越先执行;
  • Criteria(标准):Filters执行所需条件
  • Action(行动):如果符合执行条件,则执行Action(具体逻辑代码)
@Sl4j
public class MyPreFilter extends ZuulFilter {

    @Override
    public Object run() {
            RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

       log.info("{} AccessUserNameFilter request to {}", request.getMethod(), request.getRequestURL().toString());
        // 获取请求的参数
        String username = request.getParameter("username");
        // 如果请求的参数不为空,且值为demo时,则通过
        if(null != username && username.equals("demo")) {
          // 对该请求进行路由
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
            // 设值,让下一个Filter看到上一个Filter的状态
            ctx.set("isSuccess", true);
            return null;
        }else{
          // 过滤该请求,不对其进行路由
            ctx.setSendZuulResponse(false);
            // 返回错误码
            ctx.setResponseStatusCode(401);
            // 返回错误内容
            ctx.setResponseBody("{\"result\":\"username is not correct!\"}");
            ctx.set("isSuccess", false);
            return null;
        }
    }

    @Override
    public boolean shouldFilter() {
    // 是否执行该过滤器,此处为true,说明需要过滤
        return true;
    }

    /**
     * 指定该Filter执行的顺序(Filter从小到大执行)
     * DEBUG_FILTER_ORDER = 1;
     * FORM_BODY_WRAPPER_FILTER_ORDER = -1;
     * PRE_DECORATION_FILTER_ORDER = 5;
     * RIBBON_ROUTING_FILTER_ORDER = 10;
     * SEND_ERROR_FILTER_ORDER = 0;
     * SEND_FORWARD_FILTER_ORDER = 500;
     * SEND_RESPONSE_FILTER_ORDER = 1000;
     * SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
     * SERVLET_30_WRAPPER_FILTER_ORDER = -2;
     * SERVLET_DETECTION_FILTER_ORDER = -3;
     */
    @Override
    public int filterOrder() {
    // 优先级为0,数字越大,优先级越低
        return org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public String filterType() {
    // 前置过滤器
        return org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
    }
}
三、Zuul请求生命周期图:
生命周期图
上一篇下一篇

猜你喜欢

热点阅读