91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Sentinel分布式系統限流降級框架

發布時間:2021-10-13 10:25:43 來源:億速云 閱讀:165 作者:iii 欄目:編程語言

這篇文章主要講解了“如何理解Sentinel分布式系統限流降級框架”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解Sentinel分布式系統限流降級框架”吧!

(一)概述

在分布式系統中,許多服務之間通過遠程調用實現信息交互,調用時難免會出現調用失敗的情況,Sentinel能保證在一個服務出現問題的情況下,不會導致整體服務失敗,防止服務雪崩,提高分布式系統的可用性。

常用的容錯方式有:

1、超時:設置比較短的超時時間,如果調用不成功,在很短時間內就釋放連接,避免大量線程堵塞等待。

2、限流:超過設置的閾值就拒絕請求。

3、斷路器:保護服務過載,當有服務發生無法調用請求堆積時,能夠及時切換該服務,防止整個服務的崩潰。

Sentinel的地位和SpringCloud中的Hystrix類似,Sentinel以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。

(二)SpringCloudAlibaba集成Sentinel

首先我們在sentinel的github官網上下載sentinel-dashboard-1.7.2.jar

然后通過jar命令啟動起來,端口默認8080,直接ip+端口訪問,這是sentinel的控制后臺,賬號密碼都是sentinel

如何理解Sentinel分布式系統限流降級框架 接著在項目中引入依賴

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

在配置文件中,輸入Sentinel的后臺地址,地址和端口寫自己的,端口默認8080

spring.cloud.sentinel.transport.dashboard=localhost:8080

啟動后在Sentinel后臺就可以看到這個應用

如何理解Sentinel分布式系統限流降級框架

sentinel控制臺調用的API默認是http://ip:8719/api,在本地啟動了引入sentinel依賴的項目啟動后,默認在8719這個端口上會暴露一個api出來。

(三)sentinel的流控規則

寫了一個簡單的請求:

@RestController
public class TestController {
    @GetMapping("/test")
    public String test(){
        return "test";
    }
}

接下來通過這個請求去了解sentinel的流控規則,所謂流控規則,就是對請求的控制

如何理解Sentinel分布式系統限流降級框架

資源名:默認是請求的路徑

針對來源:Sentinel可以針對調用者進行限流,填寫微服務名,指定對哪個微服務進行限流 ,默認default(不區分來源,全部限制)

閾值類型:可選QPS和線程數,可以設置達到多少后執行流控策略

是否集群:你的環境是否是集群

流控模式

1、直接:直接對該資源進行控制,比如上面的/test訪問達到閾值,就限流

2、關聯:當關聯的資源達到閾值時,就限流自己。

如何理解Sentinel分布式系統限流降級框架 看圖,如果/test2訪問達到閾值,就限流/test

3、鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就可以限流),這個鏈路的名稱可以從簇點鏈路中獲取。

如何理解Sentinel分布式系統限流降級框架

流控效果

1、快速失敗:直接失敗

2、Warm Up:預熱模式,根據codeFactory的值(默認3),從閾值/codeFactory,經過預熱時長,才達到設置的QPS閾值。比如設置QPS為90,設置預熱為10秒,則最初的閾值為90/3=30,經過10秒后才達到90。

3、排隊等待:比如設置閾值為10,超時時間為500毫秒,當第11個請求到的時候,不會直接報錯,而是等待500毫秒,如果之后閾值還是超過10,則才會被限流。

設置完流控規則后,不停刷新去觸發到閾值,看到出現了下面的提示:

如何理解Sentinel分布式系統限流降級框架

這樣的提示不太友好,可以自定義限流后返回的數據信息,分別對應于五種限流異常:

public class MyBlockException implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        JSONObject object=new JSONObject();
        if (e instanceof FlowException){
            object.put("status","100");
            object.put("message","接口限流");
            object.put("data",null);
        }else if (e instanceof DegradeException){
            object.put("status","101");
            object.put("message","服務降級");
            object.put("data",null);
        }else if (e instanceof ParamFlowException){
            object.put("status","102");
            object.put("message","熱點參數限流");
            object.put("data",null);
        }else if (e instanceof SystemBlockException){
            object.put("status","103");
            object.put("message","觸發系統保護");
            object.put("data",null);
        }else if (e instanceof AuthorityException){
            object.put("status","104");
            object.put("message","授權規則不通過");
            object.put("data",null);
        }

        httpServletResponse.setStatus(500);
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(httpServletResponse.getWriter(),object);
    }
}

代碼中定義了五種不同的

