1. 程式人生 > >雙劍合璧 Nacos 結合 Sentinel 實現流量安全控制

雙劍合璧 Nacos 結合 Sentinel 實現流量安全控制

Alibaba Sentinel 是一款高效能且輕量級的流量控制、熔斷降級解決方案。是面向分散式服務架構的高可用流量控制組件。

Sentinel 官網:https://sentinelguard.io/zh-cn/

Github:https://github.com/alibaba/Sentinel

Sentinel 是什麼

隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 主要以流量為切入點,從流量控制、熔斷降級、系統自適應保護等多個維度來保障微服務的穩定性。

Sentinel 具有以下特徵:

  • 「豐富的應用場景」:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、訊息削峰填谷、叢集流量控制、實時熔斷下游不可用應用等。
  • 「完備的實時監控」:Sentinel 同時提供實時的監控功能。您可以在控制檯中看到接入應用的單臺機器秒級資料,甚至 500 臺以下規模的叢集的彙總執行情況。
  • 「廣泛的開源生態」:Sentinel 提供開箱即用的與其它開源框架/庫的整合模組,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。
  • 「完善的 SPI 擴充套件點」:Sentinel 提供簡單易用、完善的 SPI 擴充套件介面。您可以通過實現擴充套件介面來快速地定製邏輯。例如定製規則管理、適配動態資料來源等。

「Sentinel 主要特徵」

「Sentinel 開源生態」

Sentinel 目前已經針對 Servlet、Dubbo、Spring Boot/Spring Cloud、gRPC 等進行了適配,使用者只需引入相應依賴並進行簡單配置即可非常方便地享受 Sentinel 的高可用流量防護能力。Sentinel 還為 Service Mesh 提供了叢集流量防護的能力。未來 Sentinel 還會對更多常用框架進行適配。

Sentinel 分為兩個部分:

  • 核心庫(Java 客戶端)不依賴任何框架/庫,能夠運行於所有 Java 執行時環境,同時對 Dubbo / Spring Cloud 等框架也有較好的支援。
  • 控制檯(Dashboard)基於 Spring Boot 開發,打包後可以直接執行,不需要額外的 Tomcat 等應用容器。

Sentinel 的歷史

  • 2012 年,Sentinel 誕生,主要功能為入口流量控制。
  • 2013-2017 年,Sentinel 在阿里巴巴集團內部迅速發展,成為基礎技術模組,覆蓋了所有的核心場景。Sentinel 也因此積累了大量的流量歸整場景以及生產實踐。
  • 2018 年,Sentinel 開源,並持續演進。
  • 2019 年,Sentinel 朝著多語言擴充套件的方向不斷探索,推出 C++ 原生版本,同時針對 Service Mesh 場景也推出了 Envoy 叢集流量控制支援,以解決 Service Mesh 架構下多語言限流的問題。
  • 2020 年,推出 Sentinel Go 版本,繼續朝著雲原生方向演進。

Sentinel 核心

Sentinel 的使用可以分為兩個部分:

  • 核心庫(Java 客戶端):不依賴任何框架/庫,能夠運行於 Java 7 及以上的版本的執行時環境,同時對 Dubbo / Spring Cloud 等框架也有較好的支援(見 主流框架適配)。
  • 控制檯(Dashboard):控制檯主要負責管理推送規則、監控、叢集限流分配管理、機器發現等。

Sentinel 控制檯

Sentinel 提供一個輕量級的開源控制檯,它提供機器發現以及健康情況管理、監控(單機和叢集),規則管理和推送的功能。

官網文件:https://github.com/alibaba/Sentinel/wiki/控制檯

獲取控制檯

您可以從 release 頁面 下載最新版本的控制檯 jar 包。

您也可以從最新版本的原始碼自行構建 Sentinel 控制檯:

  • 下載 控制檯 工程
  • 使用以下命令將程式碼打包成一個 fat jar: mvn clean package

