Dubbo監視センタ
6820 ワード
Dubbo監視センタ
Dubboは1つの粗末な監視センターを提供して関連するサービスの情況を開発して観察することができて、普通の小さい会社の使う異化はすでに満足することができて、しかし大きい会社の中で業務は比較的に複雑で、往々にして需要を満たすことができなくて、そのため自分でカスタマイズして開発する必要があります(我が社は自分でカスタマイズしたセットです).実はDubboのモニタリングはDubboの核心業務ではなく、説明した理由も自分の学習の私心を満たすためで、自分もモニタリングセンターが一般的にどのように構築されるか分からないので、この機会に勉強しながら共有しましょう.
ビジネスモニタリングとして、一般的にモニタリングするデータはconsumer側の呼び出し時間、provider側の対応する時間、同時量、rtなどである.これらのデータの収集は,インタフェース呼び出しの後に収集するだけでなく,インタフェース呼び出しの前に収集する必要がある.モニタリングはすべてのアプリケーションが必要ではないので、Dubboのモニタリングセンターはオプションで、Dubboの既存のアーキテクチャに基づいてFilterがこのような仕事に最適であり、Dubboもそうしています.Filterの具体的な実装を簡単に見てみましょう.
Dubboが収集したデータは主に以下の項目がある.総成功回数 総失敗回数 合計requestデータサイズ 合計responseデータサイズ 呼び出し総消費時間 同時量 最大requestデータサイズ 最大responseデータサイズ 最大消費時間 最大同時量 DubboMonitorは、Filterで収集したデータを格納し、monitorServicesにデータを送信し、最終的にmonitorServicesが受信したデータを整理して表示します.
write()メソッドはLinkedBlockingQueue独自のロックメカニズムを利用してデータを分類して指定したファイルにリフレッシュし、収集したデータがない場合write()はデータが来るまでブロックします.drawメソッドはwirte()メソッドに基づいて生成されたデータファイルを定期的にスキャンしてグラフを生成する.個人的にはwriteもdrawも比較的はっきりした方法だと思いますが、中には重要な内容は含まれていないので、具体的なコードは展示されません.
以上の紹介から分かるように、Dubboは収集したデータ情報を1つのキューで格納している.単機の問題で、本質的には一定の容量制限がある.Dubboが現在設定しているキューの最大長は100000(10 W)であるが、データを生成するデータがDubboがファイルを書く速度を超えるとデータの蓄積が発生し、蓄積は時間とともに深刻になり、最終的には一部の収集データが漏れ、収集プロセス全体が正確でない可能性がある.したがって、アプリケーションへのアクセスが大きい場合は、Dubboのモニタリングセンターをカスタマイズしてください.
Dubboは1つの粗末な監視センターを提供して関連するサービスの情況を開発して観察することができて、普通の小さい会社の使う異化はすでに満足することができて、しかし大きい会社の中で業務は比較的に複雑で、往々にして需要を満たすことができなくて、そのため自分でカスタマイズして開発する必要があります(我が社は自分でカスタマイズしたセットです).実はDubboのモニタリングはDubboの核心業務ではなく、説明した理由も自分の学習の私心を満たすためで、自分もモニタリングセンターが一般的にどのように構築されるか分からないので、この機会に勉強しながら共有しましょう.
ビジネスモニタリングとして、一般的にモニタリングするデータはconsumer側の呼び出し時間、provider側の対応する時間、同時量、rtなどである.これらのデータの収集は,インタフェース呼び出しの後に収集するだけでなく,インタフェース呼び出しの前に収集する必要がある.モニタリングはすべてのアプリケーションが必要ではないので、Dubboのモニタリングセンターはオプションで、Dubboの既存のアーキテクチャに基づいてFilterがこのような仕事に最適であり、Dubboもそうしています.Filterの具体的な実装を簡単に見てみましょう.
// , ,
public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {
// monitor
if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) {
// invoke() context
RpcContext context = RpcContext.getContext();
//
long start = System.currentTimeMillis();
// ( )
getConcurrent(invoker, invocation).incrementAndGet();
try {
//
Result result = invoker.invoke(invocation);
collect(invoker, invocation, result, context, start, false);
return result;
} catch (RpcException e) {
collect(invoker, invocation, null, context, start, true);
throw e;
} finally {
getConcurrent(invoker, invocation).decrementAndGet(); //
}
} else {
return invoker.invoke(invocation);
}
}
// , monitor
private void collect(Invoker> invoker, Invocation invocation, Result result, RpcContext context, long start, boolean error) {
try {
// ---- ----
long elapsed = System.currentTimeMillis() - start; //
int concurrent = getConcurrent(invoker, invocation).get(); //
String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY);
String service = invoker.getInterface().getName(); //
String method = RpcUtils.getMethodName(invocation); //
URL url = invoker.getUrl().getUrlParameter(Constants.MONITOR_KEY);
Monitor monitor = monitorFactory.getMonitor(url);// DubboMonitor
int localPort;
String remoteKey;
String remoteValue;
if (Constants.CONSUMER_SIDE.equals(invoker.getUrl().getParameter(Constants.SIDE_KEY))) {
// ---- ----
context = RpcContext.getContext(); // invoke() context
localPort = 0;
remoteKey = MonitorService.PROVIDER;
remoteValue = invoker.getUrl().getAddress();
} else {
// ---- ----
localPort = invoker.getUrl().getPort();
remoteKey = MonitorService.CONSUMER;
remoteValue = context.getRemoteHost();
}
//input request ,output
String input = "", output = "";
if (invocation.getAttachment(Constants.INPUT_KEY) != null) {
input = invocation.getAttachment(Constants.INPUT_KEY);
}
if (result != null && result.getAttachment(Constants.OUTPUT_KEY) != null) {
output = result.getAttachment(Constants.OUTPUT_KEY);
}
monitor.collect(new URL(Constants.COUNT_PROTOCOL,
NetUtils.getLocalHost(), localPort,
service + "/" + method,
MonitorService.APPLICATION, application,
MonitorService.INTERFACE, service,
MonitorService.METHOD, method,
remoteKey, remoteValue,
error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1",
MonitorService.ELAPSED, String.valueOf(elapsed),
MonitorService.CONCURRENT, String.valueOf(concurrent),
Constants.INPUT_KEY, input,
Constants.OUTPUT_KEY, output));
} catch (Throwable t) {
logger.error("Failed to monitor count service " + invoker.getUrl() + ", cause: " + t.getMessage(), t);
}
}
Dubboが収集したデータは主に以下の項目がある.
public SimpleMonitorService() {
//
queue = new LinkedBlockingQueue(Integer.parseInt(ConfigUtils.getProperty("dubbo.monitor.queue", "100000")));
writeThread = new Thread(new Runnable() {
public void run() {
while (running) {
try {
write(); //
} catch (Throwable t) { //
logger.error("Unexpected error occur at write stat log, cause: " + t.getMessage(), t);
try {
Thread.sleep(5000); //
} catch (Throwable t2) {
}
}
}
}
});
writeThread.setDaemon(true);
writeThread.setName("DubboMonitorAsyncWriteLogThread");
writeThread.start();
chartFuture = scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
public void run() {
try {
draw(); //
} catch (Throwable t) { //
logger.error("Unexpected error occur at draw stat chart, cause: " + t.getMessage(), t);
}
}
}, 1, 300, TimeUnit.SECONDS);
INSTANCE = this;
}
write()メソッドはLinkedBlockingQueue独自のロックメカニズムを利用してデータを分類して指定したファイルにリフレッシュし、収集したデータがない場合write()はデータが来るまでブロックします.drawメソッドはwirte()メソッドに基づいて生成されたデータファイルを定期的にスキャンしてグラフを生成する.個人的にはwriteもdrawも比較的はっきりした方法だと思いますが、中には重要な内容は含まれていないので、具体的なコードは展示されません.
以上の紹介から分かるように、Dubboは収集したデータ情報を1つのキューで格納している.単機の問題で、本質的には一定の容量制限がある.Dubboが現在設定しているキューの最大長は100000(10 W)であるが、データを生成するデータがDubboがファイルを書く速度を超えるとデータの蓄積が発生し、蓄積は時間とともに深刻になり、最終的には一部の収集データが漏れ、収集プロセス全体が正確でない可能性がある.したがって、アプリケーションへのアクセスが大きい場合は、Dubboのモニタリングセンターをカスタマイズしてください.