你只差这两步 | 将Sentinel 控制台应用于生产环境
這是圍繞 Sentinel 的使用場景、技術對比和實現、開發者實踐等維度推出的系列文章的第四篇。
- 第一篇回顧:
Dubbo 的流量防衛兵 | Sentinel如何通過限流實現服務的高可用性 -?傳送門
- 第二篇回顧:
RocketMQ 的保險絲| Sentinel 如何通過勻速請求和冷啟動來保障服務的穩定性 -?傳送門
- 第三篇回顧:
技術選型:Sentinel vs Hystrix -?傳送門
Sentinel 是阿里中間件團隊研發的面向分布式服務架構的輕量級高可用流量控制組件,于今年7月正式開源。Sentinel 主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助用戶提升服務的穩定性。
Sentinel 項目地址:
https://github.com/alibaba/Sentinel
Sentinel 控制臺作為 Sentinel 的一大利器,提供了多個維度的監控和規則配置功能。Sentinel 客戶端目前已可用于生產環境,但若希望在生產環境中使用 Sentinel 控制臺還需要進行一些改造。本文將介紹如何對 Sentinel 控制臺進行改造以便在生產環境中使用。
在生產環境中使用 Sentinel 控制臺只需要兩步改造:
動態規則數據源
Sentinel 的動態規則數據源用于從中讀取及寫入規則。從 0.2.0 版本開始,Sentinel 將動態規則數據源分為兩種類型:讀數據源(ReadableDataSource)和寫數據源(WritableDataSource):
- 讀數據源僅負責監聽或輪詢讀取遠程存儲的變更。
- 寫數據源僅負責將規則變更寫入到規則源中。
其中讀數據源常見的實現方式有:
- pull 模式:客戶端主動向某個規則管理中心定期輪詢拉取規則,這個規則中心可以是 RDBMS、文件 等。這樣做的方式是簡單,缺點是可能無法及時獲取變更,拉取過于頻繁也可能會有性能問題。
- push 模式:規則中心統一推送,客戶端通過注冊監聽器的方式時刻監聽變化,比如使用 Nacos、Zookeeper 等配置中心。這種方式有更好的實時性和一致性保證。
在實際的場景中,不同的存儲類型對應的數據源類型也不同。對于 push 模式的數據源,一般不支持寫入;而 pull 模式的數據源則是可寫的。
下面我們分別來分析一下它們結合 Sentinel 控制臺的使用場景,以及相應的需要改造的點。
| 原始情況
若應用未注冊任何數據源,直接從 Sentinel 控制臺推送規則的過程非常簡單:
Sentinel 控制臺通過 API 將規則推送至客戶端并直接更新到內存中。這種情況下應用重啟規則就會消失,僅用于簡單測試,不能用于生產環境。一般在生產環境中,我們需要在應用端配置規則數據源。
| pull 模式的數據源
pull 模式的數據源(如本地文件、RDBMS 等)一般是可寫入的。使用時需要在客戶端注冊數據源:將對應的讀數據源注冊至對應的 RuleManager,將寫數據源注冊至 transport 的?WritableDataSourceRegistry?中。以本地文件數據源為例:
public class FileDataSourceInit implements InitFunc {@Overridepublic void init() throws Exception {String flowRulePath = "xxx";ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));// 將可讀數據源注冊至 FlowRuleManager.FlowRuleManager.register2Property(ds.getProperty());WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);// 將可寫數據源注冊至 transport 模塊的 WritableDataSourceRegistry 中.// 這樣收到控制臺推送的規則時,Sentinel 會先更新到內存,然后將規則寫入到文件中.WritableDataSourceRegistry.registerFlowDataSource(wds);}private <T> String encodeJson(T t) {return JSON.toJSONString(t);} }本地文件數據源會定時輪詢文件的變更,讀取規則。這樣我們既可以在應用本地直接修改文件來更新規則,也可以通過 Sentinel 控制臺推送規則。以本地文件數據源為例,推送過程如下圖所示:
首先 Sentinel 控制臺通過 API 將規則推送至客戶端并更新到內存中,接著注冊的寫數據源會將新的規則保存到本地的文件中。使用 pull 模式的數據源時一般不需要對 Sentinel 控制臺進行改造。
| push 模式的數據源
對于 push 模式的數據源(如遠程配置中心),推送的操作不應由 Sentinel 數據源進行,而應該經控制臺進行推送,數據源僅負責獲取配置中心推送的配置并更新到本地。
假設寫入的操作也由數據源進行,那么 Sentinel 客戶端收到控制臺推送的規則后,將新的規則更新到內存中,同時將規則推送至遠程的配置中心。此時,數據源監聽到配置中心推送過來的新規則,又一次更新到內存中。也就是說應用在本地更新完規則并推送到遠程后,又要接收變更并更新一次,這樣顯然是不合理的。因此推送規則正確做法應該是?配置中心控制臺/Sentinel 控制臺 → 配置中心 → Sentinel 數據源 → Sentinel,而不是經 Sentinel 數據源推送至配置中心。這樣的流程就非常清晰了:
注意由于不同的生產環境可能使用不同的數據源,從 Sentinel 控制臺推送至配置中心的實現需要用戶自行改造。以 ZooKeeper 為例,我們可以按照如下步驟進行改造(假設推送維度為應用維度):
監控數據持久化
Sentinel 會記錄資源訪問的秒級數據(若沒有訪問則不進行記錄)并保存在本地日志中,具體格式請見?秒級監控日志文檔。Sentinel 控制臺通過?Sentinel 客戶端預留的 API?從秒級監控日志中拉取監控數據,并進行聚合。目前 Sentinel 控制臺中監控數據聚合后直接存在內存中,未進行持久化,且僅保留最近 5 分鐘的監控數據。若需要監控數據持久化的功能,可以自行擴展實現?MetricsRepository?接口(0.2.0 版本),然后注冊成 Spring Bean 并在相應位置通過?@Qualifier?注解指定對應的 bean name 即可。MetricsRepository?接口定義了以下功能:
- save?與?saveAll:存儲對應的監控數據
- queryByAppAndResourceBetween:查詢某段時間內的某個應用的某個資源的監控數據
- listResourcesOfApp:查詢某個應用下的所有資源
其中默認的監控數據類型為?MetricEntity,包含應用名稱、時間戳、資源名稱、異常數、請求通過數、請求 block 數、平均響應時間等信息。
同時用戶可以自行進行擴展,適配 Grafana 等可視化平臺,以便將監控數據更好地進行可視化。
其它
在生產環境中使用 Sentinel 控制臺還需要考慮以下問題:
- 權限控制:生產環境下的權限控制是非常重要的,理論上只有 AppOps 或管理員才有權限去修改對應應用的規則。Sentinel 控制臺不提供權限控制功能,需要開發者自行進行改造。
同時也可以到?Awesome Sentinel?去參考社區用戶的一些擴展和解決方案,也歡迎大家將一些比較好的擴展實現添加進來。
原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的你只差这两步 | 将Sentinel 控制台应用于生产环境的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 负载均衡SLB新功能介绍
- 下一篇: SLB访问日志分析:基于客户端来源和HT