一、什么是动态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 {@Overridepublic 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.FilterConstantsclass GroovyFilter extends ZuulFilter {private static final Logger LOGGER = LoggerFactory.getLogger(GroovyFilter.class)@OverrideString filterType() {return FilterConstants.PRE_TYPE}//过滤器优先级@Overrideint filterOrder() {return 5}@Overrideboolean shouldFilter() {return true}@OverrideObject 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);}}

Zuul实现Groovy加载动态Filter相关推荐

  1. Spring Cloud实战小贴士:Zuul的饥饿加载(eager-load)使用

    上一篇 我们介绍了如何使用Ribbon的 earger-load配置加速Spring Cloud中对服务接口的第一次调用.可是这样只是解决了内部服务间的调用,另外一个问题依然经常困扰我们,那就是网关到 ...

  2. Linux系统程序运行时加载动态库路径顺序

    程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 链接时路径(Link-time path)和运行时路径(Run-time ...

  3. php无法加载dll插件,php无法加载动态库怎么办

    php无法加载动态库的解决办法:1.将PHP的集成包里的"libmySQL.dll"复制到system32目录下:2.将PHP的解压目录添加到PATH里:3.在Apache的配置文 ...

  4. 使用Poco实现插件方式加载动态库

    动态库封装虚基类 //AbstractPlugin.h #ifndef __ABSTRACTPLUGIN_H__ #define __ABSTRACTPLUGIN_H__#include <st ...

  5. sunPKCS11加载动态库(转)

    sunPKCS11加载动态库(转) http://www.cnblogs.com/sunfb/archive/2013/03/01/2938491.html 这篇文章不介绍具体的编程方法,而是针对PK ...

  6. tableview动态修改和删除_Ubuntu加载动态库失败的解决方案

    在ubuntu下代码编译通过的情况下,经常出现运行时加载动态库出错的情况.这些问题很琐碎,不具备任何技术含量,纯属耽误时间,这也是linux系统的通病,花里胡哨,故弄玄虚. 为了减少初学者在这种无意义 ...

  7. php7.2 加载pgsql驱动,PHP启动:无法加载动态库PGSQL - php

    我正在尝试使用运行Symfony 3.x: Ubuntu 16.04 PHP 7.0 NGinx 我想与我创建的PGSQL数据库进行交互,但出现此错误: PHP警告:PHP启动:无法加载动态库 '/u ...

  8. PHP: 在类(class)中加载动态函数, 变量函数或半变量函数 variable function/method

    最终实例在下方 以前用过cakephp, 他们的数据库查询还是蛮强大的, 后来好奇它的类的写法,比如: <?php $this->Post->findByTitle('My Firs ...

  9. 替换Android中VM 加载动态库方式

    Android 加载动态库的代码在 dalvik/vm/Native.cpp ( froyo 中是 Native.c),加载的方式就是调用 libdl 中 dlopen, dlsym 这些函数 应该可 ...

最新文章

  1. touchdesigner下载_TouchDesigner Pro Mac版下载_TouchDesigner Pro Mac版官方下载-太平洋下载中心...
  2. 杰和弯道超车 推企业级NAS存储应用方案
  3. 你要的云小信是范爷?柳岩?还是奶茶MM?
  4. oracle audit文件,[20191128]oracle Audit文件管理2.txt
  5. 编写干净的测试–验证或不验证
  6. 二十八种未授权访问漏洞合集(暂时最全)
  7. HTML鼠标点击文字语音播放,10款jQuery+HTML5实现的鼠标点 经过播放音频
  8. Chrome 开发工具 Workspace 使用
  9. trufflesuite/truffle-hdwallet-provider
  10. Centos7 安装python3.7.0
  11. 黑马品优购项目的总结-首页
  12. 锐捷服务器虚拟化技术_锐捷核心交换机VSU虚拟化配置
  13. Android5.1开机LOGO与开机动画
  14. 王煜全分析:四大类手机游戏的未来机会
  15. vue项目查看脚手架版本报错
  16. android 通知栏设置,安卓手机通知栏介绍:安卓手机通知栏设置方法
  17. 技术学校面试该说什么_我第一次现场技术面试后,香港专业教育学院学到了什么...
  18. word骨灰级水平,赶紧留一份
  19. Hi3516的venc编码模块处理流程
  20. mysql mybatis分表查询_mybatis 自动分表

热门文章

  1. 136wm打印机无线安装流程
  2. input 输入框限制只能输入两位有效小数
  3. 华为云DevCloud一枝独秀
  4. 优化长尾关键词有什么好处?在线长尾关键词挖掘
  5. 写在末日来临之前的2012 CSDN 博客之星评选
  6. 双目立体视觉三维重建
  7. 无线营销新蓝海----解析H5应用场景的四大类型
  8. 一些想说的话,无关技术
  9. kubectl top查看资源占用
  10. html5 offsetx,HTML5将发布OFFSETX OFFSETY跳(HTML5 Drag Release offset