(四)sentinel的降級規則

降級規則指的是在應用高峰期,將個別的服務關閉,使得能夠有更多地資源去處理重要的業務,比如雙十一的時候,我們會發現支付寶的部分功能會被暫時關閉。

如何理解Sentinel分布式系統限流降級框架

RT模式:平均響應時間、當1S內持續進入N個請求,如果平均響應時間超過閾值,那么在接下來的時間窗口內,按降級邏輯進行處理(報一個DegradeException錯誤)。

異常比例:可以輸入一個0.0~1.0的數字,表示出現異常的比例。如果一秒內超過這個比例,那么在接下來的時間窗口內,按降級邏輯進行處理。

異常數:指當資源近一分鐘的異常數超過閾值之后會,那么在接下來的時間窗口內,按降級邏輯進行處理。

(五)sentinel的熱點規則

所謂熱點規則,就是對某些經常訪問的數據(熱點數據),對其訪問進行限制,

比如以商品ID為參數,限制這個商品的訪問次數。在代碼中需要對要限制的請求進行埋點

@GetMapping("/test3")
@SentinelResource(value = "test3",blockHandler = "handHotKey")
public String test3(@RequestParam(value = "a",required = false)String a,
                    @RequestParam(value = "b",required = false)String b){
    return "test3"+a+b;
}

public String handHotKey(String a1, String a2, BlockException e){
    return "熱點數據限流";
}

設置熱點規則,這里的資源名就是@SentinelResource中所設置的value,參數索引的表示對第幾個參數進行限流控制,閾值和窗口時長表示在1秒內如果有2個對參數0的請求,就限流。限流后會執行自己設置的blockHandler方法。

如何理解Sentinel分布式系統限流降級框架

高級設置中可以設置參數例外項,即根據設置參數的值進行限流:

如何理解Sentinel分布式系統限流降級框架

這樣設置后,如果訪問/test3?a=1,則按照下面的閾值進行控制。

(六)Sentinel的系統規則

通過監控系統的一些參數進行規則限流: 如何理解Sentinel分布式系統限流降級框架

Load:這個參數只能在Linux或類Unix機器生效,將系統的1分鐘的loadAverage作為指標,這個值一般設置為CPU核心數量*2.5。

RT:當單臺機器上所有入口流量的平均RT達到閾值就觸發系統保護,單位是毫秒。

并發線程數:當單臺機器上所有入口流量的并發線程數達到閾值就觸發系統保護。

入口QPS:當單臺機器上所有入口流量的QPS達到閾值就觸發閾值就觸發系統保護。

CPU使用率:當系統CPU使用率超過閾值就觸發系統保護。

(七)Sentinel的授權規則

授權規則可以指定哪些請求可以訪問哪些不能訪問,首先來看如何配置:

如何理解Sentinel分布式系統限流降級框架

資源名就是請求名,流控應用中可以手動輸入一些應用名,如果是白名單,則流控應用中設置的這些可以訪問,如果是黑名單則流控應用中設置的不能訪問。

接著需要在代碼中去獲取請求:

@Component
public class MyRequestOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String origin=httpServletRequest.getParameter("origin");
        if (origin==null){
            throw new IllegalArgumentException("origin參數未指定");
        }
        return origin;

    }
}

通過設置后,所有請求必須帶上參數origin=XXX,以上面的配置為例,只有origin=javayz的請求才能通過訪問。如果不喜歡參數的方式,可以在代碼中換成header傳遞,效果一樣。

(八)Sentinel控制臺與服務之間的通信原理

使用Sentinel需要引入引入sentinel依賴,其中sentinel-transport-simple-http依賴會將微服務注冊到SentinelDashboard中。啟動微服務之后,會在8719端口自動開放一系列api接口,我們也可以通過http://ip:8719/api訪問到這些api接口,SentinelDashboard就是通過這些API與微服務之間進行通信。

這個8719端口可以在配置文件中修改:

spring.cloud.sentinel.transport.port=8719

(九)Sentinel的保護規則

默認情況下,我們代碼中的所有GetMapping、PostMapping請求都會被Sentinel保護,也就是都會經過Sentinel的攔截器,但是也可以手動關閉這個攔截。

spring.cloud.sentinel.filter.enabled=false

這樣的話sentinel就沒法捕捉請求了。但是還是可以通過代碼的方式使用Sentinel

