天天看點

服務網關zuul1.服務網關和zuul2.路由轉發,排除和自定義3.動态路由4.高可用5.pre和post過濾器6.限流7.鑒權8.跨域(跨域資源共享)

1.服務網關和zuul

1.服務網關的要素:穩定性,高可用。性能,并發性。安全性。擴充性。

2.常用網關方案:Nginx+Lua,Kong,Tyk,Spring Cloud Zuul

3.zuul特點:路由+過濾器=Zuul,核心是一系列的過濾器

4.四種過濾器API:

前置(Pre) :限流,鑒權,參數校驗,請求轉發

路由(Route)

後置(Post): 統計

錯誤(Error)

2.路由轉發,排除和自定義

1.導入依賴

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

2.主類加注解@EnableZuulProxy

3.配置bootstrap.yml

zuul:
  routes:
    #    myProduct:  #任意字元都可以
    #      path: /myProduct/**
    #      serviceId: product
    product: /myProduct/**  #路由自定義(簡潔方式)
  ignored-patterns:
    - /**/product/listForOrder  #排除某些路由
  sensitive-headers:  #開放cookie
management:
  endpoints:
    web:
      exposure:
        include: "*" #/autuator/routes檢視所有路由資訊
      

3.動态路由

@Component
public class ZuulConfig {
    @RefreshScope
    @ConfigurationProperties("zuul")
    public ZuulProperties zuulProperties(){
        return new ZuulProperties();
    }
}      

4.高可用

将多個Zuul節點注冊到Eureka Server上

5.pre和post過濾器

前置pre:

@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE;
    }
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER-1;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}      

後置post

@Component
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 currentContext = RequestContext.getCurrentContext();
        HttpServletResponse response = currentContext.getResponse();
        response.setHeader("X-FOO", UUID.randomUUID().toString());
        return null;
    }
}      

6.限流

限流時機:請求被轉發之前調用(令牌桶限流)

@Component
public class RateLimiterFilter extends ZuulFilter {
    private static final RateLimiter RATELIMITER= 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 (!RATELIMITER.tryAcquire()){
            throw new RateLimiterException();
        }
        return null;
    }
}      

7.鑒權

@Component
public class AuthBuyerFilter extends ZuulFilter {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public String filterType() {
        return PRE_TYPE;
    }
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }
    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        if ("/order/order/create".equals(request.getRequestURI())) {
            return true;
        }
        return false;
    }
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        /**
         * /order/create  隻能買家通路
         * /order/finish  隻能買家通路
         * /product/list  都可以通路
         */
        Cookie cookie = CookieUtil.get(request, "openid");
        if (cookie == null || StringUtils.isEmpty(cookie.getValue())) {
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}      

8.跨域(跨域資源共享)

1.被調用的類或方法上加@CorssOrigin注解

2.在Zuul裡增加CorsFilter過濾器

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter(){
        final UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config=new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Arrays.asList("*"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowedMethods(Arrays.asList("*"));
        config.setMaxAge(300l);
        source.registerCorsConfiguration("/**",config);
        return new CorsFilter(source);
    }
}
      

繼續閱讀