【轉(zhuǎn)】【Sentinel】sentinel 集成 apollo 最佳實(shí)踐

原文:https://www.cnblogs.com/kiwifly/p/11569190.html

【Sentinel】sentinel 集成 apollo 最佳實(shí)踐

sentinel

前言

在 sentinel 的控制臺(tái)設(shè)置的規(guī)則信息默認(rèn)都是存在內(nèi)存當(dāng)中的铐伴。所以無(wú)論你是重啟了 sentinel 的客戶端還是 sentinel 的控制臺(tái)伦吠。你所設(shè)置的規(guī)則都會(huì)丟失亡电。如果想要 sentinel 在線上環(huán)境使用疾瓮,要么花錢用阿里云上的付費(fèi)版本,要么自己去實(shí)現(xiàn)規(guī)則的持久化,如果你或你所在的公司不差錢,那么關(guān)掉這篇文章菲嘴,直接用付費(fèi)版吧,省掉了一大堆坑要踩汰翠×淦海或者你是一個(gè)特立獨(dú)行的人,那么我們接著往下說(shuō)复唤。
??首先說(shuō)一下寫這篇文章的原因健田,因?yàn)檎娴迷谂c apllo 集成時(shí),踩坑踩到懷疑人生佛纫。另一點(diǎn)是妓局,找了一大堆關(guān)于集成的 apollo 的文章,都清一色的都是仿照官方給的限流規(guī)則的 DEMO 做的呈宇。 但是 sentinel 規(guī)則還有熔斷規(guī)則好爬、參數(shù)限流、系統(tǒng)限流甥啄、黑白名單等很多規(guī)則存炮,每個(gè)規(guī)則還有細(xì)節(jié)上的不一致,這些都沒有提蜈漓,還有一些客戶端的坑就更沒有了穆桂。踩了這么多坑,有了一點(diǎn)心得與體會(huì)迎变,梳理與此充尉,希望能幫助到讀者飘言。

拉取 sentinel 控制臺(tái)源碼進(jìn)行修改

因?yàn)樾薷膬?nèi)容過(guò)多衣形,本文不會(huì)詳述,下面的截圖是所有修改內(nèi)容姿鸿,并且因?yàn)閷戇@篇文章時(shí)谆吴,1.7版本在 master 開發(fā),有大量快照版本苛预。所以是切到當(dāng)前穩(wěn)定的 1.6 分支進(jìn)行修改的句狼。我已經(jīng) fork sentinel 到我的 github,下面是修改的內(nèi)容 地址

修改點(diǎn)1:實(shí)現(xiàn)所有規(guī)則的拉取與推送接口

添加與實(shí)現(xiàn)了所有的規(guī)則的 Provider 與 Publisher 的配置拉取的與推送热某。

修改點(diǎn)2:修改控制臺(tái)使用的規(guī)則操作 api

規(guī)則在控制臺(tái)的操作 controller 進(jìn)行大量改造腻菇。

修改點(diǎn)3:修改 xxEntity

最后一點(diǎn)也是最坑的修改了大量的 xxEntity 類胳螟,這些類是規(guī)則的實(shí)體類,本身沒什么筹吐,源碼是直接 json 化保存的糖耸,但是用于客戶端集成的 spring-cloud-alibaba 使用了 json 校驗(yàn),如果 apollo 保存的 json 與客戶端的實(shí)體類有一丁點(diǎn)不一樣就報(bào) convert 0 rules but there are 1 rules from datasource . RuleCLass: FlowRule 丘薛。是不是覺得很摸不著頭腦嘉竟,這報(bào)錯(cuò)跟 json 格式轉(zhuǎn)換錯(cuò)誤有什么,下面是 spring-cloud-alibaba json 轉(zhuǎn)換的代碼洋侨。

寫這段代碼的老哥舍扰,把這個(gè)異常吃了,并補(bǔ)上了一個(gè) // won't be happen 的注釋希坚,你能理解我當(dāng)時(shí)被這個(gè)報(bào)錯(cuò)坑的死去活來(lái)边苹,后來(lái)發(fā)現(xiàn)是這里的問(wèn)題嗎?后來(lái)在 github 上找到兩個(gè)同樣的問(wèn)題問(wèn)題1裁僧、問(wèn)題2勾给,按照方法把 xxEntity 中用不到的字段全部加上 @JSONField(serialize = false) 解決。

修改點(diǎn)4:抽離配置使得可以在啟動(dòng)的時(shí)傳入

添加的配置在下面

