美文网首页
Spring-Zuul动态加载过滤器

Spring-Zuul动态加载过滤器

作者: small瓜瓜 | 来源:发表于2019-07-29 13:00 被阅读0次

    Spring Zuul核心组件是过滤器,路由转发都是通过各种过滤器实现。作为网关服务器,它需要不间断的工作。就算是内部逻辑要改变,也最好不要使其停止工作。

    • 对于路由规则的改变,可以通过远程配置中心来实现不停止服务的改变规则。
      但是对于过滤器这种通过编码实现的规则,通过java实现是比较麻烦的。但是我们可以通过基于JVM上的动态语言groovy来实现。

    这里我就跳过服务注册中心和远程配置中心的创建直接创建Zuul服务了

    • 创建一个Maven项目pom.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>spring-cloud-myTest</artifactId>
            <groupId>top.itreatment</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>zuulTest</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zuul</artifactId>
                <version>RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
                <version>1.3.4.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all -->
            <dependency>
                <groupId>org.codehaus.groovy</groupId>
                <artifactId>groovy-all</artifactId>
                <version>3.0.0-beta-2</version>
                <type>pom</type>
            </dependency>
    
        </dependencies>
    
    </project>
    
    • 创建一个配置属性类:
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties("zuul.auto.filter")
    public class FilterConfiguration {
    
        private String root;
        private Integer interval;
    
        public String getRoot() {
            return root;
        }
    
        public void setRoot(String root) {
            this.root = root;
        }
    
        public Integer getInterval() {
            return interval;
        }
    
        public void setInterval(Integer interval) {
            this.interval = interval;
        }
    }
    
    • 配置文件
    server:
      port: 1025
    
    spring:
      application:
        name: api-getway
    
    zuul:
      routes:
        api-a:
          path: /api-a/**
          serviceId: service-provider
        api-b:
          path: /api-b/**
          url: forward:/local
      auto:
        filter:
          root: filterRoot
          interval: 5
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
    • 创建一个启动类
    import com.netflix.zuul.FilterFileManager;
    import com.netflix.zuul.FilterLoader;
    import com.netflix.zuul.groovy.GroovyCompiler;
    import com.netflix.zuul.groovy.GroovyFileFilter;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    import org.springframework.context.annotation.Bean;
    import top.itreatment.config.FilterConfiguration;
    
    @SpringBootApplication
    @EnableZuulProxy
    @EnableConfigurationProperties(FilterConfiguration.class)
    public class ZApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ZApplication.class, args);
        }
    
        @Bean
        public FilterLoader filterLoader(FilterConfiguration configuration) {
            FilterLoader filterLoader = FilterLoader.getInstance();
            filterLoader.setCompiler(new GroovyCompiler());
            try {
                FilterFileManager.setFilenameFilter(new GroovyFileFilter());
                FilterFileManager.init(
                        configuration.getInterval(),
                        configuration.getRoot() + "/pre",    // 路径一定要存在,管理器不会自动创建
                        configuration.getRoot() + "/post"    // 路径不存在就会报异常,抛出的信息并不友好
                );
            } catch (Exception e) {
                throw new RuntimeException();
            }
            return filterLoader;
        }
    }
    
    • 下面编写一个Groovy文件:
    import com.netflix.zuul.ZuulFilter
    import com.netflix.zuul.context.RequestContext
    import com.netflix.zuul.exception.ZuulException
    import org.slf4j.Logger
    import org.slf4j.LoggerFactory
    
    
    class PreGroovyFilter extends ZuulFilter {
    
        private Logger logger = LoggerFactory.getLogger(PreGroovyFilter.class)
    
        @Override
        String filterType() {
            return "pre"
        }
    
        @Override
        int filterOrder() {
            return 50
        }
    
        @Override
        boolean shouldFilter() {
            return true
        }
    
        @Override
        Object run() throws ZuulException {
            def request = RequestContext.getCurrentContext().getRequest()
            logger.info("this is a pre filter: Send{} request to{}",
                    request.getMethod(), request.getRequestURL().toString())
            def parameter = request.getParameter("accessToken")
            if (parameter == null) {
                logger.warn("accessToken is null")
            } else {
                logger.warn("accessToken is {}", parameter)
            }
            return null
        }
    }
    

    上面的文件可以动态添加
    到这需要编写的文件就全部搞定了,我们启动看看效果

    相关文章

      网友评论

          本文标题:Spring-Zuul动态加载过滤器

          本文链接:https://www.haomeiwen.com/subject/eigvrctx.html