在 sentinel 的控制檯設置的規則信息默認都是存在內存當中的。因此不管你是重啓了 sentinel 的客戶端仍是 sentinel 的控制檯。你所設置的規則都會丟失。若是想要 sentinel 在線上環境使用,要麼花錢用阿里雲上的付費版本,要麼本身去實現規則的持久化,若是你或你所在的公司不差錢,那麼關掉這篇文章,直接用付費版吧,省掉了一大堆坑要踩。或者你是一個特立獨行的人,那麼咱們接着往下說。
首先說一下寫這篇文章的緣由,由於真得在與 apllo 集成時,踩坑踩到懷疑人生。另外一點是,找了一大堆關於集成的 apollo 的文章,都清一色的都是仿照官方給的限流規則的 DEMO 作的。 可是 sentinel 規則還有熔斷規則、參數限流、系統限流、黑白名單等不少規則,每一個規則還有細節上的不一致,這些都沒有提,還有一些客戶端的坑就更沒有了。踩了這麼多坑,有了一點心得與體會,梳理與此,但願能幫助到讀者。java
由於修改內容過多,本文不會詳述,下面的截圖是全部修改內容,而且由於寫這篇文章時,1.7版本在 master 開發,有大量快照版本。因此是切到當前穩定的 1.6 分支進行修改的。我已經 fork sentinel 到個人 github,下面是修改的內容 地址git
添加與實現了全部的規則的 Provider 與 Publisher 的配置拉取的與推送。github
規則在控制檯的操做 controller 進行大量改造。web
最後一點也是最坑的修改了大量的 xxEntity 類,這些類是規則的實體類,自己沒什麼,源碼是直接 json 化保存的,可是用於客戶端集成的 spring-cloud-alibaba 使用了 json 校驗,若是 apollo 保存的 json 與客戶端的實體類有一丁點不同就報 convert 0 rules but there are 1 rules from datasource . RuleCLass: FlowRule 。 是否是以爲很摸不着頭腦,這報錯跟 json 格式轉換錯誤有什麼,下面是 spring-cloud-alibaba json 轉換的代碼。spring
寫這段代碼的老哥,把這個異常吃了,並補上了一個 // won't be happen 的註釋,你能理解我當時被這個報錯坑的死去活來,後來發現是這裏的問題嗎?後來在 github 上找到兩個一樣的問題問題1、問題2,按照方法把 xxEntity 中用不到的字段所有加上 @JSONField(serialize = false) 解決。json
添加的配置在下面bootstrap
配置名稱 | 是否必填 | 默認值 | 做用 |
---|---|---|---|
env | 否 | DEV | 指定 apollo 使用的環境 |
app.id | 否 | sentinel-apollo | 指定保存 sentinel 規則的 apollo 應用 ID |
cluster.name | 否 | default | 指定保存 sentinel 使用的 apollo 集羣 |
namespace.name | 否 | application | 指定保存 sentinel 使用的 apollo 命名空間 |
modify.user | 是 | apollo 控制檯顯示的修改人帳號,此帳號務必要有此應用的權限 | |
modify.comment | 否 | modify by sentinel-dashboard | apollo 控制檯顯示的修改備註 |
release.user | 是 | apollo 控制檯顯示的發佈人帳號,此帳號務必要有此應用的權限 | |
release.comment | 否 | release by sentinel-dashboard | apollo 控制檯顯示的發佈備註 |
apollo.portal.url | 是 | apollo 控制檯的地址 | |
apollo.application.token | 是 | 指定保存 sentinel 規則的 apollo 應用 openapi 的 token | |
authority.key.suffix | 否 | authority | 認證規則保存在 apollo 中的 key 的後綴 |
degrade.key.suffix | 否 | degrade | 熔斷規則保存在 apollo 中的 key 的後綴 |
flow.key.suffix | 否 | flow | 限流規則保存在 apollo 中的 key 的後綴 |
param.key.suffix | 否 | param_flow | 參數限流規則保存在 apollo 中的 key 的後綴 |
system.key.suffix | 否 | system | 系統限流規則保存在 apollo 中的 key 的後綴 |
auth.username | 否 | sentinel | sentinel 控制檯的登陸用戶名 |
auth.password | 否 | sentinel | sentinel 控制檯的登陸密碼 |
server.port | 否 | 8080 | sentinel 控制檯的啓動端口 |
源碼地址segmentfault
<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>
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 { /** * 沒有註解經過自適應的限流 * @return */ @GetMapping("/flowRule") @ResponseBody public String flowRule(){ return "success"; } /** * 經過手動註解的限流 * @return */ @GetMapping("/flowRuleWithAnno") @ResponseBody @SentinelResource("flowRuleWithAnno") public String flowRuleWithAnno(){ return "success"; } /** * 參數限流規則測試 * @param param * @return */ @GetMapping("/paramFlowRule") @ResponseBody @SentinelResource("paramFlowRule") public String paramFlowRule(String param){ return "success"; } /** * 熔斷規則測試 * @return */ @GetMapping("/degradeRule") @ResponseBody @SentinelResource("degradeRule") public String degradeRule(){ throw new RuntimeException("服務器異常"); } }
apollo: bootstrap: enabled: true # 開啓 apollo meta: xxx # 指定 apollo 註冊地址 app: id: sentinel-apollo # 指定規則項目在 apollo 的app.id,要與 sentinel 控制檯啓動參數一致 spring: application: name: study-sentinel-example # 應用名稱,不一樣項目要惟一,會把他作爲規則 Key 的前綴 cloud: sentinel: transport: dashboard: localhost:8989 # sentinel 控制檯的地址 datasource: ds1: apollo: namespace-name: {部門名}.sentinel-rule # 保存規則的 apollo 應用的公共 namespace, 要與 sentinel 控制檯啓動參數一致 rule-type: flow # 指定該數據源是限流規則 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds1.apollo.rule-type} # 指定該規則在 apollo 應用中 key 名稱 ds2: apollo: namespace-name: {部門名}.sentinel-rule rule-type: degrade # 指定該數據源是熔斷規則 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds2.apollo.rule-type} # 指定該規則在 apollo 應用中 key 名稱 ds3: apollo: namespace-name: {部門名}.sentinel-rule rule-type: param_flow # 指定該數據源是參數限流規則 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds3.apollo.rule-type} # 指定該規則在 apollo 應用中 key 名稱 ds4: apollo: namespace-name: {部門名}.sentinel-rule rule-type: system # 指定該數據源是系統限流規則 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds4.apollo.rule-type} # 指定該規則在 apollo 應用中 key 名稱 ds5: apollo: namespace-name: {部門名}.sentinel-rule rule-type: authority # 指定該數據源是認證限流(黑白名單)規則 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds5.apollo.rule-type} # 指定該規則在 apollo 應用中 key 名稱
jmeter 是用於測試與驗證規則使用的,由於能夠設置線程數,因此能夠很好的測試限流狀況。測試腳本下載api
線程組要把線程設置成 100,方便後面的統計,另外爲了在一秒內執行完,Ramp-Up 時間設爲0 服務器
請求默認值就是填寫你本地的啓的測試項目的地址
xx 規則填寫測試接口地址,參數限流由於要作對照實驗因此寫了兩個
查看結果樹能夠看到你每次請求的內容與結果
能夠看到上張圖片內有紅色的有綠色的,紅色說明斷言失敗,綠色說明斷言成功,斷言的內容就是包含 success
聚合統計,這個能夠統計出100個線程請求後的整體結果,咱們只要看 Error% 的失敗率就能夠了。圖中能夠看到除了熔斷限流,其它限流失敗率是 0
歡迎關注個人公衆號「KIWI的碎碎念」,也能夠收藏 個人博客