SpringCloud笔记五:微服务网关zuul

SpringCloud笔记五:微服务网关zuul

什么是网关

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

统一接入

​ 智能路由,

​ AB测试,灰度测试

​ 负载均衡,容灾处理

​ 日志埋点。

流量监控

​ 限流处理

​ 服务降级

安全防护

​ 鉴权处理

​ 监控

​ 机器网络隔离

  1. 网关的架构位置

zuul网关架构位置

  1. 主流网关

1、zuul:是Netflix开源的微服务项目,和Eureka,Ribbon,Hystrix等组件配合使用,zuul2.0比1.0的性能提高了很多。

2、Kong:由Mashape公司开源,基于Nginx的ApI gateway

3、Nginx+Lua:是一个高性能的Http和反向代理服务器,lua是脚本语言,让Nginx执行Lua脚本,并且高并发,非阻塞的处理各种请求。

SpringCloud的网关组件zuul基本使用

  1. 加入依赖,可以在创建应用的时候选择zuul和hystrix,引入依赖,比较慢,可以指定镜像
<repositories>
    <repository>
        <id>nexus-aliyun</id>
        <name>Nexus aliyun</name>
        <layout>default</layout>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
</repositories>
  1. 进行eureka服务注册
server:
  port: 9000

#服务名称
spring:
  application:
    name: api-gateway

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  1. zuul网关路由映射配置
#自定义路由映射
zuul:
  routes:
    order-service: /apigatewaytwo/**
    product-service: /apigateway/**
 ignored-patterns: /*-service/**
 #忽略整个服务,对外提供接口
 #ignored-services: product-service
  1. zuul配置作用图

zuul配置中心

Zuul常见问题分析和网关过滤器原理分析

  1. 路由名称定义问题

路由映射重复覆盖问题。后面的会覆盖前面的。

#自定义路由映射
zuul:
  routes:
    #下面两个必须唯一
    order-service: /apigateway/order/**
    product-service: /apigateway/product/**
    ignored-patterns: /*-service/**
    #忽略整个服务,对外提供接口
    #ignored-services: product-service
  1. http请求头过滤问题

zuul网关有个问题,默认会屏蔽调请求的cookie内容,这样后端就会接收不到cookie信息,需要在配置中处理一下。sensitive-headers:

#自定义路由映射
zuul:
  routes:
    #下面两个必须唯一
    order-service: /apigateway/order/**
    product-service: /apigateway/product/**
  ignored-patterns: /*-service/**
    #处理http请求头为空
  sensitive-headers:
    #忽略整个服务,对外提供接口
    #ignored-services: product-service
  1. 过滤器执行顺序问题,过滤器的order值越小,越先执行。

在ZuulFilter类里面

zuulFilter类

  1. 共享requestContext,上下文对象。

自定义Zuul过滤器实现登录鉴权功能

  1. 在网关项目中新建一个包filter,然后新建一个类并集成ZuulFilter
  2. 重写ZuulFilter里面的方法。
  3. 添加@Component,让spring扫描
  4. 过滤器代码
/**
 * @program: api-gateway
 * @description: 登录过滤器
 * @author: kaifan·Zhang
 * @create: 2020-03-19 16:
 */
@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());
        System.out.println(request.getRequestURL());
        /*
        *       /apigateway/order/api/v1/order/save
                 http://localhost:9000/apigateway/order/api/v1/order/save
         **/
        //ACL,将访问接口列表存储在redis里面,定期进行拉取
        if("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())){
            return true;
        }
        return false;
    }

    /**
     * 业务逻辑,这段代码就是如果拦截,就会执行,如果不拦截,就不会执行。
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        //jwt操作
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String token = request.getHeader("token");
        if(StringUtils.isBlank(token)){
            token=request.getParameter("token");
        }
        if(StringUtils.isEmpty(token)){
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());//401未授权
        }

        return null;
    }
}

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

  1. 采用谷歌guava框架,网关限流

原理:当用户请求时,服务端设置一个令牌,只有拿到令牌的请求,才允许访问,否则就抛弃掉。也就是这个网关设置最多访问量为1000,当超过1000的并发量时,就限制访问。

使用RateLimiter设置令牌。这个令牌是每秒产生的。限制每秒最多1000的访问量。

  1. 限流种类

1、nginx限流

2、网关限流

  1. 网关限流代码
@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();
        HttpServletRequest request = requestContext.getRequest();
        if(!RATE_LIMITER.tryAcquire()){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());//429请求过多
        }
        return null;
    }
}

Zuul微服务网关集群搭建

  1. 网关架构模型
    限流
    网关模型

  2. nginx+lvs+keepalive

资料

  1. 开启多个网关服务

换个服务端口,

或者在Idea的启动vm中

-Dserver.port=xxxx(端口)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章