<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>

          流量治理神器-Sentinel 究竟是怎么做到讓業(yè)務(wù)方接入簡(jiǎn)單?

          共 3522字,需瀏覽 8分鐘

           ·

          2021-11-20 01:02

          點(diǎn)擊上方藍(lán)字“設(shè)為星標(biāo)”



          大家好,我是架構(gòu)擺渡人,這是流量治理系列的第10篇原創(chuàng)文章,如果有收獲,還請(qǐng)分享給更多的朋友。
          ?
          做業(yè)務(wù)開發(fā),需要考慮業(yè)務(wù)的擴(kuò)展性。做基礎(chǔ)框架開發(fā),需要考慮如何讓業(yè)務(wù)方接入,使用簡(jiǎn)單,盡量不要耦合在業(yè)務(wù)代碼中。
          ?
          Sentinel里面是如何做到讓業(yè)務(wù)方接入簡(jiǎn)單,使用方便的呢?這篇文章就來剖析下Sentinel的那些適配是如何實(shí)現(xiàn)的。

          基本使用




          基本使用可以直接用SphU類對(duì)資源進(jìn)行保護(hù),使用方式如下:

          ?

          public static void main(String[] args) {    // 配置規(guī)則.    initFlowRules();    while (true) {        // 1.5.0 版本開始可以直接利用 try-with-resources 特性        try (Entry entry = SphU.entry("HelloWorld")) {            // 被保護(hù)的邏輯            System.out.println("hello world");     } catch (BlockException ex) {            // 處理被流控的邏輯      System.out.println("blocked!");     }    }}

          ?

          這種方式其實(shí)就違背了前面我們說的耦合問題,跟業(yè)務(wù)代碼耦合在了一起,擴(kuò)展性不好。

          ?

          注解使用




          可以在基本使用的基礎(chǔ)上優(yōu)化下,不在業(yè)務(wù)代碼中出現(xiàn)SphU相關(guān)的代碼,比如說定義一個(gè)注解在來實(shí)現(xiàn)這個(gè)功能。

          ?

          使用方式如下:

          ?

          @SentinelResource("HelloWorld")public void helloWorld() {    // 資源中的邏輯    System.out.println("hello world");}

          ?

          通過注解和切面我們就可以將邏輯收攏,不會(huì)在散落在各個(gè)業(yè)務(wù)代碼中,就算有一天你的限流方式改成了其他框架,注解都不用變,直接將切面里面的邏輯更新即可。

          ?

          適配Dubbo




          當(dāng)我們需要對(duì)Dubbo的接口進(jìn)行限流時(shí),使用原生的代碼方式和注解方式都可以,但是這樣就需要我們?cè)诿總€(gè)調(diào)用的地方進(jìn)行改造,那么能不能做成自動(dòng)適配的方式,連注解都不用加呢?

          ?

          在Sentinel中有一個(gè)sentinel-apache-dubbo-adapter的模塊就是專門用于適配dubbo的。原理就是通過Dubbo的Filter機(jī)制來實(shí)現(xiàn)通用的適配邏輯。

          ?

          有consumer Filter和provider Filter, 業(yè)務(wù)方只需要依賴這個(gè)包,就自動(dòng)適配dubbo了,然后通過Sentinel的控制臺(tái)進(jìn)行配置,就可以達(dá)到限流和熔斷的效果了。


          ?

          適配Feign




          Dubbo都適配了,怎么能少的了Feign呢,其實(shí)原理都是一樣,也是通過Feign的Filter機(jī)制來適配。不過Feign的適配整合放在了Spring Cloud Alibaba中。

          ?

          通過定義SentinelInvocationHandler,在invoke方法中適配Sentinel的邏輯。詳細(xì)代碼在com.alibaba.cloud.sentinel.feign.SentinelInvocationHandler中。


          ?

          適配Zuul




          對(duì)于Zuul的適配同樣有一個(gè)單獨(dú)的模塊sentinel-zuul-adapter。原理呢還是一樣,Zuul也有Filter, 既然是限流在Zuul中肯定是用pre filter。

          ?

          實(shí)現(xiàn)類是com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter,貼一小段代碼給大家看下:

          ?

          public Object run() throws ZuulException {    RequestContext ctx = RequestContext.getCurrentContext();    String origin = this.parseOrigin(ctx.getRequest());    String routeId = (String)ctx.get("proxy");    Deque asyncEntries = new ArrayDeque();    String fallBackRoute = routeId;    try {        if (StringUtil.isNotBlank(routeId)) {            ContextUtil.enter("sentinel_gateway_context$$route$$" + routeId, origin);            this.doSentinelEntry(routeId, 0, ctx, asyncEntries);        }        Set<String> matchingApis = this.pickMatchingApiDefinitions(ctx);        if (!matchingApis.isEmpty() && ContextUtil.getContext() == null) {            ContextUtil.enter("zuul_default_context", origin);        }        Iterator var14 = matchingApis.iterator();        while(var14.hasNext()) {            String apiName = (String)var14.next();            this.doSentinelEntry(apiName, 1, ctx, asyncEntries);        }    } catch (BlockException var12) {        ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(fallBackRoute);        BlockResponse blockResponse = zuulBlockFallbackProvider.fallbackResponse(fallBackRoute, var12);        ctx.setRouteHost((URL)null);        ctx.set("serviceId", (Object)null);        ctx.setResponseBody(blockResponse.toString());        ctx.setResponseStatusCode(blockResponse.getCode());        ctx.getResponse().setContentType("application/json; charset=utf-8");    } finally {        if (!asyncEntries.isEmpty()) {            ctx.put("_sentinel_entries", asyncEntries);        }    }    return null;}

          ?


          總結(jié)




          本文只是為了讓大家了解,在開發(fā)一個(gè)底層框架的時(shí)候,需要考慮的問題。這個(gè)問題就是使用起來越簡(jiǎn)單越好,這才是好的框架該有的樣子。

          ?

          當(dāng)然,Sentinel還適配了其他很多的框架,比如httpclient, Spring Cloud Gateway啊等,底層思想都是相同的,都是利用擴(kuò)展機(jī)制進(jìn)行統(tǒng)一處理。

          ?

          大家好,我是從古代穿越過來的美男子:架構(gòu)擺渡人。我將把我的武功秘籍全部傳授與你們,覺得有用請(qǐng)分享給身邊的朋友。來個(gè)三連吧,感謝各位!另外我還在B站錄制《真實(shí)訂單業(yè)務(wù),億級(jí)數(shù)據(jù)帶你實(shí)戰(zhàn)分庫分表》的實(shí)戰(zhàn)課程,記得去學(xué)習(xí)哦!


          點(diǎn)擊閱讀原文直達(dá)主頁

          瀏覽 34
          點(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>
                  亚洲无码福利导航 | 一级特黄大片色 | 国产标清视频 | 夫妻自拍在线观看 | 无码特级毛片 |