使用修改的控制臺(tái)版本

  1. 你可以fork sentinel 官方代碼按上述的自行修改锅知,然后打包
  2. 你可以拉取我 fork 的 sentinel 代碼下來(lái)直接打包
  3. 你可以使用我已經(jīng)打好的包 地址

自定義配置

配置名稱 是否必填 默認(rèn)值 作用
env DEV 指定 apollo 使用的環(huán)境
app.id sentinel-apollo 指定保存 sentinel 規(guī)則的 apollo 應(yīng)用 ID
cluster.name default 指定保存 sentinel 使用的 apollo 集群
namespace.name application 指定保存 sentinel 使用的 apollo 命名空間
modify.user apollo 控制臺(tái)顯示的修改人賬號(hào)播急,此賬號(hào)務(wù)必要有此應(yīng)用的權(quán)限
modify.comment modify by sentinel-dashboard apollo 控制臺(tái)顯示的修改備注
release.user apollo 控制臺(tái)顯示的發(fā)布人賬號(hào),此賬號(hào)務(wù)必要有此應(yīng)用的權(quán)限
release.comment release by sentinel-dashboard apollo 控制臺(tái)顯示的發(fā)布備注
apollo.portal.url apollo 控制臺(tái)的地址
apollo.application.token 指定保存 sentinel 規(guī)則的 apollo 應(yīng)用 openapi 的 token
authority.key.suffix authority 認(rèn)證規(guī)則保存在 apollo 中的 key 的后綴
degrade.key.suffix degrade 熔斷規(guī)則保存在 apollo 中的 key 的后綴
flow.key.suffix flow 限流規(guī)則保存在 apollo 中的 key 的后綴
param.key.suffix param_flow 參數(shù)限流規(guī)則保存在 apollo 中的 key 的后綴
system.key.suffix system 系統(tǒng)限流規(guī)則保存在 apollo 中的 key 的后綴
auth.username sentinel sentinel 控制臺(tái)的登錄用戶名
auth.password sentinel sentinel 控制臺(tái)的登錄密碼
server.port 8080 sentinel 控制臺(tái)的啟動(dòng)端口

Apollo 配置

創(chuàng)建用于保存 sentinel 的項(xiàng)目

  1. 點(diǎn)擊創(chuàng)建項(xiàng)目按鈕


  2. 輸入項(xiàng)目信息


    1. 應(yīng)用 ID 對(duì)應(yīng) 上面表格中的 app.id
    2. 應(yīng)用負(fù)責(zé)人 對(duì)應(yīng) 上面表格中的 modify.userrelease.user
  3. 創(chuàng)建一個(gè)公共命名空間

    1. 點(diǎn)擊右下角添加 Namespace 按鈕


    2. 創(chuàng)建 Namespace


      1. 名稱對(duì)應(yīng)上面表格中的 namespace.name售睹,注意名稱是要包含部門名的桩警,這里脫敏了
      2. 類型一定要選擇 public ,原因后面會(huì)說(shuō)
  4. 發(fā)布 Namespace


    1. 私有的空間是不能被繼承的昌妹,application 沒有用捶枢,可以刪除
      1. 這里的用意是我們獨(dú)立出一個(gè)單獨(dú)的用于保存規(guī)則的 apollo 應(yīng)用,因?yàn)槭枪驳姆裳拢云渌黙pollo 應(yīng)用可以繼承烂叔,這樣對(duì)于已經(jīng)集成 apollo 的項(xiàng)目來(lái)說(shuō),改動(dòng)最小
      2. 注意紅色的提示固歪,我們建的公共空間要首先發(fā)布一次蒜鸡,否則 api 無(wú)法訪問(wèn)到
  5. 創(chuàng)建此項(xiàng)目的開放平臺(tái)授權(quán)

    1. 點(diǎn)擊右上角的開放平臺(tái)授權(quán)管理

    2. 創(chuàng)建應(yīng)用


      1. 第三方應(yīng)用 ID 就是你上面創(chuàng)建的項(xiàng)目的 appId
      2. 第三方應(yīng)用名稱 隨便寫
    3. 賦權(quán)


      1. token 你點(diǎn)擊創(chuàng)建應(yīng)用后自動(dòng)生成的
      2. 被管理的 Appid 就是你上面創(chuàng)建的項(xiàng)目的 appId
      3. 授權(quán)類型 一定要選 App

spring boot 集成 sentinel

源碼地址

引入依賴

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>0.9.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-apollo</artifactId>
            <version>1.5.2</version>
        </dependency>

測(cè)試 controller

package cn.coder4j.study.example.sentinel;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author buhao
 * @version TestController.java, v 0.1 2019-09-19 20:53 buhao
 */
