springcloud2.0 -- zuul

pom依赖

    
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-zuul
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

在启动类上面加入注解

@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ExampleZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExampleZuulApplication.class, args);
    }

}

我们需要将zuul也加入到eureka的注册列表中(配置上zuul可能有办法不需要注册成为eureka的客户端,通过url进行转发,zuul的功能和nginx差不多)

zuul拦截器

public class QueryParamPreFilter extends ZuulFilter {

    /**
     * pre:路由之前
     * routing:路由之时
     * post: 路由之后
     * error:发送错误调用
     * @return
     */
    @Override
    public String filterType() {
        // 路由之前
        return "pre";
    }

    @Override
    public int filterOrder() {
        // 过滤的顺序
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        // 这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        // 过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问
        return null;
    }
}

创建一个类继承ZuulFilter,同时run里面就是执行的逻辑,filterType指的处理的行为,注释已经列出了返回值对应的行为,问题来了,如果都需要处理怎么办? 如果是路由前中后都需要处理, 那么理论上你需要创建三个类,都继承ZuulFilter,同时三个类的filterType返回为对应的行为。run中执行改行为需要做的操作。

zuul 配置文件

server:
  port: 8751
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
zuul:
  routes:
    example:
      path: /**
      serviceId: example-feign
    ## 当给定路径无法访问时,跳转到默认的路由
    error: /error/**

演示模板,zuul.routes.example.path 将所有解析的路径都映射到实例id为 example-feign的实例上(实例id通过eureka可以获得,打debug可以看到猫腻),example-feign是下一章要讲的负载均衡,这里不做太多的介绍。

error这个配置意为当给定路径无法访问时会跳转到默认的路由,同时需要新增一个类

public class MyFallbackProvider implements FallbackProvider {

    // 下一级路由无法访问时的跳转处理
    // 要为所有路由提供默认回退则可以设置为 * 或者 null
    @Override
    public String getRoute() {
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "SUCCESS";
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("Service-Timeout".getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

类似重定向到一个统一的错误页面上,和nginx访问不到重定向到500页面一样。当然你可以配置为不跳转,就默认原路径返回。

最后

在一些简单的应用上可以直接使用nginx代替zuul,不用做太多的复杂的路由跳转,但是在复杂的应用上,例如security或者要验证token,cookies等,zuul的拦截器可以帮我们很好的处理,虽然zuul的功能和nginx有点类似,但是仍然有他的使用场景,nginx我们还是尽量保持整洁,不做太多业务层上的操作。

你可能感兴趣的:(java)