从零开始学习SpringBoot

SpringCloud Zuul

2018-09-12  本文已影响3人  BzCoder

1.微服务网关简介

在微服务环境下,不同的服务有其不同的网络地址,若让客户端直接与各个微服务通信,客户端会多次请求不同微服务,存在跨域请求,处理相对复杂。此时我们就需要使用微服务网关。微服务网关介于服务端与客户端的中间层,所有外部服务请求都会先经过微服务网关,客户只能跟微服务网关进行交互,无需调用特定微服务接口,使得开发得到简化。

2.Zuul简介

Zuul 是开源的微服务网关,可与 Eureka、Ribbon、Hystrix 等组件配合使用,Zuul 它的核心是一系列过滤器,这些过滤器可完成下面功能:

3.配置

Maven

引入spring-cloud-starter-netflix-eureka-clientspring-cloud-starter-netflix-zuul

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

添加注解

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

最后记得将他注册到注册中心上,就可以直接运行了,是不是非常简单呢?

4.详细配置

  routes:
    product: /myProduct/**
  ignored-patterns:
   - /**/product/**
/**
 * 跨域配置
 *
 * @author BaoZhou
 * @date 2018/9/13
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();


        config.setAllowCredentials(true);
        //可以写域名,比如http://www.baidu.com
        config.setAllowedOrigins(Arrays.asList("*"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowedMethods(Arrays.asList("GET","POST"));
        config.setMaxAge(300L);
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter();
    }
}
zuul:
  routes:
    product: /myProduct/**
  ignored-patterns:
     - /**/product/**
  sensitiveHeaders:
 @ConfigurationProperties("zuul")
    @RefreshScope
    public ZuulProperties zuulProperties() {
        return new ZuulProperties();
    }

Zuul有四种过滤器:

限流 令牌桶

public class RateLimitFilter extends ZuulFilter {
    private static final RateLimiter RATE_LIMITER =RateLimiter.create(100);
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        if(!RATE_LIMITER.tryAcquire())
        {
            throw new RateLimitException();
        }
        return null;
    }
}

添加请求头

public class AddResponseHeaderFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return SEND_RESPONSE_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletResponse response = requestContext.getResponse();
        response.setHeader("X-Foo",UUID.randomUUID().toString());
        return null;
    }
}

校验请求参数

public class TokenFilter extends ZuulFilter {

    /**
     * 指定过滤器类型
     * 可以从常量中去选取
     * public static final String ERROR_TYPE = "error";
     * public static final String POST_TYPE = "post";
     * public static final String PRE_TYPE = "pre";
     * public static final String ROUTE_TYPE = "route";
     *
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 设置过滤器优先级,数字越小优先级越高
     * public static final int DEBUG_FILTER_ORDER = 1;
     * public static final int FORM_BODY_WRAPPER_FILTER_ORDER = -1;
     * public static final int PRE_DECORATION_FILTER_ORDER = 5;
     * public static final int RIBBON_ROUTING_FILTER_ORDER = 10;
     * public static final int SEND_ERROR_FILTER_ORDER = 0;
     * public static final int SEND_FORWARD_FILTER_ORDER = 500;
     * public static final int SEND_RESPONSE_FILTER_ORDER = 1000;
     * public static final int SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
     * public static final int SERVLET_30_WRAPPER_FILTER_ORDER = -2;
     * public static final int SERVLET_DETECTION_FILTER_ORDER = -3;
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 处理逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        //从Url参数里获取token,也可以从cookie,header里获取
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token))
        {
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

一般在run里写逻辑,shouldFilter里写是否需要过滤来保证逻辑的清晰。

文中很多内容引用自https://www.jianshu.com/p/29e9c91e3f3e,特别感谢!

上一篇下一篇

猜你喜欢

热点阅读