zuul的使用,过滤规则配置

LD is tigger forever,CG are not brothers forever, throw the pot and shine forever.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code,Keep progress,make a better result.

目录

概述

架构特性

设计思路

实现思路分析

1.核心逻辑

  ​zuul的核心逻辑都是由一系列filter过滤器链实现的,但是filter的类型不同,执行的时机也不同,效果自然也不一样,主要特点如下: ​ filter的类型:filter的类型,决定了它在整个filter链中的执行顺序,可能在端点路由前执行,也可能在端点路由时执行,还有可能在端点路由后执行,甚至是端点路由发生异常时执行。 ​ filter的执行顺序:同一种类型的filter,可以通过filterOrder()方法设置执行顺序,一般都是根据业务场景自定义filter执行顺序。 ​ filter执行条件:filter运行所需的标准,或条件。 ​ filter执行效果:符合某个filter执行条件,产生执行效果。 ​ zuul内部有一套完整的机制,可以动态读取编译运行filter机制,filter与filter之间不直接通信,在请求线程中会通过RequestContext来共享状态,它内部是用ThreadLocal实现的,例如HttpServletRequest、HttpServletResponse、异常信息等。部分源码如下:

2。主控制类

zuul中不同类型的filter执行逻辑的核心在ZuulServlet类中,主要代码如下:

public class ZuulServlet extends HttpServlet {
private static final long serialVersionUID = -3374242278843351500L;
private ZuulRunner zuulRunner;
@Override
public void init(ServletConfig config) throws ServletException {
    super.init(config);
 
    String bufferReqsStr = config.getInitParameter("buffer-requests");
    boolean bufferReqs = bufferReqsStr != null && bufferReqsStr.equals("true") ? true : false;
 
    zuulRunner = new ZuulRunner(bufferReqs);
}
 
@Override
public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
    try {
        init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
 
        // Marks this request as having passed through the "Zuul engine", as opposed to servlets
        // explicitly bound in web.xml, for which requests will not have the same data attached
        RequestContext context = RequestContext.getCurrentContext();
        context.setZuulEngineRan();
 
        try {
	        //如果preRoute方法在执行的时候出现异常,直接就抛出500异常,不会走catch中的error方法,见下图FilterProcessor类中的preRoute方法。
            preRoute(); 
        } catch (ZuulException e) {
			//如果preRoute在执行过程中,抛出Zuul异常,这里被捕捉到以后,会执行error方法,打印堆栈信息,见下图FilterProcessor类中的error方法。
			error(e); 
            postRoute();
            return;
        }
        try {
            route();
        } catch (ZuulException e) {
            error(e);
            postRoute();
            return;
        }
        try {
            postRoute();
        } catch (ZuulException e) {
            error(e);
            return;
        }
 
    } catch (Throwable e) {
        error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
    } finally {
        RequestContext.getCurrentContext().unset();
    }
  }  //.......
}

生命周期

pre:在zuul网关按照规则路由到下级服务之前执行,如果需要对请求进行预处理,可以使用这种类型的过滤器。如:认证鉴权,限流等。
route:这种过滤器是zuul路由动作的执行者,是Apache HttpClient或Ribbon构建和发送原始HTTP请求的地方,现在也支持OKHTTP。
post:这种过滤器是在端点请求完毕,返回结果或者发生异常后执行的filter。如果需要对返回的结果进行再次处理,可以在这种过滤中处理逻辑。
error: 这种过滤器是在整个生命周期内,如果发生异常,就执行该filter,可以做全局异常处理。

自定义Filter

public class PreFilter extends ZuulFilter {
 
    /**
     * filter类型
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
 
    /**
     * 同一个类型下的filter的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }
 
    /**
     * 为true时 run执行
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public Object run() throws ZuulException {
        System.out.println("这是一个自定义的zuulFilter");
        //RequestContext 支持多个filter 执行传递参数   相当于ThreadLocal
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String a = request.getParameter("a");
        if(a == null){
            //对改请求禁止路由,即禁止访问下游服务
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseBody("error");
            requestContext.set("key", false);
            return null;
        }
        requestContext.set("key", true);
        return null;
    }
}

3.2.自定义PostFilter类集成ZuulFilter

public class PostFilter extends ZuulFilter {
 
    /**
     * filter类型
     */
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }
 
    /**
     * 同一个类型下的filter的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }
 
    /**
     * 为true时 run执行
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        requestContext.getResponse().setCharacterEncoding("UTF-8");
        String responseBody = requestContext.getResponseBody();
        if(responseBody != null){
            requestContext.setResponseStatusCode(500);
            requestContext.setResponseBody(responseBody);
        }
        System.out.println("  post filter ");
        return null;
    }
}
@EnableEurekaClient
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(ZuulApplication.class);
 
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
        LOGGER.info("================ zuul start success ==============");
    }
 
    @Bean
    public PreFilter preFilter(){
        return new PreFilter();
    }
 
    @Bean
    public PostFilter postFilter(){
        return new PostFilter();
    }
}

相关工具如下:

实验效果:(解决思路)

分析:

小结:

主要讲述了一些zuul的使用,过滤规则配置,里面有许多不足,请大家指正~

参考资料和推荐阅读

1.链接: 参考资料.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Cloud Zuul是一个基于Netflix Zuul构建的微服务网关框架。它可以用来处理服务之间的路由、负载均衡、安全验证等问题。下面是一个简单的使用示例: 1. 首先,在pom.xml文件中添加Spring Cloud Zuul依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> ``` 2. 在启动类中添加`@EnableZuulProxy`注解,启用Zuul代理功能: ```java @SpringBootApplication @EnableZuulProxy public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class, args); } } ``` 3. 创建一个过滤器类来实现自定义的过滤逻辑。可以继承`ZuulFilter`类并实现其中的方法: ```java @Component public class MyFilter extends ZuulFilter { @Override public String filterType() { return "pre"; // 定义过滤器类型为“pre”,表示在请求路由之前执行过滤逻辑 } @Override public int filterOrder() { return 0; // 设置过滤器的执行顺序,数字越小越先执行 } @Override public boolean shouldFilter() { return true; // 是否启用该过滤器,返回true表示启用 } @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); // 自定义过滤逻辑,比如添加请求头、进行身份验证等 return null; } } ``` 4. 在配置文件中配置Zuul的路由规则。比如,可以将请求 `/api/**` 转发到名为 `service-a` 的服务: ```yaml zuul: routes: service-a: path: /api/** serviceId: service-a ``` 注意:需要在配置文件中配置服务注册中心的地址,并且保证 `service-a` 这个服务已经注册到了服务注册中心。 以上就是一个简单的Spring Cloud Zuul使用示例。通过配置路由规则和自定义过滤器,可以实现灵活的微服务网关功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执于代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值