spring cloud网关zuul源码之Filter管理

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取 2000+ 道 Java 面试题

接上一篇request管理。

原文地址:http://blog.csdn.net/haha7289/article/details/54344150

zuul支持动加载Filter类文件。实现原理是监控存放Filter文件的目录,定期扫描这些目录,如果发现有新Filter源码文件或者Filter源码文件有改动,则对文件进行编译加载。目前zuul支持使用Groovy编写的Filter。

FilterFileManager

FilterFileManager用于管理Filter存放目录,并定期扫描目录的变化。
20191123100145\_1.png
他的功能如下:

  • 开启一个线程,开始轮询
    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();
        }
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 每次轮询,处理目录内的所有*.groovy文件,即调用FilterLoader.getInstance().putFilter(file);

    void processGroovyFiles(List<File> aFiles)  {
            for (File file : aFiles) {
                FilterLoader.getInstance().putFilter(file);
            }
        }

        void manageFiles() throws Exception, IllegalAccessException, InstantiationException {
            List<File> aFiles = getFiles();
            processGroovyFiles(aFiles);
        }
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

FilterLoader

编译、加载filter文件,并且检查源文件是否有变更,除此之外,它还按照filterType组织并维护List<ZuulFilter>

20191123100145\_2.png

主要逻辑

     public boolean putFilter(File file) throws Exception {
        String sName = file.getAbsolutePath() + file.getName();
        // 如果文件在上次加载后发生了变化,重新编译加载
        if (filterClassLastModified.get(sName) != null && (file.lastModified() != filterClassLastModified.get(sName))) {
            filterRegistry.remove(sName);
        }
        ZuulFilter filter = filterRegistry.get(sName);
        if (filter == null) {
            // 编译、加载文件
            Class clazz = COMPILER.compile(file);
            if (!Modifier.isAbstract(clazz.getModifiers())) {
                filter = (ZuulFilter) FILTER_FACTORY.newInstance(clazz);
                // 为了下次Request使用filter,清空filter.filterType()类型的List<Filter>缓存,下次Request重新构建
                List<ZuulFilter> list = hashFiltersByType.get(filter.filterType());
                if (list != null) {
                    hashFiltersByType.remove(filter.filterType()); //rebuild this list
                }
                // filterRegistry 管理所有的filter,
                filterRegistry.put(file.getAbsolutePath() + file.getName(), filter);
                // 记录filter文件更新时间。
                filterClassLastModified.put(sName, file.lastModified());
                return true;
                }
            }
            return false;
        }
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

这里主要的逻辑是把Groovy源码进行编译并加载进jvm里。

FilterRegistry

用于管理加载的filter,数据结构比较简单,使用
ConcurrentHashMap<String, ZuulFilter> filters,启动key为filter的name:file.getAbsolutePath() + file.getName();

DynamicCodeCompiler

是一个接口,定义两种加载编译源码的方法:

        /** 方法最后返回的是Class,即源码编译成字节码后,还要加载。 需要支持热加载,文件变化更新等。 */
        Class compile(String sCode, String sName) throws Exception;

        Class compile(File file) throws Exception;
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

总结

zuul整体框架比较简单,如果要实现API-Gateway,或者client-api adapter code,可以参考下。框架背后的思想也许更值得我们参考。

参考


来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring cloud网关zuul源码之Filter管理

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