• SpringCloud之网关zuul


    1、微服务网关介绍和使用场景

     1)什么是网关
      API Gateway,是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求、鉴权、监控、缓存、限流等功能

      统一接入
        智能路由
        AB测试、灰度测试
        负载均衡、容灾处理
        日志埋点(类似Nignx日志)

      流量监控
        限流处理
        服务降级

      安全防护
        鉴权处理
        监控
        机器网络隔离


     2)主流的网关
      zuul:是Netflix开源的微服务网关,和Eureka,Ribbon,Hystrix等组件配合使用,Zuul 2.0比1.0的性能提高很多
      kong: 由Mashape公司开源的,基于Nginx的API gateway
      nginx+lua:是一个高性能的HTTP和反向代理服务器,lua是脚本语言,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求

    2、SpringCloud的网关组件zuul基本使用

      1、加入依赖

    <dependencies>
            <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>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>

      2、启动类加入注解 @EnableZuulProxy
        默认集成断路器 @EnableCircuitBreaker   

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    @SpringBootApplication
    @EnableZuulProxy
    public class ApiGatewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ApiGatewayApplication.class, args);
        }
    }

        默认访问规则
        http://gateway:port/service-id/**

        例子:默认 /order-service/api/v1/order/save?user_id=2&product_id=1
                  自定义 /xdclass_order/api/v1/order/save?user_id=2&product_id=1

                 自定义路由转发:
               zuul:
              routes:
            order-service: /apigateway/**

        环境隔离配置:
                 需求 :不想让默认的服务对外暴露接口
              /order-service/api/v1/order/save

          配置:
          zuul:
            ignored-patterns:  /*-service/api/v1/order/save

        yml 配置:

    server:
      port: 9000
    
    #服务的名称
    spring:
      application:
        name: api-gateway
    
    #指定注册中心地址
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    
    #/order-service/api/v1/order/save?user_id=2&product_id=1
    #自定义路由映射(注意有路由覆盖的地方,所以一般会加个模块/apigateway/order, order模块)
    zuul:
      routes:
        order-service: /apigateway/order/**
        product-service: /apigateway/product/**
      #统一入口为上面的配置,其他入口忽略(即不能通过 /order-service/api/v1/order/save 来访问)
      ignored-patterns: /*-service/**
      #处理http请求头为空的问题(默认的过滤集合包含 "cookie" ,所以后端拿不到 “cookie”, 将集合过滤设为空)
      sensitive-headers:
     

    3、Zuul常用问题分析和网关过滤器原理分析

      Zuul网关原理和过滤器生命周期,

        1、路由名称定义问题
          路由映射重复覆盖问题

        2、Http请求头过滤问题(如cookie)

        3、过滤器执行顺序问题 ,过滤器的order值越小,越先执行

        4、共享RequestContext,上下文对象

    4、自定义Zuul过滤器实现登录鉴权

      简介:自定义Zuul过滤器实现登录鉴权

      1、新建一个filter包

      2、新建一个类,实现ZuulFilter,重写里面的方法

      3、在类顶部加注解,@Component,让Spring扫描

      

    package net.xdclass.apigateway.filter;
    
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    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_TYPE;
    
    /**
     * 登录过滤器
     */
    @Component
    public class LoginFilter extends ZuulFilter {
    
        /**
         * 过滤器类型,前置过滤器
         *
         * @return
         */
        @Override
        public String filterType() {
            return PRE_TYPE;
        }
    
        /**
         * 过滤器顺序,越小越先执行
         *
         * @return
         */
        @Override
        public int filterOrder() {
    
            return 4;
        }
    
    
        /**
         * 过滤器是否生效
         *
         * @return
         */
        @Override
        public boolean shouldFilter() {
    
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
    
            //System.out.println(request.getRequestURI()); ///apigateway/product/api/v1/product/list
            //System.out.println(request.getRequestURL()); //http://localhost:9000/apigateway/product/api/v1/product/list
    
            //ACL
    
            if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
                return true;
            } else if ("/apigateway/order/api/v1/order/list".equalsIgnoreCase(request.getRequestURI())) {
                return false;
            } else if ("/apigateway/order/api/v1/order/find".equalsIgnoreCase(request.getRequestURI())) {
                return true;
            }
            return false;
        }
    
        /**
         * 业务逻辑
         *
         * @return
         * @throws ZuulException
         */
        @Override
        public Object run() throws ZuulException {
    
            //JWT
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
    
            //token对象
            String token = request.getHeader("token");
    
            if (StringUtils.isBlank((token))) {
                token = request.getParameter("token");
            }
            //登录校验逻辑  根据公司情况自定义 JWT
            if (StringUtils.isBlank(token)) {
                requestContext.setSendZuulResponse(false);
                requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            }
            return null;
        }
    }

        访问“/apigateway/order/api/v1/order/save”时需要鉴权  

     5、高并发情况下接口限流特技

      简介:谷歌guava框架介绍,网关限流使用

      对订单接口限流:

      

    package net.xdclass.apigateway.filter;
    
    import com.google.common.util.concurrent.RateLimiter;
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    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_TYPE;
    
    /**
     * 订单限流
     */
    @Component
    public class OrderRateLimiterFilter extends ZuulFilter {
    
    
        //每秒产生1000个令牌
        private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);
    
        @Override
        public String filterType() {
            return PRE_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return -4;
        }
    
    
    
        @Override
        public boolean shouldFilter() {
    
    
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
    
            //只对订单接口限流
            if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())){
                return true;
            }
    
            return false;
        }
    
        @Override
        public Object run() throws ZuulException {
            RequestContext requestContext = RequestContext.getCurrentContext();
            if(!RATE_LIMITER.tryAcquire()){
                requestContext.setSendZuulResponse(false);
                requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
            }
            return null;
        }
    }

    每秒1000个请求,超出则丢弃

    6、Zuul微服务网关集群搭建
      简介:微服务网关Zull集群搭建

      1、nginx+lvs+keepalive 避免Nginx挂掉
      https://www.cnblogs.com/liuyisai/p/5990645.html

      启动另一个api-gateway,将1000读取从配置中心读取,2台api则为500

      private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);
  • 相关阅读:
    分类模型之支持向量机
    数据预处理
    数据挖掘基本流程
    【项目】项目95
    【项目】项目94
    【项目】项目93
    【项目】项目92
    【项目】项目91
    【项目】项目90
    【项目】项目89
  • 原文地址:https://www.cnblogs.com/daxiong225/p/13172714.html
Copyright © 2020-2023  润新知