天天看點

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

本篇文章為系列文章,未讀前幾集的同學請猛戳這裡:

哈喽沃德先生:Spring Cloud 系列之 Netflix Zuul 服務網關(一)​zhuanlan.zhihu.com

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

哈喽沃德先生:Spring Cloud 系列之 Netflix Zuul 服務網關(二)​zhuanlan.zhihu.com

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

哈喽沃德先生:Spring Cloud 系列之 Netflix Zuul 服務網關(三)​zhuanlan.zhihu.com

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

本篇文章講解 Zuul 和 Sentinel 整合,實作網關限流和容錯以及高可用網關環境搭建。

Zuul 和 Sentinel 整合

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

https://www.zhihu.com/video/1234209285452181504

Sentinel 支援對 Spring Cloud Gateway、Netflix Zuul 等主流的 API Gateway 進行限流。

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

官網文檔:

  • https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
  • https://github.com/alibaba/Sentinel/wiki/網關限流#zuul-1x

網關限流

建立項目

建立

zuul-server-sentinel

項目。

添加依賴

單獨使用添加

sentinel-zuul-adapter

依賴即可。

若想跟 Sentinel Starter 配合使用,需要加上

spring-cloud-alibaba-sentinel-gateway

依賴,同時需要添加

spring-cloud-starter-netflix-zuul

依賴來讓

spring-cloud-alibaba-sentinel-gateway

子產品裡的 Zuul 自動化配置類生效。

同時請将

spring.cloud.sentinel.filter.enabled

配置項置為 false(若在網關流控控制台上看到了 URL 資源,就是此配置項沒有置為 false)。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>zuul-server-sentinel</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 繼承父依賴 -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>zuul-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- 項目依賴 -->
    <dependencies>
        <!-- spring cloud netflix zuul 依賴 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <!-- netflix eureka client 依賴 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- 單獨使用 -->
        <!-- sentinel zuul adapter 依賴 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-zuul-adapter</artifactId>
        </dependency>
        <!-- 和 Sentinel Starter 配合使用 -->
        <!--
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>
        -->
    </dependencies>

</project>
           

配置檔案

server:
  port: 9001 # 端口

spring:
  application:
    name: zuul-server-sentinel # 應用名稱
  cloud:
    sentinel:
      filter:
        enabled: false

# 配置 Eureka Server 注冊中心
eureka:
  instance:
    prefer-ip-address: true       # 是否使用 ip 位址注冊
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # 設定服務注冊中心位址
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
           

網關服務配置類

配置網關服務過濾器和網關限流規則。

package com.example.config;

import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackManager;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulErrorFilter;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter;
import com.netflix.zuul.ZuulFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.Set;

/**
 * 網關服務配置類
 */
@Configuration
public class ZuulConfig {

    // 底層繼承了 ZuulFilter
    @Bean
    public ZuulFilter sentinelZuulPreFilter() {
        // We can also provider the filter order in the constructor.
        return new SentinelZuulPreFilter();
    }

    // 底層繼承了 ZuulFilter
    @Bean
    public ZuulFilter sentinelZuulPostFilter() {
        return new SentinelZuulPostFilter();
    }

    // 底層繼承了 ZuulFilter
    @Bean
    public ZuulFilter sentinelZuulErrorFilter() {
        return new SentinelZuulErrorFilter();
    }

    /**
     * Spring 容器初始化的時候執行該方法
     */
    @PostConstruct
    public void doInit() {
        // 加載網關限流規則
        initGatewayRules();
    }

    /**
     * 網關限流規則
     */
    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        /*
            resource:資源名稱,可以是網關中的 route 名稱或者使用者自定義的 API 分組名稱
            count:限流門檻值
            intervalSec:統計時間視窗,機關是秒,預設是 1 秒
         */
        rules.add(new GatewayFlowRule("order-service")
                .setCount(3) // 限流門檻值
                .setIntervalSec(60)); // 統計時間視窗,機關是秒,預設是 1 秒
        // 加載網關限流規則
        GatewayRuleManager.loadRules(rules);
    }

}
           

啟動類

ZuulServerSentinelApplication.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
// 開啟 Zuul 注解
@EnableZuulProxy
// 開啟 EurekaClient 注解,目前版本如果配置了 Eureka 注冊中心,預設會開啟該注解
//@EnableEurekaClient
public class ZuulServerSentinelApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulServerSentinelApplication.class, args);
    }

}
           

