zuul网关zuulFilter动态加载

本文讲述的是通过FilterFileManager实现zuul网关动态加载zuulFilter

zuul网关支持动态加载zuulFilter,原理是通过 FilterFileManager 监控 zuulFilter文件存放路径,定时扫描指定路径达到如发现 zuulFilter文件增加或修改,便进行编译加载。
源码 FilterFileManager 中需要注意的是

// 该方法中 pollingIntervalSeconds 为刷新频率 与方法startPoller()相关 
//directories 为监控 zuulFilter文件存放路径 ,可多个。
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();
    }
	
	//该方法便是为了一个定时扫描的线程
	 void startPoller() {
        this.poller = new Thread("GroovyFilterFileManagerPoller") {
            public void run() {
                while(FilterFileManager.this.bRunning) {
                    try {
                        sleep((long)(FilterFileManager.this.pollingIntervalSeconds * 1000));
                        FilterFileManager.this.manageFiles();
                    } catch (Exception var2) {
                        var2.printStackTrace();
                    }
                }

            }
        };
        this.poller.setDaemon(true);
        this.poller.start();
    }
	// 该方法负责扫描加载
	 void manageFiles() throws Exception, IllegalAccessException, InstantiationException {
        List<File> aFiles = this.getFiles(); //负责扫描获取指定目录下所有 FilenameFilter.accept验证过的文件
        this.processGroovyFiles(aFiles);//扫描文件中的 zuulFilter 文件并编译加载
		
    }
	//通过FilterLoader.putFilter()方法,检查每一个文件中 zuulFilter 是否需要编译加载
	 void processGroovyFiles(List<File> aFiles) throws Exception, InstantiationException, IllegalAccessException {
        Iterator var2 = aFiles.iterator();

        while(var2.hasNext()) {
            File file = (File)var2.next();
            FilterLoader.getInstance().putFilter(file);
        }

    }

源码 FilterLoader.putFilter

 public boolean putFilter(File file) throws Exception {
        String sName = file.getAbsolutePath() + file.getName();
        if (this.filterClassLastModified.get(sName) != null && file.lastModified() != (Long)this.filterClassLastModified.get(sName)) {
            LOG.debug("reloading filter " + sName);
            this.filterRegistry.remove(sName);
        }

        ZuulFilter filter = this.filterRegistry.get(sName); 
        if (filter == null) {
            Class clazz = COMPILER.compile(file); //获取文件中的zuulFilter
            if (!Modifier.isAbstract(clazz.getModifiers())) {
                filter = FILTER_FACTORY.newInstance(clazz);
                List<ZuulFilter> list = (List)this.hashFiltersByType.get(filter.filterType());
                if (list != null) {
                    this.hashFiltersByType.remove(filter.filterType());
                }

                this.filterRegistry.put(file.getAbsolutePath() + file.getName(), filter);
                this.filterClassLastModified.put(sName, file.lastModified());
                return true;
            }
        }

        return false;
    }

    本文介绍的并非是通过 GroovyCompiler(DynamicCodeCompiler) GroovyFileFilter(FilenameFilter) Groove代码方式实现动态加载zuulFilter,而是通过自定义FilenameFilter 和 DynamicCodeCompiler 实现    
    这两个自定义可以在项目启动后配置,即添加一个实现CommandLineRunner接口的bean,配置代码可以放在实现的run方法中
 

import com.netflix.zuul.FilterFileManager;
import com.netflix.zuul.FilterLoader;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class DynamicFilterRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        FilterLoader.getInstance().setCompiler(new DynamicZuulFilterCompiler());//加入自定义实例创建类
        FilterFileManager.setFilenameFilter(new JarFileFilter());//加载文件过滤验证类
        FilterFileManager.init(1," 文件加载路径");//载入刷新频率 和 文件加载路径
    }
}

根据自己的需要创建实例

import com.netflix.zuul.DynamicCodeCompiler;

import java.io.File;

public class DynamicZuulFilterCompiler implements DynamicCodeCompiler {
    @Override
    public Class compile(String s, String s1) throws Exception {
        return null;
    }

    @Override
    public Class compile(File file) throws Exception {
        /**
         * 根据 file文件内容自定义获取并创建实例
         */
        Class<?> aClass = Class.forName("com.TestZuulFilter");
        return aClass;
    }
}

文件加载路径下筛选文件的条件(例如下方是帅选出jar包文件)
 

import java.io.File;
import java.io.FilenameFilter;

/**
 * @author peihua
 * 
 * JavaFileFilter description: JAR格式验证
 *
 */
public class JarFileFilter implements FilenameFilter {

    @Override
    public boolean accept(File dir, String name) {
        // 验证文件是否已.jar文件结尾
        return name.endsWith(".jar");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值