啟動控制檯

啟動命令如下,本文使用的是目前最新 1.7.2 版本:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar

「注意」:啟動 Sentinel 控制檯需要 JDK 版本為 1.8 及以上版本。

其中 -Dserver.port=8080 用於指定 Sentinel 控制檯埠為 8080

從 Sentinel 1.6.0 起,Sentinel 控制檯引入基本的「登入」功能,預設使用者名稱和密碼都是 sentinel。可以參考 鑑權模組文件 配置使用者名稱和密碼。

注:若您的應用為 Spring Boot 或 Spring Cloud 應用,您可以通過 Spring 配置檔案來指定配置,詳情請參考 Spring Cloud Alibaba Sentinel 文件。

為了方便啟動,可以編寫一個啟動指令碼 run.bat

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar
pause

訪問

訪問:http://localhost:8080/

輸入預設使用者名稱和密碼 sentinel 點選登入。至此控制檯就安裝完成了。

環境準備

sentinel-demo 聚合工程。SpringBoot 2.3.0.RELEASESpring Cloud Hoxton.SR4

  • Nacos 註冊中心
  • product-service:商品服務,提供了 /product/{id} 介面
  • order-service-rest:訂單服務,基於 Ribbon 通過 RestTemplate 呼叫商品服務
  • order-server-feign:訂單服務,基於 Feign 通過宣告式服務呼叫商品服務

客戶端接入控制檯

控制檯啟動後,客戶端需要按照以下步驟接入到控制檯:

  • 新增依賴
  • 定義資源
  • 定義規則

先把可能需要保護的資源定義好,之後再配置規則。也可以理解為,只要有了資源,我們就可以在任何時候靈活地定義各種流量控制規則。在編碼的時候,只需要考慮這個程式碼是否需要保護,如果需要保護,就將之定義為一個資源。

由於我們的專案是 Spring Cloud 專案,所以可以藉助官方文件來進行學習。

Spring 官網文件:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html

Github 文件:https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel

新增依賴

父工程需要新增如下依賴:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子工程需要新增如下依賴:

<!-- spring cloud alibaba sentinel 依賴 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置檔案

客戶端需要啟動 Transport 模組來與 Sentinel 控制檯進行通訊。

order-service-rest 的 application.yml

spring:
  cloud:
    # 配置 Sentinel
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

這裡的 spring.cloud.sentinel.transport.port 埠配置會在應用對應的機器上啟動一個 Http Server,該 Server 會與 Sentinel 控制檯做互動。比如 Sentinel 控制檯添加了一個限流規則,會把規則資料 push 給這個 Http Server 接收,Http Server 再將規則註冊到 Sentinel 中。

初始化客戶端

「確保客戶端有訪問量」,Sentinel 會在「客戶端首次呼叫的時候」進行初始化,開始向控制檯傳送心跳包。

簡單的理解就是:訪問一次客戶端,Sentinel 即可完成客戶端初始化操作,並持續向控制檯傳送心跳包。

訪問

多次訪問:http://localhost:9090/order/1 然後檢視控制檯實時監控結果如下:

定義資源

「資源」 是 Sentinel 中的核心概念之一。我們說的資源,可以是任何東西,服務,服務裡的方法,甚至是一段程式碼。最常用的資源是我們程式碼中的 Java 方法。Sentinel 提供了 @SentinelResource 註解用於定義資源,並提供了 AspectJ 的擴充套件用於自動定義資源、處理 BlockException 等。

只要通過 Sentinel API 定義的程式碼,就是資源,能夠被 Sentinel 保護起來。大部分情況下,可以使用方法簽名,URL,甚至服務名稱作為資源名來標示資源。

官網文件:https://github.com/alibaba/Sentinel/wiki/如何使用#定義資源

註解支援

官網文件:https://github.com/alibaba/Sentinel/wiki/註解支援

OrderServiceImpl.java

