日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Sentinel(三)之如何使用

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Sentinel(三)之如何使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自??Sentinel如何使用

簡介

Sentinel 可以簡單的分為 Sentinel 核心庫和 Dashboard。核心庫不依賴 Dashboard,但是結合 Dashboard 可以取得最好的效果。

這篇文章主要介紹 Sentinel 核心庫的使用。如果希望有一個最快最直接的了解,可以參考?新手指南?來獲取一個最直觀的感受。

我們說的資源,可以是任何東西,服務,服務里的方法,甚至是一段代碼。使用 Sentinel 來進行資源保護,主要分為幾個步驟:

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

    對于主流的框架,我們提供適配,只需要按照適配中的說明配置,Sentinel 就會默認定義提供的服務,方法等為資源。

    ?

    定義資源

    方式一:主流框架的默認適配

    為了減少開發的復雜程度,我們對大部分的主流框架,例如 Web Servlet、Dubbo、Spring Cloud、gRPC、Spring WebFlux、Reactor 等都做了適配。您只需要引入對應的依賴即可方便地整合 Sentinel。可以參見:?主流框架的適配。

    方式二:拋出異常的方式定義資源

    SphU?包含了 try-catch 風格的 API。用這種方式,當資源發生了限流之后會拋出?BlockException。這個時候可以捕捉異常,進行限流之后的邏輯處理。示例代碼如下:

    // 1.5.0 版本開始可以利用 try-with-resources 特性(使用有限制) // 資源名可使用任意有業務語義的字符串,比如方法名、接口名或其它可唯一標識的字符串。 try (Entry entry = SphU.entry("resourceName")) {// 被保護的業務邏輯// do something here... } catch (BlockException ex) {// 資源訪問阻止,被限流或被降級// 在此處進行相應的處理操作 }

    特別地,若 entry 的時候傳入了熱點參數,那么 exit 的時候也一定要帶上對應的參數(exit(count, args)),否則可能會有統計錯誤。這個時候不能使用 try-with-resources 的方式。另外通過?Tracer.trace(ex)?來統計異常信息時,由于 try-with-resources 語法中 catch 調用順序的問題,會導致無法正確統計異常數,因此統計異常信息時也不能在 try-with-resources 的 catch 塊中調用?Tracer.trace(ex)。

    手動 exit 示例:

    Entry entry = null; // 務必保證 finally 會被執行 try {// 資源名可使用任意有業務語義的字符串,注意數目不能太多(超過 1K),超出幾千請作為參數傳入而不要直接作為資源名// EntryType 代表流量類型(inbound/outbound),其中系統規則只對 IN 類型的埋點生效entry = SphU.entry("自定義資源名");// 被保護的業務邏輯// do something... } catch (BlockException ex) {// 資源訪問阻止,被限流或被降級// 進行相應的處理操作 } catch (Exception ex) {// 若需要配置降級規則,需要通過這種方式記錄業務異常Tracer.traceEntry(ex, entry); } finally {// 務必保證 exit,務必保證每個 entry 與 exit 配對if (entry != null) {entry.exit();} }

    熱點參數埋點示例:

    Entry entry = null; try {// 若需要配置例外項,則傳入的參數只支持基本類型。// EntryType 代表流量類型,其中系統規則只對 IN 類型的埋點生效// count 大多數情況都填 1,代表統計為一次調用。entry = SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);// Your logic here. } catch (BlockException ex) {// Handle request rejection. } finally {// 注意:exit 的時候也一定要帶上對應的參數,否則可能會有統計錯誤。if (entry != null) {entry.exit(1, paramA, paramB);} }

    SphU.entry()?的參數描述:

    參數名類型解釋默認值
    entryTypeEntryType資源調用的流量類型,是入口流量(EntryType.IN)還是出口流量(EntryType.OUT),注意系統規則只對 IN 生效EntryType.OUT
    countint本次資源調用請求的 token 數目1
    argsObject[]傳入的參數,用于熱點參數限流

    注意:SphU.entry(xxx)?需要與?entry.exit()?方法成對出現,匹配調用,否則會導致調用鏈記錄異常,拋出?ErrorEntryFreeException?異常。常見的錯誤:

    • 自定義埋點只調用?SphU.entry(),沒有調用?entry.exit()
    • 順序錯誤,比如:entry1 -> entry2 -> exit1 -> exit2,應該為?entry1 -> entry2 -> exit2 -> exit1

    方式三:返回布爾值方式定義資源

    SphO?提供 if-else 風格的 API。用這種方式,當資源發生了限流之后會返回?false,這個時候可以根據返回值,進行限流之后的邏輯處理。示例代碼如下:

    // 資源名可使用任意有業務語義的字符串if (SphO.entry("自定義資源名")) {// 務必保證finally會被執行try {/*** 被保護的業務邏輯*/} finally {SphO.exit();}} else {// 資源訪問阻止,被限流或被降級// 進行相應的處理操作}

    注意:SphO.entry(xxx)?需要與 SphO.exit()方法成對出現,匹配調用,位置正確,否則會導致調用鏈記錄異常,拋出ErrorEntryFreeException` 異常。

    方式四:注解方式定義資源

    Sentinel 支持通過?@SentinelResource?注解定義資源并配置?blockHandler?和?fallback?函數來進行限流之后的處理。示例:

    // 原本的業務方法. @SentinelResource(blockHandler = "blockHandlerForGetUser") public User getUserById(String id) {throw new RuntimeException("getUserById command failed"); }// blockHandler 函數,原方法調用被限流/降級/系統保護的時候調用 public User blockHandlerForGetUser(String id, BlockException ex) {return new User("admin"); }

    注意?blockHandler?函數會在原方法被限流/降級/系統保護的時候調用,而?fallback?函數會針對所有類型的異常。請注意?blockHandler?和?fallback?函數的形式要求,更多指引可以參見?Sentinel 注解支持文檔。

    方式五:異步調用支持

    Sentinel 支持異步調用鏈路的統計。在異步調用中,需要通過?SphU.asyncEntry(xxx)?方法定義資源,并通常需要在異步的回調函數中調用?exit?方法。以下是一個簡單的示例:

    try {AsyncEntry entry = SphU.asyncEntry(resourceName);// 異步調用.doAsync(userId, result -> {try {// 在此處處理異步調用的結果.} finally {// 在回調結束后 exit.entry.exit();}}); } catch (BlockException ex) {// Request blocked.// Handle the exception (e.g. retry or fallback). }

    SphU.asyncEntry(xxx)?不會影響當前(調用線程)的 Context,因此以下兩個 entry 在調用鏈上是平級關系(處于同一層),而不是嵌套關系:

    // 調用鏈類似于: // -parent // ---asyncResource // ---syncResource asyncEntry = SphU.asyncEntry(asyncResource); entry = SphU.entry(normalResource);

    若在異步回調中需要嵌套其它的資源調用(無論是?entry?還是?asyncEntry),只需要借助 Sentinel 提供的上下文切換功能,在對應的地方通過?ContextUtil.runOnContext(context, f)?進行 Context 變換,將對應資源調用處的 Context 切換為生成的異步 Context,即可維持正確的調用鏈路關系。示例如下:

    public void handleResult(String result) {Entry entry = null;try {entry = SphU.entry("handleResultForAsync");// Handle your result here.} catch (BlockException ex) {// Blocked for the result handler.} finally {if (entry != null) {entry.exit();}} }public void someAsync() {try {AsyncEntry entry = SphU.asyncEntry(resourceName);// Asynchronous invocation.doAsync(userId, result -> {// 在異步回調中進行上下文變換,通過 AsyncEntry 的 getAsyncContext 方法獲取異步 ContextContextUtil.runOnContext(entry.getAsyncContext(), () -> {try {// 此處嵌套正常的資源調用.handleResult(result);} finally {entry.exit();}});});} catch (BlockException ex) {// Request blocked.// Handle the exception (e.g. retry or fallback).} }

    此時的調用鏈就類似于:

    -parent ---asyncInvocation -----handleResultForAsync

    更詳細的示例可以參考 Demo 中的?AsyncEntryDemo,里面包含了普通資源與異步資源之間的各種嵌套示例。

    規則的種類

    Sentinel 的所有規則都可以在內存態中動態地查詢及修改,修改之后立即生效。同時 Sentinel 也提供相關 API,供您來定制自己的規則策略。

    Sentinel 支持以下幾種規則:流量控制規則熔斷降級規則系統保護規則來源訪問控制規則?和?熱點參數規則

    流量控制規則 (FlowRule)

    流量規則的定義

    重要屬性:

    Field說明默認值
    resource資源名,資源名是限流規則的作用對象?
    count限流閾值?
    grade限流閾值類型,QPS 模式(1)或并發線程數模式(0)QPS 模式
    limitApp流控針對的調用來源default,代表不區分調用來源
    strategy調用關系限流策略:直接、鏈路、關聯根據資源本身(直接)
    controlBehavior流控效果(直接拒絕/WarmUp/勻速+排隊等待),不支持按調用關系限流直接拒絕
    clusterMode是否集群限流

    同一個資源可以同時有多個限流規則,檢查規則時會依次檢查。

    通過代碼定義流量控制規則

    理解上面規則的定義之后,我們可以通過調用?FlowRuleManager.loadRules()?方法來用硬編碼的方式定義流量控制規則,比如:

    private void initFlowQpsRule() {List<FlowRule> rules = new ArrayList<>();FlowRule rule = new FlowRule(resourceName);// set limit qps to 20rule.setCount(20);rule.setGrade(RuleConstant.FLOW_GRADE_QPS);rule.setLimitApp("default");rules.add(rule);FlowRuleManager.loadRules(rules); }

    更多詳細內容可以參考?流量控制。

    熔斷降級規則 (DegradeRule)

    熔斷降級規則包含下面幾個重要的屬性:

    Field說明默認值
    resource資源名,即規則的作用對象?
    grade熔斷策略,支持慢調用比例/異常比例/異常數策略慢調用比例
    count慢調用比例模式下為慢調用臨界 RT(超出該值計為慢調用);異常比例/異常數模式下為對應的閾值?
    timeWindow熔斷時長,單位為 s?
    minRequestAmount熔斷觸發的最小請求數,請求數小于該值時即使異常比率超出閾值也不會熔斷(1.7.0 引入)5
    statIntervalMs統計時長(單位為 ms),如 60*1000 代表分鐘級(1.8.0 引入)1000 ms
    slowRatioThreshold慢調用比例閾值,僅慢調用比例模式有效(1.8.0 引入)?

    同一個資源可以同時有多個降級規則。

    理解上面規則的定義之后,我們可以通過調用?DegradeRuleManager.loadRules()?方法來用硬編碼的方式定義流量控制規則。

    private void initDegradeRule() {List<DegradeRule> rules = new ArrayList<>();DegradeRule rule = new DegradeRule();rule.setResource(KEY);// set threshold RT, 10 msrule.setCount(10);rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);rule.setTimeWindow(10);rules.add(rule);DegradeRuleManager.loadRules(rules); }

    更多詳情可以參考?熔斷降級。

    系統保護規則 (SystemRule)

    Sentinel 系統自適應限流從整體維度對應用入口流量進行控制,結合應用的 Load、CPU 使用率、總體平均 RT、入口 QPS 和并發線程數等幾個維度的監控指標,通過自適應的流控策略,讓系統的入口流量和系統的負載達到一個平衡,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。

    系統規則包含下面幾個重要的屬性:

    Field說明默認值
    highestSystemLoadload1?觸發值,用于觸發自適應控制階段-1 (不生效)
    avgRt所有入口流量的平均響應時間-1 (不生效)
    maxThread入口流量的最大并發數-1 (不生效)
    qps所有入口資源的 QPS-1 (不生效)
    highestCpuUsage當前系統的 CPU 使用率(0.0-1.0)-1 (不生效)

    理解上面規則的定義之后,我們可以通過調用?SystemRuleManager.loadRules()?方法來用硬編碼的方式定義流量控制規則。

    private void initSystemRule() {List<SystemRule> rules = new ArrayList<>();SystemRule rule = new SystemRule();rule.setHighestSystemLoad(10);rules.add(rule);SystemRuleManager.loadRules(rules); }

    注意系統規則只針對入口資源(EntryType=IN)生效。更多詳情可以參考?系統自適應保護文檔。

    訪問控制規則 (AuthorityRule)

    很多時候,我們需要根據調用方來限制資源是否通過,這時候可以使用 Sentinel 的訪問控制(黑白名單)的功能。黑白名單根據資源的請求來源(origin)限制資源是否通過,若配置白名單則只有請求來源位于白名單內時才可通過;若配置黑名單則請求來源位于黑名單時不通過,其余的請求通過。

    授權規則,即黑白名單規則(AuthorityRule)非常簡單,主要有以下配置項:

    • resource:資源名,即規則的作用對象
    • limitApp:對應的黑名單/白名單,不同 origin 用?,?分隔,如?appA,appB
    • strategy:限制模式,AUTHORITY_WHITE?為白名單模式,AUTHORITY_BLACK?為黑名單模式,默認為白名單模式

    更多詳情可以參考?來源訪問控制。

    熱點規則 (ParamFlowRule)

    詳情可以參考?熱點參數限流。

    查詢更改規則

    引入了 transport 模塊后,可以通過以下的 HTTP API 來獲取所有已加載的規則:

    http://localhost:8719/getRules?type=<XXXX>

    其中,type=flow?以 JSON 格式返回現有的限流規則,degrade 返回現有生效的降級規則列表,system 則返回系統保護規則。

    獲取所有熱點規則:

    http://localhost:8719/getParamRules

    定制自己的持久化規則

    上面的規則配置,都是存在內存中的。即如果應用重啟,這個規則就會失效。因此我們提供了開放的接口,您可以通過實現?DataSource?接口的方式,來自定義規則的存儲數據源。通常我們的建議有:

    • 整合動態配置系統,如 ZooKeeper、Nacos、Apollo 等,動態地實時刷新配置規則
    • 結合 RDBMS、NoSQL、VCS 等來實現該規則
    • 配合 Sentinel Dashboard 使用

    更多詳情請參考?動態規則配置。

    規則生效的效果

    判斷限流降級異常

    在 Sentinel 中所有流控降級相關的異常都是異常類?BlockException?的子類:

    • 流控異常:FlowException
    • 熔斷降級異常:DegradeException
    • 系統保護異常:SystemBlockException
    • 熱點參數限流異常:ParamFlowException

    我們可以通過以下函數判斷是否為 Sentinel 的流控降級異常:

    BlockException.isBlockException(Throwable t);

    除了在業務代碼邏輯上看到規則生效,我們也可以通過下面簡單的方法,來校驗規則生效的效果:

    • 暴露的 HTTP 接口:通過運行下面命令?curl http://localhost:8719/cnode?id=<資源名稱>,觀察返回的數據。如果規則生效,在返回的數據欄中的?block?以及?block(m)?中會有顯示
    • 日志:Sentinel 提供秒級的資源運行日志以及限流日志,詳情可以參考:?日志

    block 事件

    Sentinel 提供以下擴展接口,可以通過?StatisticSlotCallbackRegistry?向?StatisticSlot?注冊回調函數:

    • ProcessorSlotEntryCallback: callback when resource entry passed (onPass) or blocked (onBlocked)
    • ProcessorSlotExitCallback: callback when resource entry successfully completed (onExit)

    可以利用這些回調接口來實現報警等功能,實時的監控信息可以從?ClusterNode?中實時獲取。

    其它 API

    業務異常統計 Tracer

    業務異常記錄類?Tracer?用于記錄業務異常。相關方法:

    • trace(Throwable e):記錄業務異常(非?BlockException?異常),對應的資源為當前線程 context 下 entry 對應的資源。該方法必須在?SphU.entry(xxx)?成功之后且 exit 之前調用,否則當前 context 為空則會拋出異常。
    • trace(Throwable e, int count):記錄業務異常(非?BlockException?異常),異常數目為傳入的?count。該方法必須在?SphU.entry(xxx)?成功之后且 exit 之前調用,否則當前 context 為空則會拋出異常。
    • traceEntry(Throwable, int, Entry):向傳入 entry 對應的資源記錄業務異常(非?BlockException?異常),異常數目為傳入的?count。

    如果用戶通過?SphU?或?SphO?手動定義資源,則 Sentinel 不能感知上層業務的異常,需要手動調用?Tracer.trace(ex)?來記錄業務異常,否則對應的異常不會統計到 Sentinel 異常計數中。注意不要在 try-with-resources 形式的?SphU.entry(xxx)?中使用,否則會統計不上。

    從 1.3.1 版本開始,注解方式定義資源支持自動統計業務異常,無需手動調用?Tracer.trace(ex)?來記錄業務異常。Sentinel 1.3.1 以前的版本需要手動記錄。

    上下文工具類 ContextUtil

    相關靜態方法:

    標識進入調用鏈入口(上下文)

    以下靜態方法用于標識調用鏈路入口,用于區分不同的調用鏈路:

    • public static Context enter(String contextName)
    • public static Context enter(String contextName, String origin)

    其中?contextName?代表調用鏈路入口名稱(上下文名稱),origin?代表調用來源名稱。默認調用來源為空。返回值類型為?Context,即生成的調用鏈路上下文對象。

    流控規則中若選擇“流控方式”為“鏈路”方式,則入口資源名即為上面的?contextName。

    注意

    • ContextUtil.enter(xxx)?方法僅在調用鏈路入口處生效,即僅在當前線程的初次調用生效,后面再調用不會覆蓋當前線程的調用鏈路,直到 exit。Context?存于 ThreadLocal 中,因此切換線程時可能會丟掉,如果需要跨線程使用可以結合?runOnContext?方法使用。
    • origin 數量不要太多,否則內存占用會比較大。

    退出調用鏈(清空上下文)

    • public static void exit():該方法用于退出調用鏈,清理當前線程的上下文。

    獲取當前線程的調用鏈上下文

    • public static Context getContext():獲取當前線程的調用鏈路上下文對象。

    在某個調用鏈上下文中執行代碼

    • public static void runOnContext(Context context, Runnable f):常用于異步調用鏈路中 context 的變換。

    指標統計配置

    Sentinel 底層采用高性能的滑動窗口數據結構來統計實時的秒級指標數據,并支持對滑動窗口進行配置。主要有以下兩個配置:

    • windowIntervalMs:滑動窗口的總的時間長度,默認為 1000 ms
    • sampleCount:滑動窗口劃分的格子數目,默認為 2;格子越多則精度越高,但是內存占用也會越多

    我們可以通過?SampleCountProperty?來動態地變更滑動窗口的格子數目,通過?IntervalProperty?來動態地變更滑動窗口的總時間長度。注意這兩個配置都是全局生效的,會影響所有資源的所有指標統計。

    Dashboard

    詳情請參考:Sentinel Dashboard 文檔。

    總結

    以上是生活随笔為你收集整理的Sentinel(三)之如何使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。