Spring Cloud Zuul -- 服务网关

2018-12-07  本文已影响0人  saoraozhe3hao

服务网关:API Gateway,API网关
Spring Cloud Zuul:封装于Netflix Zuul
API网关的其他方案:Nginx + Lua、Kong、Tyk

功能:让外部请求经过统一的网关,在网关上过滤请求,加工响应
过滤请求:限流、权限校验、路由

Zuul 项目构建

1、借助IDEA,初始化项目
New Project -> Spring Initializr -> 选择依赖Cloud Routing.Zuul
2、给主类增加注解 @EnableZuulProxy
3、application.properties 更名为 application.yml

server.port: 8080
zuul:
  routes.myService:
    path: /myService/**
    serviceId: service_1  # 路径与服务的映射,前提是 Zuul也得是 Eureka Client
    sensitiveHeaders:     # 把敏感头设为空,即可让Zuul把所有请求头都转发给服务
  ignored-patterns:  # 让一些路径不允许通过Zuul访问(但不影响直接访问原服务)
  - /inner/**
  - /**/inner

4、运行主类 main方法,访问 localhost:8080/myService/path 或 localhost:8080/service_1/path,即可访问到service_1的接口

前置过滤器

请求数据流:前置过滤器 -> 路由过滤器 -> 服务 -> 错误过滤器(可选) -> 后置过滤器

@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;  // 前置过滤器
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;  // 过滤器顺序,让它在PRE_DECORATION_FILTER过滤器之前
    }

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

    @Override
    public Object run() throws ZuulException {
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest hsr = rc.getRequest();
        if(false){
            rc.setSendZuulResponse(false);    // 校验不通过,直接返回
            rc.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

后置过滤器

@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; // 过滤器顺序,让它在SEND_RESPONSE_FILTER过滤器之前
    }

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

    @Override
    public Object run() throws ZuulException {
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletResponse hsr = rc.getResponse();
        hsr.setHeader("X-Hogen", "dd");
        return null;
    }
}

限流

令牌桶限流:每秒往令牌桶里放固定数目的令牌,应用从桶里取到令牌才处理请求,否则丢弃请求

@Component
public class TokenFilter extends ZuulFilter {
    // RateLimiter 来源于 Google Guava组件
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(100);   // 每秒往桶里放100个令牌

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SERVLET_DETECTION_FILTER_ORDER - 1;  // 设置成比最高优先级还高
    }

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

    @Override
    public Object run() throws ZuulException {
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest hsr = rc.getRequest();
        if(!RATE_LIMITER.tryAcquire()){  // 尝试取令牌
            rc.setSendZuulResponse(false); 
        }
        return null;
    }
}

Zuul 高可用

Zuul 同时得是 Eureka Client,部署多台即可

上一篇 下一篇

猜你喜欢

热点阅读