package com.example.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.pojo.Order;
import com.example.service.OrderService;
import com.example.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ProductService productService;

    /**
     * 根據主鍵和訂單編號查詢訂單
     *
     * @param id
     * @param orderNo
     * @return
     */
    @Override
    @SentinelResource(value = "selectOrderByIdAndOrderNo",
            blockHandler = "selectOrderByIdAndOrderNoBlockHandler",
            fallback = "selectOrderByIdAndOrderNoFallback")
    public Order selectOrderByIdAndOrderNo(Integer id, String orderNo) {
        return new Order(id, orderNo, "中國", 2666D,
                Arrays.asList(productService.selectProductById(1)));
    }

    // 服務流量控制處理,引數最後多一個 BlockException,其餘與原函式一致。
    public Order selectOrderByIdAndOrderNoBlockHandler(Integer id, String orderNo,
                                                       BlockException ex) {
        // Do some log here.
        ex.printStackTrace();
        return new Order(id, "服務流量控制處理-託底資料", "中國", 2666D,
                Arrays.asList(productService.selectProductById(1)));
    }

    // 服務熔斷降級處理,函式簽名與原函式一致或加一個 Throwable 型別的引數
    public Order selectOrderByIdAndOrderNoFallback(Integer id, String orderNo,
                                                   Throwable throwable) {
        System.out.println("order-service 服務的 selectOrderById 方法出現異常,異常資訊如下:"
                + throwable);
        return new Order(id, "服務熔斷降級處理-託底資料", "中國", 2666D,
                Arrays.asList(productService.selectProductById(1)));
    }

}

ProductServiceImpl.java

package com.example.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.pojo.Product;
import com.example.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * 商品管理
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 根據主鍵查詢商品
     *
     * @param id
     * @return
     */
    @SentinelResource(value = "selectProductById",
            blockHandler = "selectProductByIdBlockHandler", fallback = "selectProductByIdFallback")
    @Override
    public Product selectProductById(Integer id) {
        return restTemplate.getForObject("http://product-service/product/" + id, Product.class);
    }

    // 服務流量控制處理,引數最後多一個 BlockException,其餘與原函式一致。
    public Product selectProductByIdBlockHandler(Integer id, BlockException ex) {
        // Do some log here.
        ex.printStackTrace();
        return new Product(id, "服務流量控制處理-託底資料", 1, 2666D);
    }

    // 服務熔斷降級處理,函式簽名與原函式一致或加一個 Throwable 型別的引數
    public Product selectProductByIdFallback(Integer id, Throwable throwable) {
        System.out.println("product-service 服務的 selectProductById 方法出現異常,異常資訊如下:"
                + throwable);
        return new Product(id, "服務熔斷降級處理-託底資料", 1, 2666D);
    }

}

注意:註解方式埋點不支援 private 方法。