@RequestMapping("/test")
@Controller
public class TestController {

    /**
     * 沒有注解通過(guò)自適應(yīng)的限流
     * @return
     */
    @GetMapping("/flowRule")
    @ResponseBody
    public String flowRule(){
        return "success";
    }

    /**
     * 通過(guò)手動(dòng)注解的限流
     * @return
     */
    @GetMapping("/flowRuleWithAnno")
    @ResponseBody
    @SentinelResource("flowRuleWithAnno")
    public String flowRuleWithAnno(){
        return "success";
    }

    /**
     * 參數(shù)限流規(guī)則測(cè)試
     * @param param
     * @return
     */
    @GetMapping("/paramFlowRule")
    @ResponseBody
    @SentinelResource("paramFlowRule")
    public String paramFlowRule(String param){
        return "success";
    }

    /**
     * 熔斷規(guī)則測(cè)試
     * @return
     */
    @GetMapping("/degradeRule")
    @ResponseBody
    @SentinelResource("degradeRule")
    public String degradeRule(){
        throw new RuntimeException("服務(wù)器異常");
    }
}

配置 application.yml

apollo:
  bootstrap:
    enabled: true # 開啟 apollo
  meta: xxx       # 指定 apollo 注冊(cè)地址
app:
  id: sentinel-apollo  # 指定規(guī)則項(xiàng)目在 apollo 的app.id,要與 sentinel 控制臺(tái)啟動(dòng)參數(shù)一致
spring:
  application:
    name: study-sentinel-example  # 應(yīng)用名稱牢裳,不同項(xiàng)目要唯一逢防,會(huì)把他做為規(guī)則 Key 的前綴
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8989  # sentinel 控制臺(tái)的地址
      datasource:
        ds1:
          apollo:
            namespace-name: {部門名}.sentinel-rule  # 保存規(guī)則的 apollo 應(yīng)用的公共 namespace, 要與 sentinel 控制臺(tái)啟動(dòng)參數(shù)一致
            rule-type: flow   # 指定該數(shù)據(jù)源是限流規(guī)則
            flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds1.apollo.rule-type} # 指定該規(guī)則在 apollo 應(yīng)用中 key 名稱
        ds2:
          apollo:
            namespace-name: {部門名}.sentinel-rule
            rule-type: degrade # 指定該數(shù)據(jù)源是熔斷規(guī)則
            flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds2.apollo.rule-type} # 指定該規(guī)則在 apollo 應(yīng)用中 key 名稱
        ds3:
          apollo:
            namespace-name: {部門名}.sentinel-rule
            rule-type: param_flow # 指定該數(shù)據(jù)源是參數(shù)限流規(guī)則
            flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds3.apollo.rule-type} # 指定該規(guī)則在 apollo 應(yīng)用中 key 名稱
        ds4:
          apollo:
            namespace-name: {部門名}.sentinel-rule
            rule-type: system  # 指定該數(shù)據(jù)源是系統(tǒng)限流規(guī)則
            flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds4.apollo.rule-type} # 指定該規(guī)則在 apollo 應(yīng)用中 key 名稱
        ds5:
          apollo:
            namespace-name: {部門名}.sentinel-rule
            rule-type: authority # 指定該數(shù)據(jù)源是認(rèn)證限流(黑白名單)規(guī)則
            flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds5.apollo.rule-type} # 指定該規(guī)則在 apollo 應(yīng)用中 key 名稱

sentinel 控制臺(tái)配置

  1. 第一次啟動(dòng)時(shí) sentinel 是沒有應(yīng)用數(shù)據(jù)蒲讯,只要請(qǐng)求幾次你應(yīng)用的接口就可以了


  2. 請(qǐng)求之后可以看到我們的應(yīng)用在右側(cè)列表了


  3. 首先點(diǎn)擊簇點(diǎn)監(jiān)控忘朝,如果是空白的話說(shuō)明,接口還沒有被請(qǐng)求過(guò)判帮,通過(guò)上面提供的 jmeter 腳本局嘁,可以快速訪問(wèn)所有接口溉箕,訪問(wèn)后如下圖所示


    1. 可以看到除了我們手動(dòng)通過(guò)注解定義的資源名,還多了一些是通過(guò)我們的 controller 路徑的資源名悦昵,這些都是我們客戶端集成 spring-cloud-starter-alibaba-sentinel 包后约巷,自動(dòng)適配的。這兩種其實(shí)在使用上有區(qū)別的
      1. 自動(dòng)適配的限流后會(huì)返回 Blocked by Sentinel (flow limiting)
      2. 通過(guò)注解的是會(huì)拋出 UndeclaredThrowableException 異常旱捧,我們可以通過(guò) 文章 說(shuō)的方法轉(zhuǎn)成我們想的限流異常處理独郎。
    2. 右邊的操作就是添加各種規(guī)則,這里修改后會(huì)實(shí)時(shí)同步到客戶端并同步保存到 apollo

