当前位置: 七九推 > IT编程>开发语言>Java > Zuul实现Groovy加载动态Filter

Zuul实现Groovy加载动态Filter

2023年01月25日 Java 我要评论
一、什么是动态Filter Zuul提供了一个能够对过滤器进行动态的加载、编译、运行的框架。这些过滤器是由Groovy写成,被放在Zuul Server上的特定目录下面。Zuul会按期轮

一、什么是动态Filter

Zuul提供了一个能够对过滤器进行动态的加载、编译、运行的框架。这些过滤器是由Groovy写成,被放在Zuul Server上的特定目录下面。Zuul会按期轮询这些目录,修改过的过滤器会动态的加载到Zuul Server中。这样如果要对过滤器有改动,就不用进行网关的重新发布了,只需要把过滤器上传到指定目录即可

下面我们就基于spring-cloud-starter-zuul(SpringCloud版本为Edgware.SR3)进行扩展,实现动态加载Filter的功能

二、Zuul动态Filter实现

1)、添加groovy依赖

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.12</version>
        </dependency>

2)、加载Groovy脚本

平常开发中有时需要实现在项目启动后执行的功能,SpringBoot提供的一种简单的实现方案就是添加一个Bean并实现CommandLineRunner接口,实现功能的代码放在实现的run方法中

多个CommandLineRunner接口的实现类时,通过@Order注解指定执行顺序

@Component
@Order(value = 1)
public class GroovyLoadLineRunner implements CommandLineRunner {

    @Override
    public void run(String... strings) throws Exception {
        FilterLoader.getInstance().setCompiler(new GroovyCompiler());
        //读取配置,获取脚本根目录
        String scriptRoot = System.getProperty("zuul.filter.root", "groovy/filters");
        //获取刷新间隔
        String refreshInterval = System.getProperty("zuul.filter.refreshInterval", "5");
        if (scriptRoot.length() > 0) {
            scriptRoot = scriptRoot + File.separator;
        }
        FilterFileManager.setFilenameFilter(new GroovyFileFilter());
        FilterFileManager.init(Integer.parseInt(refreshInterval), scriptRoot + "pre",
                scriptRoot + "route", scriptRoot + "post");
    }
}

3)、编写Groovy脚本

import com.netflix.zuul.ZuulFilter
import com.netflix.zuul.context.RequestContext
import org.apache.catalina.servlet4preview.http.HttpServletRequest
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants

class GroovyFilter extends ZuulFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(GroovyFilter.class)

    @Override
    String filterType() {
        return FilterConstants.PRE_TYPE
    }

    //过滤器优先级
    @Override
    int filterOrder() {
        return 5
    }

    @Override
    boolean shouldFilter() {
        return true
    }

    @Override
    Object run() {
        HttpServletRequest request = (HttpServletRequest) RequestContext.getCurrentContext().getRequest()
        Enumeration<String> headerNames = request.getHeaderNames()
        while (headerNames.hasMoreElements()) {
            String name = (String) headerNames.nextElement()
            String value = request.getHeader(name)
            LOGGER.info("header: " + name + ":" + value)
        }
        LOGGER.info("This is Groovy Filter")
        return null
    }

}

现在idea目录中创建存放过滤器的文件夹

启动参数中指定加载网关的目录

-Dzuul.filter.root=/Users/hanxiantao/Desktop/学习笔记/Zuul深入学习/zuul_lab/lab05/zuul_gateway/groovy/filters

先不把Groovy脚本放到目录下,请求网关,并没有GroovyFilter中打印的日志

再把Groovy脚本放到目录下,请求网关,打印日志如下:

在这里插入图片描述

三、Zuul动态加载Filter源码解析

下面我们来看下Zuul是如何实现动态加载Filter的,GroovyLoadLineRunner中我们最后调用了FilterFileManager的init()方法

public class FilterFileManager {

    /**
     * Initialized the GroovyFileManager.
     *
     * @param pollingIntervalSeconds the polling interval in Seconds
     * @param directories            Any number of paths to directories to be polled may be specified
     * @throws IOException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public static void init(int pollingIntervalSeconds, String... directories) throws Exception, IllegalAccessException, InstantiationException {
        if (INSTANCE == null) INSTANCE = new FilterFileManager();

        INSTANCE.aDirectories = directories;
        INSTANCE.pollingIntervalSeconds = pollingIntervalSeconds;
        INSTANCE.manageFiles();
        INSTANCE.startPoller();

    }

init()方法最后调用了startPoller(),这里开启了一个守护线程,会一直循环从我们指定的目录下读取文件,然后放到FilterLoader中,从而实现了动态加载Filter的功能

public class FilterFileManager {

    void startPoller() {
        poller = new Thread("GroovyFilterFileManagerPoller") {
            public void run() {
                while (bRunning) {
                    try {
                        sleep(pollingIntervalSeconds * 1000);
                        manageFiles();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        poller.setDaemon(true);
        poller.start();
    }
  
    void manageFiles() throws Exception, IllegalAccessException, InstantiationException {
        List<File> aFiles = getFiles();
        processGroovyFiles(aFiles);
    }
  
    /**
     * puts files into the FilterLoader. The FilterLoader will only addd new or changed filters
     *
     * @param aFiles a List<File>
     * @throws IOException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    void processGroovyFiles(List<File> aFiles) throws Exception, InstantiationException, IllegalAccessException {

        for (File file : aFiles) {
            FilterLoader.getInstance().putFilter(file);
        }
    }  

本文地址:https://blog.csdn.net/qq_40378034/article/details/109558790

(0)
打赏 微信扫一扫 微信扫一扫

相关文章:

  • 学习Java(重新做人第二天)

    学习Java(重新做人第二天)

    学习Java(重新做人第二天)在mooc上跟翁恺老师学习 ( 面向对象程序设计——Java语言)有秒计时的数字时钟(10分)题目内容:这一周的编程题是需要你在课... [阅读全文]
  • 大专生自学Java到找到工作的经过

    大专生自学Java到找到工作的经过

    刚到大三时前面两年荒废了 什么都没学到所以打算自学个编程 自己对java非常感兴趣 就打算自学java 但是一开始看书 有很多看不懂 非常苦恼 也打算过去培训 ... [阅读全文]
  • 死磕 java同步系列之JMM(Java Memory Model)

    简介java内存模型是在硬件内存模型上的更高层的抽象,它屏蔽了各种硬件和操作系统访问的差异性,保证了java程序在各种平台下对内存的访问都能达到一致的效果。硬件内存模型在正式讲解j…

    2023年01月24日 开发语言
  • Java单例模式下的MongoDB数据库操作工具类

    Java单例模式下的MongoDB数据库操作工具类

    本文实例讲述了java单例模式下的mongodb数据库操作工具类。分享给大家供大家参考,具体如下:我经常对mongodb进行一些基础操作,将这些常用操作合并到一... [阅读全文]
  • Java中关于内存泄漏出现的原因汇总及如何避免内存泄漏(超详细版)

    android 内存泄漏总结内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个…

    2023年01月26日 开发语言
  • 荐
                                                        基于业务描述语言BDL的需求方法论

    荐 基于业务描述语言BDL的需求方法论

    业务需求需求重要吗?业务需求重要吗?为什么重要?它有多重要?需求的切入点在哪里?业务架构与业务需求之间是什么关系?业务需求与软件需求之间又是什么关系?软件需求与... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2023  七九推 保留所有权利. 粤ICP备17035492号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com