@GetMapping("/test4")
public String test4(){
    ContextUtil.enter("test4","abc");
    Entry entry=null;
    try {
        entry= SphU.entry("test4");
        //業務代碼
        return "業務處理結束";
    } catch (BlockException e) {
        e.printStackTrace();
        //一系列的異常處理。參考MyBlockException
        //.....
        return "觸發限流";
    }catch (NullPointerException e){
        //對異常進行監控
        Tracer.trace(e);
        return "空指針異常";            
    }finally {
        if (entry!=null){
            entry.exit();
        }
        ContextUtil.exit();
    }
}

或者還可以使用注解方式加入埋點

@SentinelResource(value = "test3",blockHandler = "handHotKey")

這樣配置后就增加了資源test3的攔截,如果觸發限流策略,就會進入當前類的handHotKey方法,或者配置blockHandlerClass,就會進入blockHandlerClass所配置類中的handHotKey方法。

(十)RestTemplate整合Sentinel

首先需要在配置文件中開啟對RestTemplate的支持,默認也是true

resttemplate.sentinel.enabled=true

接著在RestTemplate注入Bean的代碼中增加一個Sentinel注解:

@SentinelRestTemplate(blockHandler = "fallback",blockHandlerClass = MyBlockHandlerClass.class)
@LoadBalanced //負載均衡
@Bean
public RestTemplate restTemplate(){
    return new RestTemplate();
}

調用的限流處理方法如下:

public class MyBlockHandlerClass {
    public static SentinelClientHttpResponse block(){
        return new SentinelClientHttpResponse("block info");
    }
}

(十一)Feign整合Sentinel

首先需要在配置文件中開啟對Feign的支持,默認為false:

feign.sentinel.enabled=true

接在在@FeignClient注解中增加fallback的類:

@FeignClient(name = "nacos-discovery-provider",fallback = TestServiceFallback.class,configuration = FeignConfiguration.class)
public interface TestService {
    @GetMapping("/{name}")
    String index(@PathVariable("name") String string);
}

最后設置規則后就會觸發fallback中對應的方法,具體實現
public class TestServiceFallback implements TestService{
    @Override
    public String index(String string) {
        return "fallback";
    }
}

(十二)Sentinel的持久化

默認模式:

在前面介紹Sentinel時,會發現每次重啟微服務后Sentinel中的配置都會丟失,這是因為API將規則推送到了客戶端的內存中,重啟后就消失了。

Pull模式

在Sentinel Dashboard中設置規則之后,推送給客戶端后不僅保存在內存中,還會保存到本地文件中。Pull模式需要通過代碼實現,這段代碼可以直接拿去復用:

@Slf4j
public class FileDataSourceInit implements InitFunc {
    @Override
    public void init() throws Exception {

        String ruleDir=System.getProperty("user.home")+"/sentinel/rules";
        log.info(ruleDir);
        //限流規則路徑
        String flowRulePath = ruleDir + "/flow-rule.json";
        //降級規則路徑
        String degradeRulePath = ruleDir + "/degrade-rule.json";
        //熱點規則路徑
        String paramFlowRulePath = ruleDir+"/param-flow-rule.json";
        //系統規則路徑
        String systemRulePath = ruleDir+"/system-rule.json";
        //權限規則路徑
        String authorityRulePath=ruleDir+"/authority-rule.json";

        this.mkdirIfNotExists(ruleDir);
        this.createFileIfNotExists(flowRulePath);
        this.createFileIfNotExists(flowRulePath);
        this.createFileIfNotExists(flowRulePath);
        this.createFileIfNotExists(flowRulePath);
        this.createFileIfNotExists(flowRulePath);

        // 流控規則,可讀取數據
        ReadableDataSource<String, List<FlowRule>> flowRuleRDS=new FileRefreshableDataSource<>(
                flowRulePath,
                flowRuleListParser
        );
        //將可讀數據源注入到FlowRuleManager,當文件發生變化時就會更新規則到緩存
        FlowRuleManager.register2Property(flowRuleRDS.getProperty());
        //流控規則:可寫數據源
        WritableDataSource<List<FlowRule>> flowRuleWDS=new FileWritableDataSource<List<FlowRule>>(
                flowRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);

        //降級規則:可讀數據源
        ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS=new FileRefreshableDataSource<>(
                degradeRulePath,
                degradeRuleListParser
        );
        DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
        //降級規則:可寫數據源
        WritableDataSource<List<DegradeRule>> degradeRuleWDS=new FileWritableDataSource<List<DegradeRule>>(
                flowRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);

        //熱點參數:可讀數據源
        ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS=new FileRefreshableDataSource<>(
                paramFlowRulePath,
                paramFlowRuleListParser
        );
        ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
        //熱點參數:可寫數據源
        WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS=new FileWritableDataSource<List<ParamFlowRule>>(
                paramFlowRulePath,
                this::encodeJson
        );
        ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);