通路

多次通路:http://localhost:9001/order-service/order/1 觸發限流後會傳回固定的提示:

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

自定義限流處理

發生限流之後的處理流程 :

  • 發生限流之後可自定義傳回參數,通過實作

    ZuulBlockFallbackProvider

    接口,預設的實作是

    DefaultBlockFallbackProvider

  • 預設的 fallback route 的規則是 route ID 或自定義的 API 分組名稱。

編寫限流處理類

OrderBlockFallbackProvider.java

package com.example.fallback;

import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.BlockResponse;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackProvider;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 對訂單服務做服務容錯處理
 */
public class OrderBlockFallbackProvider implements ZuulBlockFallbackProvider {

    private Logger logger = LoggerFactory.getLogger(OrderBlockFallbackProvider.class);

    @Override
    public String getRoute() {
        return "order-service"; // 服務名稱
    }

    @Override
    public BlockResponse fallbackResponse(String route, Throwable cause) {
        logger.error("{} 服務觸發限流", route);
        if (cause instanceof BlockException) {
            return new BlockResponse(429, "服務通路壓力過大,請稍後再試。", route);
        } else {
            return new BlockResponse(500, "系統錯誤,請聯系管理者。", route);
        }
    }

}
           

将限流處理類注冊至 Zuul 容器

ZuulConfig.java

// Spring 容器初始化的時候執行該方法
@PostConstruct
public void doInit() {
    // 注冊 FallbackProvider
    ZuulBlockFallbackManager.registerProvider(new OrderBlockFallbackProvider());
    // 加載網關限流規則
    initGatewayRules();
}
           

多次通路:http://localhost:9001/order-service/order/1 觸發限流後傳回自定義提示:

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

高可用網關

業内通常用多少 9 來衡量網站的可用性,例如 QQ 的可用性是 4 個 9,就是說 QQ 能夠保證在一年裡,服務在 99.99% 的時間是可用的,隻有 0.01% 的時間不可用,大約最多 53 分鐘。

對于大多數網站,2 個 9 是基本可用;3 個 9 是叫高可用;4 個 9 是擁有自動恢複能力的高可用。

實作高可用的主要手段是

資料的備援備份

服務的失效轉移

,這兩種手段具體可以怎麼做呢,在網關裡如何展現?主要有以下幾個方向:

  • 叢集部署
  • 負載均衡
  • 健康檢查
  • 節點自動重新開機
  • 熔斷
  • 服務降級
  • 接口重試

Nginx + 網關叢集實作高可用網關

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

下載下傳

官網:http://nginx.org/en/download.html 下載下傳穩定版。為了友善學習,請下載下傳 Windows 版本。

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

安裝

解壓檔案後直接運作根路徑下的

nginx.exe

檔案即可。

Nginx 預設端口為 80,通路:http://localhost:80/ 看到下圖說明安裝成功。

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

配置網關叢集

進入 Nginx 的

conf

目錄,打開

nginx.conf

檔案,配置網關叢集:

http {

    ...

    # 網關叢集
    upstream gateway {
        server 127.0.0.1:9000;
        server 127.0.0.1:9001;
    }

    server {
        listen       80;
        server_name  localhost;

        ...

        # 代理網關叢集,負載均衡調用
        location / {
            proxy_pass http://gateway;
        }

        ...
    }

    ...

}
           

通路

啟動兩台網關伺服器

http://localhost:9000/

http://localhost:9001/

和相關服務。

通路:http://localhost/product-service/product/1 實作高可用網關。

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

總結

一個請求過來,首先經過 Nginx 的一層負載,到達網關,然後由網關負載到真實後端,若後端有問題,網關會進行重試通路,多次通路後仍傳回失敗,可以通過熔斷或服務降級立即傳回結果。而且,由于是負載均衡,網關重試時不一定會通路到出錯的後端。

至此 Zuul 服務網關所有的知識點就講解結束了。

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

大家可以通過

分類

檢視更多關于

Spring Cloud

的文章。

本文采用

知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協定

您的

點贊

轉發

是對我最大的支援。

掃碼關注

哈喽沃德先生

「文檔 + 視訊」每篇文章都配有專門視訊講解,學習更輕松噢 ~

spring cloud gateway 網關_Spring Cloud 系列之 Netflix Zuul 服務網關(四)

繼續閱讀