Sentinel(十五)之在生产环境中使用 Sentinel
轉(zhuǎn)載自??在生產(chǎn)環(huán)境中使用 Sentinel
引言
Sentinel 目前已可用于生產(chǎn)環(huán)境,除了阿里巴巴以外,也有很多企業(yè)在生產(chǎn)環(huán)境中廣泛使用 Sentinel。
生產(chǎn)環(huán)境的 Sentinel Dashboard 需要具備下面幾個特性:
- 規(guī)則管理及推送,集中管理和推送規(guī)則。sentinel-core?提供 API 和擴展接口來接收信息。開發(fā)者需要根據(jù)自己的環(huán)境,選取一個可靠的推送規(guī)則方式;同時,規(guī)則最好在控制臺中集中管理。
- 監(jiān)控,支持可靠、快速的實時監(jiān)控和歷史監(jiān)控數(shù)據(jù)查詢。sentinel-core?記錄秒級的資源運行情況,并且提供 API 來拉取資源運行信息。當(dāng)機器大于一臺以上的時候,可以通過 Dashboard 來拉取,聚合,并且存儲這些信息。這個時候,Dashboard 需要有一個存儲媒介,來存儲歷史運行情況。
- 權(quán)限控制,區(qū)分用戶角色,來進行操作。生產(chǎn)環(huán)境下的權(quán)限控制是非常重要的,理論上只有管理員等高級用戶才有權(quán)限去修改應(yīng)用的規(guī)則。
由于開發(fā)者有各自不一樣的環(huán)境和需求,我們會對“規(guī)則管理和推送”,“監(jiān)控”這兩個方面給出建議以及最佳實踐;對于權(quán)限控制,由于每個開發(fā)者的環(huán)境都不一樣,我們在最佳實踐中僅僅使用了簡單的認(rèn)證。開發(fā)者可以依循自己的需求,結(jié)合實際生產(chǎn)環(huán)境,選擇最適合自己的方式。
同時我們也在云上提供?企業(yè)級的 Sentinel 控制臺 (AHAS Sentinel),歡迎大家體驗。
規(guī)則管理及推送
一般來說,規(guī)則的推送有下面三種模式:
| 原始模式 | API 將規(guī)則推送至客戶端并直接更新到內(nèi)存中,擴展寫數(shù)據(jù)源(WritableDataSource) | 簡單,無任何依賴 | 不保證一致性;規(guī)則保存在內(nèi)存中,重啟即消失。嚴(yán)重不建議用于生產(chǎn)環(huán)境 |
| Pull 模式 | 擴展寫數(shù)據(jù)源(WritableDataSource), 客戶端主動向某個規(guī)則管理中心定期輪詢拉取規(guī)則,這個規(guī)則中心可以是 RDBMS、文件 等 | 簡單,無任何依賴;規(guī)則持久化 | 不保證一致性;實時性不保證,拉取過于頻繁也可能會有性能問題。 |
| Push 模式 | 擴展讀數(shù)據(jù)源(ReadableDataSource),規(guī)則中心統(tǒng)一推送,客戶端通過注冊監(jiān)聽器的方式時刻監(jiān)聽變化,比如使用 Nacos、Zookeeper 等配置中心。這種方式有更好的實時性和一致性保證。生產(chǎn)環(huán)境下一般采用 push 模式的數(shù)據(jù)源。 | 規(guī)則持久化;一致性;快速 | 引入第三方依賴 |
原始模式
如果不做任何修改,Dashboard 的推送規(guī)則方式是通過 API 將規(guī)則推送至客戶端并直接更新到內(nèi)存中:
?
這種做法的好處是簡單,無依賴;壞處是應(yīng)用重啟規(guī)則就會消失,僅用于簡單測試,不能用于生產(chǎn)環(huán)境。
Pull模式
pull 模式的數(shù)據(jù)源(如本地文件、RDBMS 等)一般是可寫入的。使用時需要在客戶端注冊數(shù)據(jù)源:將對應(yīng)的讀數(shù)據(jù)源注冊至對應(yīng)的 RuleManager,將寫數(shù)據(jù)源注冊至 transport 的?WritableDataSourceRegistry?中。以本地文件數(shù)據(jù)源為例:
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>>() {}));// 將可讀數(shù)據(jù)源注冊至 FlowRuleManager.FlowRuleManager.register2Property(ds.getProperty());WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);// 將可寫數(shù)據(jù)源注冊至 transport 模塊的 WritableDataSourceRegistry 中.// 這樣收到控制臺推送的規(guī)則時,Sentinel 會先更新到內(nèi)存,然后將規(guī)則寫入到文件中.WritableDataSourceRegistry.registerFlowDataSource(wds);}private <T> String encodeJson(T t) {return JSON.toJSONString(t);} }本地文件數(shù)據(jù)源會定時輪詢文件的變更,讀取規(guī)則。這樣我們既可以在應(yīng)用本地直接修改文件來更新規(guī)則,也可以通過 Sentinel 控制臺推送規(guī)則。以本地文件數(shù)據(jù)源為例,推送過程如下圖所示:
?
首先 Sentinel 控制臺通過 API 將規(guī)則推送至客戶端并更新到內(nèi)存中,接著注冊的寫數(shù)據(jù)源會將新的規(guī)則保存到本地的文件中。使用 pull 模式的數(shù)據(jù)源時一般不需要對 Sentinel 控制臺進行改造。
這種實現(xiàn)方法好處是簡單,不引入新的依賴,壞處是無法保證監(jiān)控數(shù)據(jù)的一致性。
Push模式
生產(chǎn)環(huán)境下一般更常用的是 push 模式的數(shù)據(jù)源。對于 push 模式的數(shù)據(jù)源,如遠(yuǎn)程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不應(yīng)由 Sentinel 客戶端進行,而應(yīng)該經(jīng)控制臺統(tǒng)一進行管理,直接進行推送,數(shù)據(jù)源僅負(fù)責(zé)獲取配置中心推送的配置并更新到本地。因此推送規(guī)則正確做法應(yīng)該是?配置中心控制臺/Sentinel 控制臺 → 配置中心 → Sentinel 數(shù)據(jù)源 → Sentinel,而不是經(jīng) Sentinel 數(shù)據(jù)源推送至配置中心。這樣的流程就非常清晰了:
我們提供了 ZooKeeper, Apollo, Nacos 等的動態(tài)數(shù)據(jù)源實現(xiàn)。以 ZooKeeper 為例子,如果要使用第三方的配置中心作為配置管理,您需要做下面的幾件事情:
從 Sentinel 1.4.0 開始,Sentinel 控制臺提供?DynamicRulePublisher?和?DynamicRuleProvider?接口用于實現(xiàn)應(yīng)用維度的規(guī)則推送和拉取,并提供了相關(guān)的示例。Sentinel 提供應(yīng)用維度規(guī)則推送的示例頁面(/v2/flow),用戶改造控制臺對接配置中心后可直接通過 v2 頁面推送規(guī)則至配置中心。改造詳情可參考?應(yīng)用維度規(guī)則推送示例。
部署多個控制臺實例時,通常需要將規(guī)則存至 DB 中,規(guī)則變更后同步向配置中心推送規(guī)則。
監(jiān)控
Sentinel 會記錄資源訪問的秒級數(shù)據(jù)(若沒有訪問則不進行記錄)并保存在本地日志中,具體格式請見?秒級監(jiān)控日志文檔。Sentinel 控制臺可以通過?Sentinel 客戶端預(yù)留的 HTTP API?從秒級監(jiān)控日志中拉取監(jiān)控數(shù)據(jù),并進行聚合。
目前 Sentinel 控制臺中監(jiān)控數(shù)據(jù)聚合后直接存在內(nèi)存中,未進行持久化,且僅保留最近 5 分鐘的監(jiān)控數(shù)據(jù)。若需要監(jiān)控數(shù)據(jù)持久化的功能,可以自行擴展實現(xiàn)?MetricsRepository?接口(0.2.0 版本),然后注冊成 Spring Bean 并在相應(yīng)位置通過?@Qualifier注解指定對應(yīng)的 bean name 即可。MetricsRepository?接口定義了以下功能:
- save?與?saveAll:存儲對應(yīng)的監(jiān)控數(shù)據(jù)
- queryByAppAndResourceBetween:查詢某段時間內(nèi)的某個應(yīng)用的某個資源的監(jiān)控數(shù)據(jù)
- listResourcesOfApp:查詢某個應(yīng)用下的所有資源
其中默認(rèn)的監(jiān)控數(shù)據(jù)類型為?MetricEntity,包含應(yīng)用名稱、時間戳、資源名稱、異常數(shù)、請求通過數(shù)、請求拒絕數(shù)、平均響應(yīng)時間等信息。對于監(jiān)控數(shù)據(jù)的存儲,用戶需要根據(jù)自己的存儲精度,來考慮如何存儲這些監(jiān)控數(shù)據(jù)。為了更好地支撐大規(guī)模的集群,生產(chǎn)環(huán)境通常需要部署多個控制臺實例,通常需要仔細(xì)設(shè)計下監(jiān)控分片拉取和寫入策略。
同時用戶可以自行進行擴展,適配 Grafana 等可視化平臺,以便將監(jiān)控數(shù)據(jù)更好地進行可視化。
最佳實踐
我們提供了一個云上版本的控制臺。通過這個版本,開發(fā)者可以看到一個完整的生產(chǎn)環(huán)境的控制臺的功能全集。它主要包括:
- 可靠的實時監(jiān)控和歷史監(jiān)控數(shù)據(jù)查詢:該控制臺將會示范 Sentinel 的監(jiān)控能做成什么樣子,包括實時監(jiān)控、集群熱力圖等,請參考“監(jiān)控”以及“簇點鏈路”模塊。
- 動態(tài)規(guī)則管理/推送:該控制臺將會示范如何做一個合理的 push 結(jié)構(gòu)的實現(xiàn),請參考“規(guī)則”模塊。
- 機器列表:如何利用 Sentinel 上報的機器信息進行管理,請參考“機器列表”模塊。
- 全自動托管的集群流控與 Service Mesh 流控能力
詳情請參考?AHAS Sentinel 控制臺文檔來參考如何在生產(chǎn)環(huán)境中使用控制臺。
同類組件功能對比
| 隔離策略 | 信號量隔離(并發(fā)控制) | 線程池隔離/信號量隔離 | 信號量隔離 |
| 熔斷降級策略 | 基于慢調(diào)用比例、異常比例、異常數(shù) | 基于異常比例 | 基于異常比例、響應(yīng)時間 |
| 實時統(tǒng)計實現(xiàn) | 滑動窗口(LeapArray) | 滑動窗口(基于 RxJava) | Ring Bit Buffer |
| 動態(tài)規(guī)則配置 | 支持近十種動態(tài)數(shù)據(jù)源 | 支持多種數(shù)據(jù)源 | 有限支持 |
| 擴展性 | 多個擴展點 | 插件的形式 | 接口的形式 |
| 基于注解的支持 | 支持 | 支持 | 支持 |
| 單機限流 | 基于 QPS,支持基于調(diào)用關(guān)系的限流 | 有限的支持 | Rate Limiter |
| 集群流控 | 支持 | 不支持 | 不支持 |
| 流量整形 | 支持預(yù)熱模式與勻速排隊控制效果 | 不支持 | 簡單的 Rate Limiter 模式 |
| 系統(tǒng)自適應(yīng)保護 | 支持 | 不支持 | 不支持 |
| 熱點識別/防護 | 支持 | 不支持 | 不支持 |
| 多語言支持 | Java/Go/C++ | Java | Java |
| Service Mesh 支持 | 支持 Envoy/Istio | 不支持 | 不支持 |
| 控制臺 | 提供開箱即用的控制臺,可配置規(guī)則、實時監(jiān)控、機器發(fā)現(xiàn)等 | 簡單的監(jiān)控查看 | 不提供控制臺,可對接其它監(jiān)控系統(tǒng) |
其它
Awesome Sentinel?里記錄非常多的社區(qū)用戶的一些擴展和解決方案,也歡迎大家將一些比較好的擴展實現(xiàn)添加進來。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Sentinel(十五)之在生产环境中使用 Sentinel的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Sentinel(十三)之动态规则扩展
- 下一篇: Sentinel(十六)之AHAS Se