        //系統規則:可讀數據源
        ReadableDataSource<String, List<SystemRule>> systemRuleRDS=new FileRefreshableDataSource<>(
                systemRulePath,
                systemRuleListParser
        );
        SystemRuleManager.register2Property(systemRuleRDS.getProperty());
        //系統規則:可寫數據源
        WritableDataSource<List<SystemRule>> systemRuleWDS=new FileWritableDataSource<List<SystemRule>>(
                systemRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);

        //授權規則:可讀數據源
        ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS=new FileRefreshableDataSource<>(
                authorityRulePath,
                authorityRuleListParser
        );
        AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
        WritableDataSource<List<AuthorityRule>> authorityRuleWDS=new FileWritableDataSource<List<AuthorityRule>>(
                authorityRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
    }

    private Converter<String,List<FlowRule>> flowRuleListParser=source-> JSON.parseObject(
            source,
            new TypeReference<List<FlowRule>>(){}
    );
    private Converter<String,List<DegradeRule>> degradeRuleListParser=source-> JSON.parseObject(
            source,
            new TypeReference<List<DegradeRule>>(){}
    );
    private Converter<String,List<SystemRule>> systemRuleListParser=source-> JSON.parseObject(
            source,
            new TypeReference<List<SystemRule>>(){}
    );
    private Converter<String,List<AuthorityRule>> authorityRuleListParser=source-> JSON.parseObject(
            source,
            new TypeReference<List<AuthorityRule>>(){}
    );
    private Converter<String,List<ParamFlowRule>> paramFlowRuleListParser=source-> JSON.parseObject(
            source,
            new TypeReference<List<ParamFlowRule>>(){}
    );


    private void mkdirIfNotExists(String filePath) {
        File file=new File(filePath);
        if (!file.exists()){
            file.mkdirs();
        }
    }

    private void createFileIfNotExists(String filePath) throws IOException {
        File file=new File(filePath);
        if (!file.exists()){
            file.createNewFile();
        }
    }

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

sentinel的數據持久化是通過SPI機制實現的,因此需要在resource下新建文件夾META-INF/services,然后新建一個文件com.alibaba.csp.sentinel.init.InitFunc

文件中寫入上面這個類的全限定名:

如何理解Sentinel分布式系統限流降級框架

之后產生規則后就會在代碼中設定的路徑下產生json文件,重啟后之前的配置也不會消失。

Push模式: 客戶端通過注冊監聽器的方式時刻監聽變化,比如使用Nacos、Zookeeper等配置中心,這種方式保證了很好的實時性和一致性,生產環境中一般采用push模式。我們用Nacos實現

1、添加sentinel-datasource-nacos依賴

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

2、配置持久化數據源

spring.cloud.sentinel.datasource.ds1.nacos.server-addr=192.168.78.128:8848
spring.cloud.sentinel.datasource.ds1.nacos.data-id=${spring.application.name}.json
spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.data-type=json
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow

3、在Nacos中手動添加配置文件,這里的配置文件取的就是和本地配置文件相同格式

如何理解Sentinel分布式系統限流降級框架

[
    {
        "clusterMode":false,
        "controlBehavior":0,
        "count":2,
        "grade":1,
        "limitApp":"default",
        "maxQueueingTimeMs":500,
        "resource":"/test",
        "strategy":0,
        "warmUpPeriodSec":10
    }
]

push模式目前還有缺點,Nacos修改配置文件后可同步到Sentinel,但是在Sentinel中修改配置后無法同步到Nacos,需要手動去同步數據。

感謝各位的閱讀,以上就是“如何理解Sentinel分布式系統限流降級框架”的內容了,經過本文的學習后,相信大家對如何理解Sentinel分布式系統限流降級框架這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

房山区| 比如县| 株洲市| 平谷区| 呼伦贝尔市| 张北县| 呈贡县| 鹿邑县| 司法| 鲁甸县| 泸溪县| 洞头县| 航空| 交城县| 通江县| 新闻| 嘉荫县| 镇安县| 东辽县| 平度市| 汝城县| 南江县| 墨竹工卡县| 白山市| 晋中市| 娱乐| 西吉县| 股票| 醴陵市| 阳谷县| 额尔古纳市| 弋阳县| 大港区| 蒲城县| 郎溪县| 庆安县| 当雄县| 濉溪县| 奇台县| 青浦区| 邻水|