jmeter 配置

jmeter 是用于測(cè)試與驗(yàn)證規(guī)則使用的枚赡,因?yàn)榭梢栽O(shè)置線程數(shù)氓癌,所以可以很好的測(cè)試限流情況。測(cè)試腳本下載

  1. 線程組要把線程設(shè)置成 100贫橙,方便后面的統(tǒng)計(jì)贪婉,另外為了在一秒內(nèi)執(zhí)行完,Ramp-Up 時(shí)間設(shè)為0


  2. 請(qǐng)求默認(rèn)值就是填寫你本地的啟的測(cè)試項(xiàng)目的地址


  3. xx 規(guī)則填寫測(cè)試接口地址卢肃,參數(shù)限流因?yàn)橐鰧?duì)照實(shí)驗(yàn)所以寫了兩個(gè)


  4. 查看結(jié)果樹可以看到你每次請(qǐng)求的內(nèi)容與結(jié)果


  5. 可以看到上張圖片內(nèi)有紅色的有綠色的疲迂,紅色說(shuō)明斷言失敗,綠色說(shuō)明斷言成功莫湘,斷言的內(nèi)容就是包含 success


  6. 聚合統(tǒng)計(jì)尤蒿,這個(gè)可以統(tǒng)計(jì)出100個(gè)線程請(qǐng)求后的總體結(jié)果,我們只要看 Error% 的失敗率就可以了幅垮。圖中可以看到除了熔斷限流腰池,其它限流失敗率是 0


測(cè)試步驟

  1. 在簇點(diǎn)鏈路中找到 /test/flowRule,并點(diǎn)擊流控按鈕

  2. 單機(jī)閾值填入 10忙芒,點(diǎn)擊新增


  3. 新增后會(huì)跳轉(zhuǎn)到流程規(guī)則頁(yè)面


  4. 運(yùn)行jemter示弓,可以看到失敗率為90%,這代表你的限流成功了


    1. 上面說(shuō)了失敗是因?yàn)閿嘌詻]有成功呵萨,也就是說(shuō)沒有返回 success奏属,那他現(xiàn)在返回的是什么呢?

    2. 察看結(jié)果樹潮峦,隨便找一條紅包的記錄囱皿,看響應(yīng)數(shù)量


    3. 可以看到返回的是 "Blocked by Sentinel (flow limiting)",這個(gè)就是集成后配置的限流頁(yè)面的返回值跑杭,可以通過(guò) spring.cloud.sentinel.servlet.block-page 指定成你自己的頁(yè)面

  5. 另外打開 apollo 可以看到铆帽,多了一個(gè)規(guī)則咆耿,這就是你剛剛添加的限流規(guī)則


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末德谅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子萨螺,更是在濱河造成了極大的恐慌窄做,老刑警劉巖愧驱,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異椭盏,居然都是意外死亡组砚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門掏颊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)糟红,“玉大人,你說(shuō)我怎么就攤上這事乌叶∨璩ィ” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵准浴,是天一觀的道長(zhǎng)事扭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)乐横,這世上最難降的妖魔是什么求橄? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮葡公,結(jié)果婚禮上罐农,老公的妹妹穿的比我還像新娘。我一直安慰自己催什,他們只是感情好啃匿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛆楞,像睡著了一般溯乒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豹爹,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天裆悄,我揣著相機(jī)與錄音,去河邊找鬼臂聋。 笑死光稼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的孩等。 我是一名探鬼主播艾君,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肄方!你這毒婦竟也來(lái)了冰垄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤权她,失蹤者是張志新(化名)和其女友劉穎虹茶,沒想到半個(gè)月后逝薪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝴罪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年董济,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片要门。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡虏肾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欢搜,到底是詐尸還是另有隱情询微,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布狂巢,位于F島的核電站撑毛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏唧领。R本人自食惡果不足惜藻雌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望斩个。 院中可真熱鬧胯杭,春花似錦、人聲如沸受啥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滚局。三九已至居暖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間藤肢,已是汗流浹背太闺。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘁圈,地道東北人省骂。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像最住,于是被迫代替她去往敵國(guó)和親钞澳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容