摘要:是用于服務監(jiān)控以及服務降級基礎組件,主要為了解決調(diào)用外部接口的時候進行成功率,響應時間,指標的監(jiān)控,同時在成功率下降到預設的閾值以下的時候自動切斷外部接口的調(diào)用,外部接口成功率恢復后自動恢復請求。
meerkat 是用于服務監(jiān)控以及服務降級基礎組件,主要為了解決調(diào)用外部接口的時候進行成功率,響應時間,QPS指標的監(jiān)控,同時在成功率下降到預設的閾值以下的時候自動切斷外部接口的調(diào)用,外部接口成功率恢復后自動恢復請求。本文將對使用方式以及進階特性進行介紹。
項目主頁: https://github.com/ChanningBJ...
為什么要進行監(jiān)控和熔斷在我們的Java服務中,經(jīng)常會調(diào)用外部的一些接口進行數(shù)據(jù)的獲取操作,當這些外部接口的成功率比較低的時候會直接影響到服務本身的成功率,因此我們添加了對外部接口調(diào)用的成功率和響應時間監(jiān)控,這樣可以在造成大量用戶影響之前預先發(fā)現(xiàn)并解決問題。同時,對于接口中的非關鍵數(shù)據(jù),我們采取了更具成功率判斷進行觸發(fā)熔斷的方式,當成功率下降到預定的閥值以下的時候自動停止對這個外部接口的訪問以便保證關鍵數(shù)據(jù)能夠正常提供,當成功率恢復以后自動恢復請求。
meerkat主要功能監(jiān)控:監(jiān)控Java內(nèi)部操作的成功率以及響應時間指標
上報:log文件和Grafhite兩種監(jiān)控指標上報方式,支持擴展其他的上報方式
熔斷:(可選功能)成功率下降到預設的閾值以下觸發(fā)熔斷保護,暫定對外部接口的訪問,成功率恢復以后自動恢復訪問
基本使用 maven定義受監(jiān)控的操作com.github.channingbj meerkat 1.2
假設我們的服務中需要從HTTP接口查詢一個節(jié)目的播放次數(shù),為了防止這個HTTP接口大量超時影響我們自身服務的質(zhì)量,可以定義一個查詢Command:
public class GetPlayCountCommand extends FusingCommand{ private final Long videoID; public GetPlayCountCommand(Long videoID) { this.videoID = videoID; } protected Optional run() { Long result = 0l; ? ? ? ?// 調(diào)用HTTP接口獲取視頻的播放次數(shù)信息 ? ? ? ?// 如果調(diào)用失敗,返回 null 或者拋出異常,會將這次操作記錄為失敗 ? ? ? ?// 如果ID非法,返回 Optional.absent(),會將這次操作記錄為成功 ? ? ? ?return Optional.fromNullable(result); } }
執(zhí)行查詢:
//獲取視頻ID為123的視頻的播放次數(shù) GetPlayCountCommand command = new GetPlayCountCommand(123l); Long result = command.execute(); // 執(zhí)行查詢操作,如果執(zhí)行失敗或者處于熔斷狀態(tài),返回 null配置監(jiān)控上報
在服務初始化的時候需要對監(jiān)控上報進行設置。下面的例子中開啟了監(jiān)控數(shù)據(jù)向日志文件的打印
MeterCenter.INSTANCE .enableReporter(new EnablingLogReporter("org.apache.log4j.RollingFileAppender")) .init();查看統(tǒng)計結果
統(tǒng)計結果會以熔斷命令類名為進行分組。例如前面我們定義的 GetPlayCountCommand 類,package name 是 com.test,那么在日志中的輸出將會是這個樣子:
type=GAUGE, name=com.test.GetPlayCountCommand.normal-rate, value=0.0 type=GAUGE, name=com.test.GetPlayCountCommand.success-rate, value=61.0 type=TIMER, name=com.test.GetPlayCountCommand.time, count=25866500, min=0.0, max=0.001, mean=3.963926781047921E-5, stddev=1.951102156677818E-4, median=0.0, p75=0.0, p95=0.0, p98=0.001, p99=0.001, p999=0.001, mean_rate=649806.0831335272, m1=1665370.7316699813, m5=2315813.300713087, m15=2446572.324069477, rate_unit=events/second, duration_unit=milliseconds
監(jiān)控項 | 含義 |
---|---|
[classname].success-rate | 成功率 |
[classname].time.m1 | QPS |
[classname].time.mean | 平均響應時間 |
[classname].normal-rate | 過去1分鐘內(nèi)處于正常訪問(非熔斷)的時間比例 |
如果不想使用熔斷功能,只是想監(jiān)控Java方法調(diào)用的耗時和成功率,可以直接使用 OperationMeter 進行實現(xiàn),只需要在函數(shù)調(diào)用的前后添加開始和結束的調(diào)用即可:
//創(chuàng)建一個操作的計數(shù)器 OperationMeter meter = MeterCenter.INSTANCE.getOrCreateMeter(OperationMeterTest.class, OperationMeter.class); //模擬成功率60% for(int k=0; k<100; k++){ Timer.Context context = meter.startOperation(); if(k%10<6){ meter.endOperation(context, OperationMeter.Result.SUCCESS); } else { meter.endOperation(context, OperationMeter.Result.FAILURE); } }
# 開啟熔斷并配置閥值和持續(xù)時間
首先創(chuàng)建一個接口,繼承自FusingConfig,用于指定配置文件的加載路徑,同時還可以設定配置文件的刷新時間,具體定義方法請參照 owner 文檔
@Config.Sources("classpath:app_config.properties") @Config.HotReload( value = 1, unit = java.util.concurrent.TimeUnit.MINUTES, type = Config.HotReloadType.ASYNC) public interface APPFusingConfig extends FusingConfig { }
創(chuàng)建查詢Command的時候在構造函數(shù)中傳入
public class GetPlayCountCommand extends FusingCommand{ private final Long videoID; public GetPlayCountCommand(Long videoID) { super( APPFusingConfig.class); //設定配置文件 this.videoID = videoID; } protected Optional run() { Long result = 0l; ? ? ? ?// 調(diào)用HTTP接口獲取視頻的播放次數(shù)信息 ? ? ? ?// 如果調(diào)用失敗,返回 null 或者拋出異常,會將這次操作記錄為失敗 ? ? ? ?// 如果ID非法,返回 Optional.absent(),會將這次操作記錄為成功 ? ? ? ?return Optional.fromNullable(result); } }
配置文件內(nèi)容如下:
監(jiān)控項 | 含義 | 默認值 |
---|---|---|
fusing.[CommandClassName].mode | 熔斷模式: FORCE_NORMAL-關閉熔斷功能; AUTO_FUSING-自動進入熔斷模式; FORCE_NORMAL-強制進行熔斷 |
FORCE_NORMAL |
fusing.[CommandClassName].duration | 觸發(fā)一次熔斷以后持續(xù)的時間,支持ms,sec,min 單位。例如 10sec | 50sec |
fusing.[CommandClassName].success_rate_threshold | 觸發(fā)熔斷的成功率閥值,降低到這個成功率以下將觸發(fā)熔斷,例如0.9表示成功率90% | 0.9 |
配置文件中的 CommandClassName 是每個操作類的名稱,可以為每個操作多帶帶設置上述參數(shù)。同時,這個配置文件支持動態(tài)加載,樂意通過修改fusing.[CommandClassName].mode 手工觸發(fā)或者關閉熔斷。
監(jiān)控指標上報Graphite我們的服務中使用的是Metric+Graphite+Gafana進行監(jiān)控數(shù)據(jù)的采集存儲和展現(xiàn),下面將介紹如何配置監(jiān)控數(shù)據(jù)上報Grafana,關于Graphite+Grafana的配置,可以參考文章:使用graphite和grafana進行應用程序監(jiān)控
定義配置文件首先定義一個接口,繼承自GraphiteReporterConfig,通過這個接口定義配置文件的加載路徑。配置文件路徑的定義方法請參照 owner 文檔, 下面是一個例子:
@Config.Sources("classpath:config.properties") public interface MyConfig extends GraphiteReporterConfig { }
配置文件中需要定義下列內(nèi)容:
配置項 | 含義 |
---|---|
meter.reporter.enabled.hosts | 開啟監(jiān)控上報的服務器列表 |
meter.reporter.perfix | 上報使用的前綴 |
meter.reporter.carbon.host | grafana(carbon-cache) 的 IP 地址,用于存儲監(jiān)控數(shù)據(jù) |
meter.reporter.carbon.port | grafana(carbon-cache) 的端口 |
下面這個例子是在192.168.0.0.1和192.168.0.0.2兩臺服務器上開啟監(jiān)控數(shù)據(jù)上報,上報監(jiān)控指標的前綴是project_name.dc:
meter.reporter.enabled.hosts = 192.168.0.0.1,192.168.0.0.2 meter.reporter.perfix = project_name.dc meter.reporter.carbon.host = hostname.graphite
由于相同機房的不同服務器對外部接口的訪問情況一般比較類似,所以僅選取部分機器上報,也是為了節(jié)省資源。僅選擇部分機器上報不影響熔斷效果。
初始化配置上報在服務初始化的時候需要對監(jiān)控上報進行設置。下面的例子中開啟了監(jiān)控數(shù)據(jù)向日志文件的打印,同時通過MyConfig指定的配置文件加載Graphite配置信息。
MeterCenter.INSTANCE .enableReporter(new EnablingLogReporter("org.apache.log4j.RollingFileAppender")) .enableReporter(new EnablingGraphiteReporter(MyConfig.class)) //監(jiān)控數(shù)據(jù)上報Grafana .init();查看統(tǒng)計結果
統(tǒng)計結果會以熔斷命令類名為進行分組。例如前面我們定義的 GetPlayCountCommand 類,package name 是 com.test,那么在日志中的輸出將會是這個樣子:
type=GAUGE, name=com.test.GetPlayCountCommand.normal-rate, value=0.0 type=GAUGE, name=com.test.GetPlayCountCommand.success-rate, value=61.0 type=TIMER, name=com.test.GetPlayCountCommand.time, count=25866500, min=0.0, max=0.001, mean=3.963926781047921E-5, stddev=1.951102156677818E-4, median=0.0, p75=0.0, p95=0.0, p98=0.001, p99=0.001, p999=0.001, mean_rate=649806.0831335272, m1=1665370.7316699813, m5=2315813.300713087, m15=2446572.324069477, rate_unit=events/second, duration_unit=milliseconds
監(jiān)控項 | 含義 |
---|---|
[classname].success-rate | 成功率 |
[classname].time.m1 | QPS |
[classname].time.mean | 平均響應時間 |
[classname].normal-rate | 過去1分鐘內(nèi)處于正常訪問(非熔斷)的時間比例 |
在Grafanna中可以看到下面的監(jiān)控圖:
自定義監(jiān)控上報meerkat使用Metrics進行監(jiān)控數(shù)據(jù)的統(tǒng)計,因此可以使用Metrics支持的所有reporter進行上報。添加一種上報的時候,只需要實現(xiàn) EnablingReporter 并在 MeterCenter 初始化之前進行調(diào)用即可。下面是log reporter的實現(xiàn),可以作為參考
public class EnablingLogReporter implements EnablingReporter { private String loggername; public EnablingLogReporter(String loggername) { this.loggername = loggername; } @Override public void invoke(MetricRegistry metricRegistry, long period, TimeUnit timeUnit) { Slf4jReporter.forRegistry(metricRegistry) .outputTo(LoggerFactory.getLogger(loggername)) .convertRatesTo(java.util.concurrent.TimeUnit.SECONDS) .convertDurationsTo(java.util.concurrent.TimeUnit.MILLISECONDS) .build().start(period, timeUnit); } }
MeterCenter 初始化的時候開啟reporter
MeterCenter.INSTANCE .enableReporter(new EnablingLogReporter("org.apache.log4j.RollingFileAppender")) .init();多實例監(jiān)控
多實例監(jiān)控主要是為了解決一個被監(jiān)控操作的實現(xiàn)類需要根據(jù)輸入?yún)?shù)的不同分別進行監(jiān)控和熔斷的情況,通過定義實例的名稱進行實現(xiàn)。例如獲取視頻播放次數(shù)的例子,獲取視頻播放次數(shù)的接口對于不同的視頻類型而言請求邏輯是一樣的,所以使用同一個類進行實現(xiàn);但是對于不同的視頻類型,接口實現(xiàn)的復雜程度不同導致成功率不同,當用戶上傳的視頻的播次接口大量失敗的時候我們不希望同時熔斷電影電視劇這類視頻的播放次數(shù)獲取,這時就需要使用多實例這種特性進行監(jiān)控和熔斷。
下面是一個單實例的實現(xiàn):
public class GetPlayCountCommand extends FusingCommand{ private final Long videoID; public GetPlayCountCommand(Long videoID) { super( APPFusingConfig.class); this.videoID = videoID; } protected Optional run() { Long result = 0l; // 調(diào)用HTTP接口獲取視頻的播放次數(shù)信息 // 如果調(diào)用失敗,返回 null 或者拋出異常,會將這次操作記錄為失敗 // 如果ID非法,返回 Optional.absent(),會將這次操作記錄為成功 return Optional.fromNullable(result); } }
假設業(yè)務上我們可以根據(jù)視頻ID判斷視頻類型,可以在類初始化的時候根據(jù)類型創(chuàng)建多種監(jiān)控實例,添加了多實例支持的實現(xiàn)如下:
public class GetPlayCountCommand extends FusingCommand{ private final Long videoID; public GetPlayCountCommand(Long videoID) { super( getVideoType(videoID), APPFusingConfig.class); this.videoID = videoID; } private static String getVideoType(Long videoID){ return "PGC"; //根據(jù)videoID進行判斷,返回 "PGC" 或者 "UGC" 這兩個類別 } protected Optional run() { Long result = 0l; // 調(diào)用HTTP接口獲取視頻的播放次數(shù)信息 // 如果調(diào)用失敗,返回 null 或者拋出異常,會將這次操作記錄為失敗 // 如果ID非法,返回 Optional.absent(),會將這次操作記錄為成功 return Optional.fromNullable(result); }
由于每個實例獨享一個監(jiān)控指標,日志中的監(jiān)控個結果是這個樣子:
type=GAUGE, name=com.test.GetPlayCountCommand.PGC.normal-rate, value=100.0 type=GAUGE, name=com.test.GetPlayCountCommand.PGC.success-rate, value=100.0 type=GAUGE, name=com.test.GetPlayCountCommand.UGC.normal-rate, value=100.0 type=GAUGE, name=com.test.GetPlayCountCommand.UGC.success-rate, value=60.0 type=TIMER, name=com.test.GetPlayCountCommand.PGC.time, count=100, min=0.0, max=0.509, mean=0.00635, stddev=0.05052135687013958, median=0.001, p75=0.002, p95=0.002, p98=0.003, p99=0.003, p999=0.509, mean_rate=1.6680162586215173, m1=8.691964170141569, m5=16.929634497812284, m15=18.919189378135307, rate_unit=events/second, duration_unit=milliseconds type=TIMER, name=com.test.GetPlayCountCommand.UGC.time, count=100, min=0.0, max=0.027, mean=0.00132, stddev=0.0026939933184772376, median=0.001, p75=0.001, p95=0.002, p98=0.005, p99=0.006, p999=0.027, mean_rate=1.6715904477699361, m1=8.691964170141569, m5=16.929634497812284, m15=18.919189378135307, rate_unit=events/second, duration_unit=milliseconds
相應的,對熔斷閥值以及持續(xù)時間的配置也需要明確指出實例的名字:
fusing.GetPlayCountCommand.UGC.mode = AUTO_FUSING fusing.GetPlayCountCommand.UGC.duration = 50sec fusing.GetPlayCountCommand.UGC.success_rate_threshold = 0.9 fusing.GetPlayCountCommand.PGC.mode = AUTO_FUSING fusing.GetPlayCountCommand.PGC.duration = 50sec fusing.GetPlayCountCommand.PGC.success_rate_threshold = 0.9
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/71138.html
摘要:有了分布式數(shù)據(jù)庫可以使數(shù)據(jù)庫的性能可以隨著節(jié)點增加線性地增加。分布式數(shù)據(jù)庫最最下面是,是主備的,通過的內(nèi)核開發(fā)能力,我們能夠實現(xiàn)主備切換數(shù)據(jù)零丟失,所以數(shù)據(jù)落在這個里面,是非常放心的,哪怕是掛了一個節(jié)點,切換完了以后,你的數(shù)據(jù)也是不會丟的。 此文已由作者劉超授權網(wǎng)易云社區(qū)發(fā)布。 歡迎訪問網(wǎng)易云社區(qū),了解更多網(wǎng)易技術產(chǎn)品運營經(jīng)驗 三、微服務化的十個設計要點 微服務有哪些要點呢?第一張圖是...
時間:2017年07月06日星期四說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學示例源碼:無學習學習源碼:無 第一章:微服務架構在二手交易平臺(轉轉)中的實踐 1-1 微服務架構特點 分享要點-微服務架構 特點 使用原因 演進 通信協(xié)議、服務注冊與發(fā)現(xiàn) 柔性可用實踐 服務治理 什么是微服務 微服務是一系列小服務的組合 微服務可以單獨運行,獨立的進程 微服務整...
摘要:系統(tǒng)需要支持命令的撤銷。第步計算斷路器的健康度會將成功失敗拒絕超時等信息報告給斷路器,斷路器會維護一組計數(shù)器來統(tǒng)計這些數(shù)據(jù)。第步,當前命令的線程池請求隊列或者信號量被占滿的時候。 斷路由器模式 在分布式架構中,當某個服務單元發(fā)生故障之后,通過斷路由器的故障監(jiān)控(類似熔斷保險絲),向調(diào)用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調(diào)用故障服務被長時間占用不釋放,避免了故障...
閱讀 1185·2021-09-27 13:34
閱讀 995·2021-09-13 10:25
閱讀 521·2019-08-30 15:52
閱讀 3460·2019-08-30 13:48
閱讀 660·2019-08-30 11:07
閱讀 2181·2019-08-29 16:23
閱讀 2007·2019-08-29 13:51
閱讀 2340·2019-08-26 17:42