美文网首页
Spring Cloud Zuul -- 服务网关

Spring Cloud Zuul -- 服务网关

作者: saoraozhe3hao | 来源:发表于2018-12-07 16:28 被阅读0次

    服务网关: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,部署多台即可

    相关文章

      网友评论

          本文标题:Spring Cloud Zuul -- 服务网关

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