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(端口)

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