コンテキスト
リンクトラッキングには多くのオプションがあります。一般的なものは、zipkin、pinpoint、skywalking、jaegerなどです。
基本的にはGoogleの論文「Tracking Systems for Dapper Massively Distributed Systems」から発展したものです。
Catでは、各リクエストに費やされた時間の合計や、業務操作やデータベース操作に費やされた時間を簡単に確認することができます。サービス間の呼び出しも、埋没させることで監視できます。
次の図では、リクエストによってRPCコールが開始され、callRPCの先頭のレコードが表示されています。11msかかっていますが、このRPCサービスに費やされた時間は、こちら側から直接見ることはできず、別のサービスで見るしかありません。
詳しくは、現在の問題を説明する図を描きました:
上の図からわかるように、リクエストは複数のサービスを経由し、各サービスにはリモートコールやローカルコールのための埋没ポイントがあり、例外やパフォーマンスメトリクスのためにコールを監視することができます。
次のセクションでは、Catでこれらのメトリクスを表示するシナリオを示します。Catでは、データがプロジェクト・ディメンションで表示されるため、各サービスに独自のモニタリング・データがあります。
もし、そのリクエストがどこで行われ、どこで最も遅く、リンク全体で最も時間がかかったかを知りたければ、その情報を見るために4つのサービスにそれぞれアクセスしなければならず、直感的ではありません。
実装方法
下図のように。
トレース情報は、リンク全体を接続するために、ゲートウェイからサービスへ、サービスからサービスへと渡される必要があります。リンクが接続されて初めて、リンク全体に費やされた時間をCatで確認できます。
この論文で達成される効果は、リクエストのエントリーポイントで、リクエストが通過したすべてのサービスと、各サービスで消費された時間を確認できることです。
リクエスト全体をつなぎ合わせるためには、一般にtraceIdと呼ばれる、一意なリクエスト識別子が必要です。 残りの作業は、リンクに関連する情報をチェーンの下にカスケードすることです。
まず、リクエストヘッダ情報を各サービスのフィルタ、例えばゲートウェイからサービスAに受け取ります。
HTTP リクエストのメッセージツリー構築
// リモート・メッセージ・ツリーを構築するif(request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_ROOT_MESSAGE_ID) != null){
CatContext catContext = new CatContext();
catContext.addProperty(Cat.Context.ROOT,request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_ROOT_MESSAGE_ID));
catContext.addProperty(Cat.Context.PARENT,request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_PARENT_MESSAGE_ID));
catContext.addProperty(Cat.Context.CHILD,request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_CHILD_MESSAGE_ID));
Cat.logRemoteCallServer(catContext);
}
FeignやRestTemplateを使用している場合は、インターセプターを使用してパスを実現できます。
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
CatContext catContext = new CatContext();
Cat.logRemoteCallClient(catContext,Cat.getManager().getDomain());
template.header(CatConstantsExt.CAT_HTTP_HEADER_ROOT_MESSAGE_ID, catContext.getProperty(Cat.Context.ROOT));
template.header(CatConstantsExt.CAT_HTTP_HEADER_PARENT_MESSAGE_ID, catContext.getProperty(Cat.Context.PARENT));
template.header(CatConstantsExt.CAT_HTTP_HEADER_CHILD_MESSAGE_ID, catContext.getProperty(Cat.Context.CHILD));
}
}
Dubboを使用している場合は、Dubboのフィルタを使用して同じ効果を得ることができます。
articles/newestインターフェースが呼び出され、ゲートウェイはリクエストをarticles-providerサービスに転送し、articles-providerはユーザー情報を得るためにuser-providerのusers/uidインターフェースを呼び出します。最も重要なことは、user-provider の中に user-provider が存在するということです。