<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          超詳細(xì)的Sentinel入門

          共 23431字,需瀏覽 47分鐘

           ·

          2021-04-12 10:25

          文章已收錄Github精選,歡迎Star:https://github.com/yehongzhi/learningSummary

          一、什么是Sentinel

          Sentinel定位是分布式系統(tǒng)的流量防衛(wèi)兵。目前互聯(lián)網(wǎng)應(yīng)用基本上都使用微服務(wù),微服務(wù)的穩(wěn)定性是一個(gè)很重要的問題,而限流、熔斷降級(jí)是微服務(wù)保持穩(wěn)定的一個(gè)重要的手段。

          下面看官網(wǎng)的一張圖,了解一下Sentinel的主要特性:

          在Sentinel之前其實(shí)就有Hystrix做熔斷降級(jí)的事情,我們都知道出現(xiàn)新的事物肯定是原來的東西有不足的地方。

          那Hystrix有什么不足之處呢?

          • Hystrix常用的線程池隔離會(huì)造成線程上下切換的overhead比較大。
          • Hystrix沒有監(jiān)控平臺(tái),需要我們自己搭建。
          • Hystrix支持的熔斷降級(jí)維度較少,不夠細(xì)粒,而且缺少管理控制臺(tái)。

          Sentinel有哪些組成部分?

          • 核心庫(Java 客戶端)不依賴任何框架/庫,能夠運(yùn)行于所有 Java 運(yùn)行時(shí)環(huán)境,同時(shí)對(duì) Dubbo / Spring Cloud 等框架也有較好的支持。
          • 控制臺(tái)(Dashboard)基于 Spring Boot 開發(fā),打包后可以直接運(yùn)行,不需要額外的 Tomcat 等應(yīng)用容器。

          Sentinel有哪些特征?

          • 豐富的應(yīng)用場(chǎng)景。控制突發(fā)流量在可控制的范圍內(nèi),消息削峰填谷,集群流量控制,實(shí)時(shí)熔斷下游不可用的應(yīng)用等等。

          • 完備的實(shí)時(shí)監(jiān)控。Sentinel 提供實(shí)時(shí)的監(jiān)控功能。您可以在控制臺(tái)中看到接入應(yīng)用的單臺(tái)機(jī)器秒級(jí)數(shù)據(jù),甚至 500 臺(tái)以下規(guī)模的集群的匯總運(yùn)行情況。

          • 廣泛的開源生態(tài)。Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應(yīng)的依賴并進(jìn)行簡(jiǎn)單的配置即可快速地接入 Sentinel。

          • 完善的 SPI 擴(kuò)展點(diǎn)。Sentinel 提供簡(jiǎn)單易用、完善的 SPI 擴(kuò)展接口。您可以通過實(shí)現(xiàn)擴(kuò)展接口來快速地定制邏輯。例如定制規(guī)則管理、適配動(dòng)態(tài)數(shù)據(jù)源等。

          二、Hello World

          一般要學(xué)一種沒接觸過的技術(shù)框架,肯定要先做個(gè)Hello World熟悉一下。

          引入Maven依賴

          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-core</artifactId>
              <version>1.8.1</version>
          </dependency>

          需要提醒一下,Sentinel僅支持JDK 1.8或者以上的版本

          定義規(guī)則

          通過定義規(guī)則來控制該資源每秒允許通過的請(qǐng)求次數(shù),例如下面的代碼定義了資源 HelloWorld 每秒最多只能通過 20 個(gè)請(qǐng)求。

          private static void initFlowRules(){
              List<FlowRule> rules = new ArrayList<>();
              FlowRule rule = new FlowRule();
              rule.setResource("HelloWorld");
              rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
              // Set limit QPS to 20.
              rule.setCount(20);
              rules.add(rule);
              FlowRuleManager.loadRules(rules);
          }

          編寫Hello World代碼

          其實(shí)代碼編寫很簡(jiǎn)單,首先需要定義一個(gè)資源entry,然后用SphU.entry("HelloWorld")entry.exit()把需要流量控制的代碼包圍起來。代碼如下:

          public static void main(String[] args) throws Exception {
              initFlowRules();
              while (true) {
                  Entry entry = null;
                  try {
                      entry = SphU.entry("HelloWorld");
                      /*您的業(yè)務(wù)邏輯 - 開始*/
                      System.out.println("hello world");
                      /*您的業(yè)務(wù)邏輯 - 結(jié)束*/
                  } catch (BlockException e1) {
                      /*流控邏輯處理 - 開始*/
                      System.out.println("block!");
                      /*流控邏輯處理 - 結(jié)束*/
                  } finally {
                      if (entry != null) {
                          entry.exit();
                      }
                  }
              }
          }

          運(yùn)行結(jié)果如下:

          我們根據(jù)目錄查看日志,文件名格式為${appName}-metrics.log.xxx:

          |--timestamp-|------date time----|-resource-|p |block|s |e|rt
          1616607101000|2021-03-25 01:31:41|HelloWorld|20|11373|20|0|1|0|0|0
          1616607102000|2021-03-25 01:31:42|HelloWorld|20|24236|20|0|0|0|0|0

          p 代表通過的請(qǐng)求。

          block 代表被阻止的請(qǐng)求。

          s 代表成功執(zhí)行完成的請(qǐng)求個(gè)數(shù)。

          e 代表用戶自定義的異常。

          rt 代表平均響應(yīng)時(shí)長(zhǎng)。

          三、使用Sentinel的方式

          下面結(jié)合實(shí)際案例,寫一個(gè)Controller接口進(jìn)行示范練習(xí)。

          @RestController
          @RequestMapping("/user")
          public class UserController {
              @Resource
              private UserService userService;

              @RequestMapping("/list")
              public List<User> getUserList() {
                  return userService.getList();
              }
          }

          @Service
          public class UserServiceImpl implements UserService {
              //模擬查詢數(shù)據(jù)庫數(shù)據(jù),返回結(jié)果
              @Override
              public List<User> getList() {
                  List<User> userList = new ArrayList<>();
                  userList.add(new User("1""周慧敏"18));
                  userList.add(new User("2""關(guān)之琳"20));
                  userList.add(new User("3""王祖賢"21));
                  return userList;
              }
          }

          假設(shè)我們要讓這個(gè)查詢接口限流,怎么做呢?

          1) 拋出異常的方式

          SphU 包含了 try-catch 風(fēng)格的 API。用這種方式,當(dāng)資源發(fā)生了限流之后會(huì)拋出 BlockException。這個(gè)時(shí)候可以捕捉異常,進(jìn)行限流之后的邏輯處理。

          @RestController
          @RequestMapping("/user")
          public class UserController {
           //資源名稱
              public static final String RESOURCE_NAME = "userList";

              @Resource
              private UserService userService;

              @RequestMapping("/list")
              public List<User> getUserList() {
                  List<User> userList = null;
                  Entry entry = null;
                  try {
                      // 被保護(hù)的業(yè)務(wù)邏輯
                      entry = SphU.entry(RESOURCE_NAME);
                      userList = userService.getList();
                  } catch (BlockException e) {
                      // 資源訪問阻止,被限流或被降級(jí)
                      return Collections.singletonList(new User("xxx""資源訪問被限流"0));
                  } catch (Exception e) {
                      // 若需要配置降級(jí)規(guī)則,需要通過這種方式記錄業(yè)務(wù)異常
                      Tracer.traceEntry(e, entry);
                  } finally {
                      // 務(wù)必保證 exit,務(wù)必保證每個(gè) entry 與 exit 配對(duì)
                      if (entry != null) {
                          entry.exit();
                      }
                  }
                  return userList;
              }

          }

          實(shí)際上還沒寫完,還要定義限流的規(guī)則。

          @SpringBootApplication
          public class SpringmvcApplication {

              public static void main(String[] args) throws Exception {
                  SpringApplication.run(SpringmvcApplication.classargs);
                  //初始化限流規(guī)則
                  initFlowQpsRule();
              }
           //定義了每秒最多接收2個(gè)請(qǐng)求
              private static void initFlowQpsRule() {
                  List<FlowRule> rules = new ArrayList<>();
                  FlowRule rule = new FlowRule(UserController.RESOURCE_NAME);
                  // set limit qps to 2
                  rule.setCount(2);
                  rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
                  rule.setLimitApp("default");
                  rules.add(rule);
                  FlowRuleManager.loadRules(rules);
              }
          }

          然后啟動(dòng)項(xiàng)目,測(cè)試。快速刷新幾次,我們就看到觸發(fā)限流的邏輯了。

          2) 返回布爾值的方式

          拋出異常的方式是當(dāng)被限流時(shí)以拋出異常的形式感知,我們通過捕獲異常進(jìn)行限流的處理,這種方式跟上面不同的在于不拋出異常,而是返回一個(gè)布爾值,我們通過判斷布爾值來進(jìn)行限流邏輯的處理。這樣我們就可以很容易寫出if-else結(jié)構(gòu)的代碼。

          public static final String RESOURCE_NAME_QUERY_USER_BY_ID = "queryUserById";

          @RequestMapping("/get/{id}")
          public String queryUserById(@PathVariable("id") String id) {
              if (SphO.entry(RESOURCE_NAME_QUERY_USER_BY_ID)) {
                  try {
                      //被保護(hù)的邏輯
                      //模擬數(shù)據(jù)庫查詢數(shù)據(jù)
                      return JSONObject.toJSONString(new User(id, "Tom"25));
                  } finally {
                      //關(guān)閉資源
                      SphO.exit();
                  }
              } else {
                  //資源訪問阻止,被限流或被降級(jí)
                  return "Resource is Block!!!";
              }
          }

          添加規(guī)則的代碼跟前面的例子一樣,我就不寫了,然后啟動(dòng)項(xiàng)目,測(cè)試。

          3) 注解的方式

          看了上面兩種方式,肯定有人會(huì)說,代碼侵入性太強(qiáng)了,如果原來舊的系統(tǒng)要接入的話,要改原來的代碼。眾所周知,舊代碼是不能動(dòng)的,否則后果很嚴(yán)重。

          那么注解的方式就很好地解決了這個(gè)問題。注解式怎么寫呢?

          @Service
          public class UserServiceImpl implements UserService {
              //資源名稱
              public static final String RESOURCE_NAME_QUERY_USER_BY_NAME = "queryUserByUserName";

              //value是資源名稱,是必填項(xiàng)。blockHandler填限流處理的方法名稱
              @Override
              @SentinelResource(value = RESOURCE_NAME_QUERY_USER_BY_NAME, blockHandler = "queryUserByUserNameBlock")
              public User queryByUserName(String userName) {
                  return new User("0", userName, 18);
              }

              //注意細(xì)節(jié),一定要跟原函數(shù)的返回值和形參一致,并且形參最后要加個(gè)BlockException參數(shù)
              //否則會(huì)報(bào)錯(cuò),F(xiàn)lowException: null
              public User queryUserByUserNameBlock(String userName, BlockException ex) {
                  //打印異常
                  ex.printStackTrace();
                  return new User("xxx""用戶名稱:{" + userName + "},資源訪問被限流"0);
              }
          }

          寫完這個(gè)核心代碼后,還要加個(gè)配置,否則不生效。

          引入sentinel-annotation-aspectj的Maven依賴。

          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-annotation-aspectj</artifactId>
              <version>1.8.1</version>
          </dependency>

          然后將SentinelResourceAspect注冊(cè)為一個(gè)Bean。

          @Configuration
          public class SentinelAspectConfiguration {
              @Bean
              public SentinelResourceAspect sentinelResourceAspect() {
                  return new SentinelResourceAspect();
              }
          }

          別忘了添加規(guī)則,可以參考第一個(gè)例子,這里就不寫了。

          最后啟動(dòng)項(xiàng)目,測(cè)試,刷新多幾次接口后,出發(fā)限流,可以看到以下結(jié)果。

          4) 熔斷降級(jí)

          除了可以對(duì)接口進(jìn)行限流之外,當(dāng)接口出現(xiàn)異常時(shí),Sentinel也可以提供熔斷降級(jí)的功能。

          @SentinelResource注解中有一個(gè)屬性fallback,當(dāng)拋出非BlockException的異常時(shí),就會(huì)進(jìn)入到fallback方法中,實(shí)現(xiàn)熔斷機(jī)制,這有點(diǎn)類似于Hystrix的FallBack。

          我們拿上面的例子做示范,如果userName為空則拋出RuntimeException。然后我們?cè)O(shè)置fallback屬性的屬性值,也就是fallback的方法,返回系統(tǒng)異常。

          @Override
          @SentinelResource(value = RESOURCE_NAME_QUERY_USER_BY_NAME, blockHandler = "queryUserByUserNameBlock", fallback = "queryUserByUserNameFallBack")
          public User queryByUserName(String userName) {
              if (userName == null || "".equals(userName)) {
                  //拋出異常
                  throw new RuntimeException("queryByUserName() command failed, userName is null");
              }
              return new User("0", userName, 18);
          }

          public User queryUserByUserNameFallBack(String userName, Throwable ex) {
              //打印日志
              ex.printStackTrace();
              return new User("-1""用戶名稱:{" + userName + "},系統(tǒng)異常,請(qǐng)稍后重試"0);
          }

          然后啟動(dòng)項(xiàng)目,故意不傳userName,進(jìn)行測(cè)試,可以看到走了fallback的方法邏輯。

          IDEA控制臺(tái)也可以看到自定義的異常信息。

          四、管理控制臺(tái)

          上面講完了Sentinel的基本用法,實(shí)際上重頭戲在Sentinel的管理控制臺(tái),管理控制臺(tái)提供了很多實(shí)用的功能。下面我們看看怎么使用。

          首先下載控制臺(tái)的jar包,當(dāng)然你也可以通過下載源碼編譯得到。

          //下載頁面地址
          https://github.com/alibaba/Sentinel/releases

          然后使用以下命令啟動(dòng):

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

          啟動(dòng)成功后,訪問http://localhost:8080,默認(rèn)登錄的用戶名和密碼都是sentinel

          登錄進(jìn)去之后,可以看到主頁面,有許多功能菜單,這里就不一一介紹了。

          客戶端接入控制臺(tái)

          那么我們自己的應(yīng)用怎么接入到控制臺(tái),使用控制臺(tái)對(duì)應(yīng)用的流量進(jìn)行監(jiān)控呢,諸位客官,請(qǐng)繼續(xù)往下看。

          首先添加maven依賴,客戶端需要引入 Transport 模塊來與 Sentinel 控制臺(tái)進(jìn)行通信。

          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-transport-simple-http</artifactId>
              <version>1.8.1</version>
          </dependency>

          配置filter,把所有訪問的 Web URL 自動(dòng)統(tǒng)計(jì)為 Sentinel 的資源。

          @Configuration
          public class FilterConfig {
              @Bean
              public FilterRegistrationBean sentinelFilterRegistration() {
                  FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
                  registration.setFilter(new CommonFilter());
                  registration.addUrlPatterns("/*");
                  registration.setName("sentinelFilter");
                  registration.setOrder(1);

                  return registration;
              }
          }

          在啟動(dòng)命令中加入以下配置,-Dcsp.sentinel.dashboard.server=consoleIp:port 指定控制臺(tái)地址和端口,-Dcsp.sentinel.api.port=xxxx 指定客戶端監(jiān)控 API 的端口(默認(rèn)是8019,因?yàn)榭刂婆_(tái)已經(jīng)使用了8719,應(yīng)用端為了防止沖突就使用8720):

          -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.api.port=8720 -Dproject.name=sentinelDemo

          啟動(dòng)項(xiàng)目,我們可以看到多了一個(gè)應(yīng)用名稱sentinelDemo,點(diǎn)擊機(jī)器列表,查看健康狀況。

          請(qǐng)求/user/list接口,然后我們可以看到實(shí)時(shí)監(jiān)控的接口的QPS情況。

          這樣就代表客戶端接入控制臺(tái)成功了!

          動(dòng)態(tài)規(guī)則

          Sentinel 的理念是開發(fā)者只需要關(guān)注資源的定義,當(dāng)資源定義成功后可以動(dòng)態(tài)增加各種流控降級(jí)規(guī)則。Sentinel 提供兩種方式修改規(guī)則:

          • 通過 API 直接修改 (loadRules)
          • 通過 DataSource 適配不同數(shù)據(jù)源修改

          手動(dòng)通過API定義規(guī)則,前面Hello World的例子已經(jīng)寫過,是一種硬編碼的形式,因?yàn)椴粔蜢`活,所以肯定不能應(yīng)用于生產(chǎn)環(huán)境。

          所以要引入DataSource,規(guī)則設(shè)置可以存儲(chǔ)在數(shù)據(jù)源中,通過更新數(shù)據(jù)源中存儲(chǔ)的規(guī)則,推送到Sentinel規(guī)則中心,客戶端就可以實(shí)時(shí)獲取最新的規(guī)則,根據(jù)最新的規(guī)則進(jìn)行限流、降級(jí)。

          一般DataSource拓展常見的實(shí)現(xiàn)方式有:

          • 拉模式:客戶端主動(dòng)向某個(gè)規(guī)則管理中心定期輪詢拉取規(guī)則,這個(gè)規(guī)則中心可以是SQL、文件等。優(yōu)點(diǎn)是比較簡(jiǎn)單,缺點(diǎn)是無法及時(shí)獲取變更。
          • 推模式:規(guī)則中心統(tǒng)一推送,客戶端通過注冊(cè)監(jiān)聽器的方式時(shí)刻監(jiān)聽變化,比如使用Nacos、Zookeeper 等配置中心。這種方式有更好的實(shí)時(shí)性和一致性保證,比較推薦使用這種方式。

          拉模式

          pull模式的數(shù)據(jù)源一般是可寫入的(比如本地文件)。首先要在客戶端注冊(cè)數(shù)據(jù)源,將對(duì)應(yīng)的讀數(shù)據(jù)源注冊(cè)至對(duì)應(yīng)的 RuleManager;然后將寫數(shù)據(jù)源注冊(cè)至 transport 的 WritableDataSourceRegistry 中。

          由此看出這是一個(gè)雙向讀寫的過程,我們既可以在應(yīng)用本地直接修改文件來更新規(guī)則,也可以通過 Sentinel 控制臺(tái)推送規(guī)則。下圖為控制臺(tái)推送規(guī)則的流程圖。

          首先引入maven依賴。

          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-datasource-extension</artifactId>
              <version>1.8.1</version>
          </dependency>

          使用SPI機(jī)制進(jìn)行擴(kuò)展,創(chuàng)建一個(gè)實(shí)現(xiàn)類,實(shí)現(xiàn)InitFunc接口的init()方法。

          public class FileDataSourceInit implements InitFunc {

              public FileDataSourceInit() {
              }

              @Override
              public void init() throws Exception {
                  String filePath = System.getProperty("user.home") + "\\sentinel\\rules\\sentinel.json";
                  ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(
                      filePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                      })
                  );
                  // 將可讀數(shù)據(jù)源注冊(cè)至 FlowRuleManager.
                  FlowRuleManager.register2Property(ds.getProperty());

                  WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(filePath, this::encodeJson);
                  // 將可寫數(shù)據(jù)源注冊(cè)至 transport 模塊的 WritableDataSourceRegistry 中.
                  // 這樣收到控制臺(tái)推送的規(guī)則時(shí),Sentinel 會(huì)先更新到內(nèi)存,然后將規(guī)則寫入到文件中.
                  WritableDataSourceRegistry.registerFlowDataSource(wds);
              }

              private <T> String encodeJson(T t) {
                  return JSON.toJSONString(t);
              }
          }

          在項(xiàng)目的 resources/META-INF/services 目錄下創(chuàng)建文件,名為com.alibaba.csp.sentinel.init.InitFunc ,內(nèi)容則是FileDataSourceInit的全限定名稱:

          io.github.yehongzhi.springmvc.config.FileDataSourceInit

          接著在${home}目錄下,創(chuàng)建\sentinel\rules目錄,再創(chuàng)建sentinel.json文件。

          然后啟動(dòng)項(xiàng)目,發(fā)送請(qǐng)求,當(dāng)客戶端接收到請(qǐng)求后就會(huì)觸發(fā)初始化操作。初始化完成后我們到控制臺(tái),然后設(shè)置流量限流規(guī)則。

          新增后,本地文件sentinel.json同時(shí)也保存了規(guī)則內(nèi)容(壓縮成一行的json)。

          [{"clusterConfig":{"acquireRefuseStrategy":0,"clientOfflineTime":2000,"fallbackToLocalWhenFail":true,"resourceTimeout":2000,"resourceTimeoutStrategy":0,"sampleCount":10,"strategy":0,"thresholdType":0,"windowIntervalMs":1000},"clusterMode":false,"controlBehavior":0,"count":3.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"userList","strategy":0,"warmUpPeriodSec":10}]

          我們可以通過修改文件來更新規(guī)則內(nèi)容,也可以通過控制臺(tái)推送規(guī)則到文件中,這就是拉模式。缺點(diǎn)是不保證一致性,實(shí)時(shí)性不保證,拉取過于頻繁也可能會(huì)有性能問題。

          推模式

          剛剛說了拉模式實(shí)時(shí)性不能保證,推模式就解決了這個(gè)問題。除此之外還可以持久化,也就是數(shù)據(jù)保存在數(shù)據(jù)源中,即使重啟也不會(huì)丟失之前的配置,這也解決了原始模式存在內(nèi)存中不能持久化的問題。

          可以和Sentinel配合使用的數(shù)據(jù)源有很多種,比如ZooKeeper,Nacos,Apollo等等。這里介紹使用Nacos的方式。

          首先要啟動(dòng)Nacos服務(wù)器,然后登錄到Nacos控制臺(tái),添加一個(gè)命名空間,添加配置。

          接著我們就要改造Sentinel的源碼。因?yàn)楣倬W(wǎng)提供的Sentinel的jar是原始模式的,所以需要改造,所以我們需要拉取源碼下來改造一下,然后自己編譯jar包。

          源碼地址:https://github.com/alibaba/Sentinel

          拉取下來之后,導(dǎo)入到IDEA中,然后我們可以看到以下目錄結(jié)構(gòu)。

          首先修改sentinel-dashboard的pom.xml文件:

          第二步,把test目錄下的四個(gè)關(guān)于Nacos關(guān)聯(lián)的類,移到rule目錄下。

          FlowRuleNacosProvider和FlowRuleNacosPublisher不需要怎么改造,本人不太喜歡名稱后綴,所以去掉了后面的后綴。

          接著NacosConfig添加Nacos的地址配置。

          最關(guān)鍵的是FlowControllerV1的改造,這是規(guī)則配置的增刪改查的一些接口。

          把移動(dòng)到rule目錄下的兩個(gè)服務(wù),添加到FlowControllerV1類中。

          @Autowired
          @Qualifier("flowRuleNacosProvider")
          private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
          @Autowired
          @Qualifier("flowRuleNacosPublisher")
          private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

          添加私有方法publishRules(),用于推送配置:

          private void publishRules(/*@NonNull*/ String app) throws Exception {
              List<FlowRuleEntity> rules = repository.findAllByApp(app);
              rulePublisher.publish(app, rules);
          }

          修改apiQueryMachineRules()方法。

          修改apiAddFlowRule()方法。

          修改apiUpdateFlowRule()方法。

          修改apiDeleteFlowRule()方法。

          Sentinel控制臺(tái)的項(xiàng)目就改造完成了,用于生產(chǎn)環(huán)境就編譯成jar包運(yùn)行,如果是學(xué)習(xí)可以直接在IDEA運(yùn)行。

          我們?cè)谇懊鎰?chuàng)建的HelloWord工程的pom.xml文件加上依賴。

          <dependency>
              <groupId>com.alibaba.csp</groupId>
              <artifactId>sentinel-datasource-nacos</artifactId>
              <version>1.8.1</version>
          </dependency>

          然后在application.yml文件加上以下配置:

          spring:
            cloud:
              sentinel:
                datasource:
                  flow:
                    nacos:
                      server-addr: localhost:8848
                      namespace: 05f447bc-8a0b-4686-9c34-344d7206ea94
                      dataId: springmvc-sentinel-flow-rules
                      groupId: SENTINEL_GROUP
                      # 規(guī)則類型,取值見:
                      # org.springframework.cloud.alibaba.sentinel.datasource.RuleType
                      rule-type: flow
                      data-type: json
            application:
              name: springmvc-sentinel-flow-rules

          以上就完成了全部的配置和改造,啟動(dòng)Sentinel控制臺(tái),還有Java應(yīng)用。

          打開Nacos控制臺(tái),我們添加限流配置如下:

          配置內(nèi)容如下:

          [{"app":"springmvc-sentinel-flow-rules","clusterConfig":{"acquireRefuseStrategy":0,"clientOfflineTime":2000,"fallbackToLocalWhenFail":true,"resourceTimeout":2000,"resourceTimeoutStrategy":0,"sampleCount":10,"strategy":0,"thresholdType":0,"windowIntervalMs":1000},"clusterMode":false,"controlBehavior":0,"count":1.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"userList","strategy":0,"warmUpPeriodSec":10},{"app":"springmvc-sentinel-flow-rules","clusterConfig":{"acquireRefuseStrategy":0,"clientOfflineTime":2000,"fallbackToLocalWhenFail":true,"resourceTimeout":2000,"resourceTimeoutStrategy":0,"sampleCount":10,"strategy":0,"thresholdType":0,"windowIntervalMs":1000},"clusterMode":false,"controlBehavior":0,"count":3.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"queryUserByUserName","strategy":0,"warmUpPeriodSec":10}]

          然后我們打開Sentinel控制臺(tái),能看到配置,證明Nacos的配置推送成功了。

          我們嘗試調(diào)用Java應(yīng)用的接口,測(cè)試是否生效。

          可以看到限流是生效的,再看看Sentinel監(jiān)控的QPS情況。

          從QPS監(jiān)控的情況看,最高的QPS只有3,其他請(qǐng)求都被拒絕了,證明限流配置是實(shí)時(shí)生效的。

          配置信息也被持久化到Nacos相關(guān)的配置表中。

          這時(shí)候,再回頭看Sentinel官網(wǎng)上關(guān)于推模式的架構(gòu)圖就比較清楚了。

          總結(jié)

          本篇文章主要介紹了Sentinel的基本用法,還有動(dòng)態(tài)規(guī)則的兩種方式,除此之外當(dāng)然還有許多功能,這里由于篇幅問題就不一一介紹了,有興趣的朋友可以自己探索一下。我個(gè)人覺得Sentinel是一個(gè)非常優(yōu)秀的組件,比原來用的Hystrix的確有著非常大的改進(jìn),值得推薦。

          我們看到官網(wǎng)上登記的企業(yè)列表,也有很多知名企業(yè)在使用,相信以后Sentinel會(huì)越來越好。

          這篇文章就講到這里了,感謝大家的閱讀,希望看完大家能有所收獲!

          覺得有用就點(diǎn)個(gè)贊吧,你的點(diǎn)贊是我創(chuàng)作的最大動(dòng)力~

          我是一個(gè)努力讓大家記住的程序員。我們下期再見!!!

          能力有限,如果有什么錯(cuò)誤或者不當(dāng)之處,請(qǐng)大家批評(píng)指正,一起學(xué)習(xí)交流!

          瀏覽 55
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大鸡巴日骚逼视频 | 天天夜射免费视频 | 国产高清激情视频 | 色老板精品永久免费视频 | 看成人性毛片 |