日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

定義資源

若您需要對特定的方法或者代碼塊進行流控,可以使用定義資源來實現。AHAS提供了5種定義資源的方法,定義資源后,在AHAS控制臺為應用配置相應規則即可生效。

背景信息

AHAS是圍繞著資源來工作的。編碼的時,只需關注如何定義資源,即哪些方法或代碼塊可能需要保護,而無需關注這個資源要如何保護。可通過定義資源來實現對代碼塊的流控,定義資源方式如下:

  • 注解方式定義資源
  • 拋出異常的方式定義資源
  • 返回布爾值方式定義資源
  • 異步調用支持
  • 主流框架的默認適配

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

通過@SentinelResource注解定義資源并配置blockHandlerfallback函數來進行限流之后的處理。

示例:

// 原本的業務方法.
@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函數僅會在原方法被降級時作為Fallback方法,其它時候不會被調用。

更多信息請參見Sentinel 注解支持文檔

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

使用拋出異常的方式定義資源后,當資源發生了限流之后會拋出BlockException。您可以按需捕捉異常,并進行限流之后的邏輯處理。示例代碼如下:

Entry entry = null;
// 務必保證finally會被執行
try {
  // 資源名可使用任意有業務語義的字符串
  entry = SphU.entry("自定義資源名");
  // 被保護的業務邏輯
  // do something...
} catch (BlockException ex) {
  // 資源訪問阻止,被限流或被降級
  // 進行相應的處理操作
} finally {
  if (entry != null) {
    entry.exit();
  }
}
重要 SphU.entry(xxx)需要與entry.exit()方法需匹配調用,否則會導致調用鏈記錄異常,拋出ErrorEntryFreeException異常。

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

使用返回布爾值方式定義資源方式后,當資源發生了限流之后會返回false。可以根據返回值,進行限流之后的邏輯處理。示例代碼如下:

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

方式四:異步調用支持

AHAS支持異步調用鏈路的統計。在異步調用中,需要通過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 方法獲取異步 Context
            ContextUtil.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
            

普通資源與異步資源之間嵌套示例請參見AsyncEntryDemo.java

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

為了減少開發的復雜程度,AHAS對主流框架進行了適配,詳情請參見支持組件列表。使用時只需要引入任意一個對應的SDK依賴,它們框架的方法和服務都會自動被定義為資源,無需修改現有代碼。