@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。 @SentinelResource 註解包含以下屬性:

  • value:資源名稱,必需項(不能為空)
  • entryType:entry 型別,可選項(預設為 EntryType.OUT
  • blockHandler / blockHandlerClass: blockHandler對應處理 BlockException 的函式名稱,可選項。blockHandler 函式訪問範圍需要是 public,返回型別需要與原方法相匹配,引數型別需要和原方法相匹配並且最後加一個額外的引數,型別為 BlockException。blockHandler 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 blockHandlerClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
  • fallback:fallback 函式名稱,可選項,用於在丟擲異常的時候提供 fallback 處理邏輯。fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。fallback 函式簽名和位置要求:
    • 返回值型別必須與原函式返回值型別一致;
    • 方法引數列表需要和原函式一致,或者可以額外多一個 Throwable 型別的引數用於接收對應的異常。
    • fallback 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
  • defaultFallback(since 1.6.0):預設的 fallback 函式名稱,可選項,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。預設 fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函式簽名要求:
    • 返回值型別必須與原函式返回值型別一致;
    • 方法引數列表需要為空,或者可以額外多一個 Throwable 型別的引數用於接收對應的異常。
    • defaultFallback 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
  • exceptionsToIgnore(since 1.6.0):用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣丟擲。

注:1.6.0 之前的版本 fallback 函式只針對降級異常(DegradeException)進行處理,「不能針對業務異常進行處理」。

特別地,若 blockHandler 和 fallback 都進行了配置,則被限流降級而丟擲

相關推薦

合璧 Nacos 結合 Sentinel 實現流量安全控制

Alibaba Sentinel 是一款高效能且輕量級的流量控制、熔斷降級解決方案。是面向分散式服務架構的高可用流量控制組件。 Sentinel 官網:https://sentinelguard.io/zh-cn/ Github:https://github.com/alibaba/Sentinel S

中芯國際詳解梁孟松、趙海軍合璧

fin 知識產權 采訪 華為 面積 空間 財務 分享 節點 集微網上海報道 文/樂川10月16日晚間中芯國際召開臨時董事會議,正式宣布梁孟松出任中芯國際聯合CEO(Co-CEO),並自即(16)日起生效。業界猜測了一年多的關於梁孟松的任職問題終於確定,雙CEO的的結局出人意

Flume+Kafka合璧玩轉大資料平臺日誌採集

概述 大資料平臺每天會產生大量的日誌,處理這些日誌需要特定的日誌系統。 一般而言,這些系統需要具有以下特徵: 構建應用系統和分析系統的橋樑,並將它們之間的關聯解耦; 支援近實時的線上分析系統和類似於Hadoop之類的離線分析系統; 具有高可擴充套件性。即:當資料量增加時,可以通過增加節點

Sketch+Keynote合璧:5步快速製作移動動效

2014年,Facebook推出了新聞閱讀應用Paper,諸多互動細節與炫酷動效啟動了介面設計的新時代,Google的Material Design更是將移動動效提升到了app基礎體驗環節的高度。盤點如今體驗優秀的移動app,精彩的動效層出不窮,放眼望去,聚集UI設

【JQ】瀑布流與無限滾動條一起使用,合璧

一般都會把masonry和infinitescroll聯合使用 基本: <script type="text/javascript" src="jquery-1.6.4.min.js"></script> <script src="jquery

合璧————Spring Boot + Mybatis Plus

引言最近在學習Mybatis Plus的使用,希望通過spring boot快速將mybatis plus整合進來。對於springboot專案,mybatis plus團隊也有自己的啟動器 :mybatis-plus-boot-starter。這個依賴內部已經整合了myba

華山論劍之iOS&tableView的合璧

對待生活,你用什麼的態度對待它,它就會以什麼的態度回報你,那麼請善待你的生活. 示意圖 上面的這張圖 我相信大家都不會陌生,因為這就是一張外賣App的一張圖,左邊一欄是"壽司,小菜,其他,就睡,套餐"右邊怎麼具體的詳情實物列表,如果我們需要做出這樣的效果,設計的思路是

vue2.0結合Element實現select動態控制input禁用

嘻嘻 [0 attr 折騰 解決 model utf del logs 今天有一個盆友問小穎,怎麽實現用select動態控制input禁用,也就是說,input默認是可編輯的,但是每當我選一次select,input就會變成禁用,雖然小穎不知道她為什麽這樣做,因為小

Spring Cloud Alibaba生態探索:Dubbo、NacosSentinel的完美結合

@[toc] ## 背景 - 在上篇文章[《Spring Cloud Alibaba微服務生態的基礎實踐》](https://www.cnblogs.com/zhuhuix/p/13679153.html)中,我們初步瞭解了`Spring Cloud Alibaba`微服務生態體系,並動手實踐了`Nacos`

php結合redis實現高並發下的搶購、秒殺功能

緩存 使用 fclose rtl global 簡單模擬 解決 fun 非阻塞 搶購、秒殺是如今很常見的一個應用場景,主要需要解決的問題有兩個: 1 高並發對數據庫產生的壓力 2 競爭狀態下如何解決庫存的正確減少("超賣"問題) 對於第一個問題,已經很容易想到用緩存來處理搶

利用Sentinel實現Redis主從切換

edi nbsp ilo bind redis poc 自主 日誌 sent 利用Sentinel(哨兵)實現Redis集群的故障自主切換 首先部署redis主從集群,這裏忽略過程,主要看配置文件: master: bind 0.0.0.0 port 6801 log

springmvc結合ehcache實現共享對象緩存

bsp 技術 name size b2c 接下來 pom etc log   筆者最近在學習Web性能優化的知識,想用springmvc結合ehcache來實現共享對象緩存,可是網上的很多教程講得不是很清楚,加上本人對spring的知識還沒有完全熟悉,所以在實現過程中碰到了

Linux平臺網卡綁定技術實現負載均衡(網卡聚合)bonding

網卡綁定Linux平臺雙網卡綁定技術實現負載均衡保持服務器的高可用性是企業級 IT 環境的重要因素。其中最重要的一點是服務器網絡連接的高可用性。網卡(NIC)綁定技術有助於保證高可用性特性並提供其它優勢以提高網絡性能。 雙網卡綁定實現就是使用兩塊網卡虛擬成為一塊網卡,這個聚合起來的設備看起來是一個單獨的以太網

cookie結合js 實現記住的拖拽

div 位置 highlight cti top mov type logs 加載 哈嘍!!!我胡漢三又回來啦!!!有木有記掛挪啊!咱們今天說一個 cookie結合JS的小案例哦! 話不多說直接上代碼: <!DOCTYPE html> <html>

gridview和detailsview的完美結合運用實現增刪改

formview efault fault default obj details grid add asp 原文發布時間為:2008-07-24 —— 來源於本人的百度文章 [由搬家工具導入]1、因Gridview中没

初涉RxAndroid結合Glide實現多圖片載入操作

roc mco avr spl asc 生命周期 png ret track 轉載請註明出處:王亟亟的大牛之路 本來周末就想發了然後各種拖拉就沒有然後了,那麽就今天早上寫吧,廢話不多開始正題 什麽是RxJava或者RxAndroid我就不多廢話了,理

nodejs結合apiblue實現MockServer

ret 業務 接口 www. 無法更新 locals 代碼 resolv 文件夾 apiblue功能很強大,裏面支持很多插件,這些插件能夠為restfulAPI提供接口文檔自動生成,甚至Mockserver的功能,當然,好多插件還是有很多坑的。下面用apiblue實現下面的

背水一戰 Windows 10 (24) - MVVM: 通過 Binding 或 x:Bind 結合 Command 實現,通過非 ButtonBase 觸發命令

block files grid collect gin 綁定 專註 ins ext 原文:背水一戰 Windows 10 (24) - MVVM: 通過 Binding 或 x:Bind 結合 Command 實現,通過非 ButtonBase 觸發命令[源碼下載] 背

javascript結合nodejs實現多文件上傳

ima 實現 依賴 看到了 包括 小夥伴 邊緣 multipart images 前端文件上傳功能比較依賴後端,所以第一步用nodejs實現一個供文件上傳的功能接口。 因為本人對nodejs也是一知半解,所以剛開始的想法是像原始的ajax交互那樣,獲取上傳文件的內容,然後

IKAnalyzer結合Lucene實現中文分詞

++ reset utf-8 incr ttr 中文分詞 擴展 沒有 font 1、基本介紹   隨著分詞在信息檢索領域應用的越來越廣泛,分詞這門技術對大家並不陌生。對於英文分詞處理相對簡單,經過拆分單詞、排斥停止詞、提取詞幹的過程基本就能實現英文分詞,單對於中文分詞而言,