美文网首页
SpringCloud 2.0 之 zuul

SpringCloud 2.0 之 zuul

作者: rommy020 | 来源:发表于2018-08-28 16:47 被阅读0次

官网:https://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul.html

zuul 介绍

Zuul是Netflix的基于JVM的微服务网关, 介于服务端与客户端的中间层,所有外部服务请求都会先经过微服务网关, 他可以与Eureka, Ribbon, Hystrix配合使用.
微服务网关好处:
1: 客户只能跟微服务网关进行交互,无需调用特定微服务接口,使得开发得到简化
2: 易于监控,微服务网关可收集监控数据并进行分析
3: 易于认证,可在微服务网关上进行认证,然后在将请求转发给微服务,无须每个微服务都进行认证
4: 减少客户端与微服务之间的交互次数

Request的生命周期

request生命周期.png

zuul过滤器类型

前置(pre), 路由(route), 后置(post), 错误(error)

zuul的使用

Zuul的基本使用使用非常简单, 只需要2步骤:
1: 引入依赖

<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>

2: 使Zuul可用
@EnableZuulProxy

然后就可以直接使用, 例如调用PRODUCER项目的getProduct的controller则可以直接调用
http://localhost:9000/producer/getProduct

查看所有的routes

http://localhost:9000/actuator/routes
http://localhost:9000/actuator/routes/details

配置解析

1: producer项目通常我们可以通过如下方式访问
http://localhost:9000/producer/getProduct
但是我们如果想修改为自己的命名, 则可以设置zuul.routes.myProducer

zuul:
  routes:
    myProducer:  ##这个名字随便取          
      path: /myProducer/**  ##这个myProducer是目前暴露出去的
      serviceId: producer   ##这个是想调用的application name
      sensitiveHeaders:
  prefix: /test
  strip-prefix: false
  ignored-patterns:  ##使下面2个url的访问不可用
    - /producer/getProduct
    - /myProducer/getProduct

zuul的过滤器

1. 请求参数拦截 (一定要有token)

ZuulFilter.java

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE; //filter类型
    }
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    //逻辑部分
    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //从{url:cookie:header}参数获取
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

2. Response拦截 (在返回中的header中加参数)

AddResponseHeaderFilter.java

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;

@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() {
        RequestContext requestContext = RequestContext.getCurrentContext();

        HttpServletResponse response = requestContext.getResponse();
        response.setHeader("my-header", UUID.randomUUID().toString());
        return null;
    }
}

3. zuul限流(利用google的令牌桶)

RateLimiterFilter.java

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

@Component
public class RateLimiterFilter 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 RateLimiterException();
        }
        return null;
    }
}

4. zuul的跨域

1: 单个方法跨域, 确定是方法太多, 每个都需要注释
@CrossOrigin(allowCredentials="true") //允许cookie跨域

2: 整个跨域
CorsConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter(){
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();

        //是否支持cookie跨域
        config.setAllowCredentials(true);

        //允许的原始域 例如: http://www.a.com
        config.setAllowedOrigins(Arrays.asList("*"));

        //允许的头
        config.setAllowedHeaders(Arrays.asList("*"));

        //允许的方法, *表示允许所有的
        config.setAllowedMethods(Arrays.asList("*"));

        config.setMaxAge(300l);

        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }
}

相关文章

网友评论

      本文标题:SpringCloud 2.0 之 zuul

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