阿里巴巴提供的控制檯只是用於演示 Sentinel 的基本能力和工做流程,並無依賴生產環境中所必需的組件,好比持久化的後端數據庫、可靠的配置中心等。目前 Sentinel 採用內存態的方式存儲監控和規則數據,監控最長存儲時間爲 5 分鐘,控制檯重啓後數據丟失。前端
這裏推薦一下阿里雲的官方版,AHAS Sentinel 控制檯 是 Sentinel 控制檯的阿里雲上版本,提供企業級的控制檯服務,包括:java
免費版,能夠提供 5 個節點的免費額度。開通專業版便可享受不限量節點額度。python
專業版沒有實例鏈接限制,開通後天天前5個限流降級節點不計費,超出部分按3元/天/實例收取相應的費用。git
官方文檔也提供了思路,若須要監控數據持久化的功能,能夠自行擴展實現 MetricsRepository 接口(0.2.0 版本),而後註冊成 Spring Bean 並在相應位置經過 @Qualifier 註解指定對應的 bean name 便可。MetricsRepository 接口定義瞭如下功能:github
save 與 saveAll:存儲對應的監控數據spring
queryByAppAndResourceBetween:查詢某段時間內的某個應用的某個資源的監控數據docker
listResourcesOfApp:查詢某個應用下的全部資源數據庫
其中默認的監控數據類型爲 MetricEntity,包含應用名稱、時間戳、資源名稱、異常數、請求經過數、請求拒絕數、平均響應時間等信息。後端
對於監控數據的存儲,用戶須要根據本身的存儲精度,來考慮如何存儲這些監控數據。顯然咱們要使用目前最流行的時序數據庫InfluxDB
解決方案,不要問什麼?閉眼享受就能夠了。併發
InfluxDB
是一個開源分佈式時序、事件和指標數據庫。使用 Go 語言編寫,無需外部依賴。
應用:性能監控,應用程序指標,物聯網傳感器數據和實時分析等的後端存儲。
強大的類SQL語法
內置http支持,使用http讀寫
基於事件:它支持任意的事件數據
無結構(無模式):能夠是任意數量的列
可度量性:你能夠實時對大量數據進行計算
持續高併發寫入、無更新、數據壓縮存儲、低查詢延時
支持min, max, sum, count, mean, median 等一系列函數
基於時間序列,支持與時間有關的相關函數(如最大,最小,求和等)
首先你得先有個 Influxdb 數據庫,建議使用 Docker 方式安裝,更多能夠參考文末連接。
須要注意的是,從1.1.0版開始不推薦使用管理員界面,並將在1.3.0版中刪除。默認狀況下禁用。若是須要,仍能夠經過設置以下環境變量來啓用它。
如下端口很重要,並由InfluxDB
使用。
chronograf
經過該命令, 生成默認配置文件:
docker run --rm influxdb influxd config > influxdb.conf
建立並運行容器:
docker run -d \ -p 8086:8086 \ -p 8083:8083 \ -e INFLUXDB_ADMIN_ENABLED=true \ -v $PWD/data:/var/lib/influxdb/ \ -v $PWD/config/influxdb.conf:/etc/influxdb/influxdb.conf:ro \ --name influx \ influxdb -config /etc/influxdb/influxdb.conf
生產環境必定要開啓權限驗證,修改 influxdb.conf 配置:
[http] enabled = true bind-address = ":8086" auth-enabled = true # 鑑權
建立用戶:
# 進入容器 docker exec -it influx /bin/sh # 鏈接 influx # 建立用戶 CREATE USER admin with PASSWORD 'admin' WITH ALL PRIVILEGES
退出從新登陸:
# 用戶密碼登陸 influx -username admin -password admin # 建立數據庫 CREATE DATABASE sentinel_log
pom.xml引入 influxdb 官方開源工具包:
<dependency> <groupId>org.influxdb</groupId> <artifactId>influxdb-java</artifactId> <version>2.15</version> </dependency>
配置文件引入:
# 自行替換 API 地址:端口 spring.influx.url=http://127.0.0.1:8086 spring.influx.user=admin spring.influx.password=admin spring.influx.database=sentinel_log
配置數據源:
/** * InfluxDb 配置 * 建立者 爪哇筆記 * 網址 https://blog.52itstyle.vip */ @Configuration public class InfluxDbConfig { @Value("${spring.influx.url:''}") private String influxDBUrl; @Value("${spring.influx.user:''}") private String userName; @Value("${spring.influx.password:''}") private String password; @Value("${spring.influx.database:''}") private String database; @Bean public InfluxDB influxDB(){ InfluxDB influxDB = InfluxDBFactory.connect(influxDBUrl, userName, password); try { /** * 異步插入: * enableBatch這裏第一個是point的個數,第二個是時間,單位毫秒 * point的個數和時間是聯合使用的,若是滿100條或者2000毫秒 * 知足任何一個條件就會發送一次寫的請求。 */ influxDB.setDatabase(database) .enableBatch(100,2000, TimeUnit.MILLISECONDS); } catch (Exception e) { e.printStackTrace(); } finally { influxDB.setRetentionPolicy("autogen"); } influxDB.setLogLevel(InfluxDB.LogLevel.BASIC); return influxDB; } }
實現 MetricsRepository 接口,重寫實現:
/** * 數據CURD * 建立者 爪哇筆記 * 網址 https://blog.52itstyle.vip */ @Component("inInfluxdbMetricsRepository") public class InInfluxdbMetricsRepository implements MetricsRepository<MetricEntity> { @Autowired public InfluxDB influxDB; @Override public synchronized void save(MetricEntity metric) { //省略代碼,太長了,參考內存寫法,參考 saveAll 這裏是單條插入 } @Override public synchronized void saveAll(Iterable<MetricEntity> metrics) { if (metrics == null) { return; } BatchPoints batchPoints = BatchPoints.builder() .tag("async", "true") .consistency(InfluxDB.ConsistencyLevel.ALL) .build(); metrics.forEach(metric->{ Point point = Point .measurement("sentinelInfo") //這裏使用微妙、若是還有覆蓋數據就使用納秒,保證 time 和 tag 惟一就能夠 .time(System.currentTimeMillis(), TimeUnit.MICROSECONDS) .tag("app",metric.getApp())//tag 數據走索引 .addField("gmtCreate", metric.getGmtCreate().getTime()) .addField("gmtModified", metric.getGmtModified().getTime()) .addField("timestamp", metric.getTimestamp().getTime()) .addField("resource", metric.getResource()) .addField("passQps", metric.getPassQps()) .addField("successQps", metric.getSuccessQps()) .addField("blockQps", metric.getBlockQps()) .addField("exceptionQps", metric.getExceptionQps()) .addField("rt", metric.getRt()) .addField("count", metric.getCount()) .addField("resourceCode", metric.getResourceCode()) .build(); batchPoints.point(point); }); //批量插入 influxDB.write(batchPoints); } @Override public synchronized List<MetricEntity> queryByAppAndResourceBetween(String app, String resource, long startTime, long endTime) { //省略代碼,太長了,參考內存寫法 } @Override public synchronized List<String> listResourcesOfApp(String app) { //省略代碼,太長了,參考內存寫法 } }
分別修改 MetricFetcher
和 MetricController
中 metricStore
的注入方式,使用 Influxdb
實現:
/** * 注入 * 建立者 爪哇筆記 * 網址 https://blog.52itstyle.vip */ @Autowired @Qualifier("inInfluxdbMetricsRepository") private MetricsRepository<MetricEntity> metricStore;
配置完成後,咱們重啓控制檯,而後訪問客戶端項目,若是控制檯打印如下數據,說明配置成功:
2019-09-21 19:47:25 [sentinel-dashboard-metrics-fetchWorker-thread-2] INFO okhttp3.OkHttpClient - --> POST http://118.190.247.102:8086/write?db=sentinel_log&precision=n&consistency=all (486-byte body) 2019-09-21 19:47:25 [sentinel-dashboard-metrics-fetchWorker-thread-2] INFO okhttp3.OkHttpClient - <-- 204 No Content http://118.190.247.102:8086/write?db=sentinel_log&precision=n&consistency=all (46ms, 0-byte body)
多訪問幾回客戶端項目,而後登錄控制檯查看,出現如下效果,說明改形成功:
注意事項:
官方前端並無實現按照時間範圍的查詢搜索,須要自行實現
官方控制檯實時監控默認查詢的是最近一分鐘的熱點資源排行,見方法 listResourcesOfApp
官方控制檯實時監控右側 Table 默認查詢的是最近五分鐘的熱點訪問詳情,見方法 queryTopResourceMetric
對於官方五分鐘的閹割版,時序數據庫實現的流控數據存儲,對於生產環境仍是頗有幫助的,好比實時數據分析,熱點資源、監控預警等等。小夥伴們還能夠根據實際生產需求結合Chronograf
、Grafana
作出更炫酷的大屏監控。
https://gitee.com/52itstyle/sentinel-dashboard
https://blog.52itstyle.vip/archives/4460/
https://hub.docker.com/_/influxdb
https://hub.docker.com/_/chronograf
https://github.com/influxdata/influxdb-java
https://github.com/influxdata/influxdb-python
https://help.aliyun.com/document_detail/97578.htm