Armeria の Zipkin tracing の改善を手伝ったよ

今年の6月くらいに Zipkin のメインコントリビューターの @adrian から一緒になんか改善しないかと声がかかったので、8月に福岡に来て、自分と東京にいる元同僚 anuraaga の3人で二日半ぐらいかけて、Armeria のこの PR Reworks tracing to use RequestContext natively をモブプログラミングっぽい感じで進行して作りました。Release Brave 5.2 · openzipkin/brave · GitHub にも詳しく書いてもらっています。

もともとは会社主催の 【東京】LINE Developer Meetup #35 - Zipkin - - connpass でAdrian Coleが来て一緒に Zipkin 関連の話題と Shop の事例で Armeria と Zipkin 連携で大変だったことを話してたので、リアクティブや非同期の環境で Zipkin のどこが使いやすくないか、どうしたら良くなるかについて話して、その後にせっかくだから又日本来て一緒にやらないかと声をかけられました。当日の資料はLINE スタンプショップにおける Zipkin 利用事例です。簡略に言うと、Zipkin はデフォルトでは ThreadLocal を利用して現在のトレーシングコンテキストを埋めていますので、非同期ではない場合、サーブレットフィルターや Spring MVC のインターセプターに埋め込めば、簡単に使えます。ただ Armeria はもともと非同期のライブラリなので、Zipkin を別で RequestContext の Attribute や ThreadLocal を利用して open/close していたら何回もコーナーケースでバグに当たって、Armeria 上での Zipkin 関連の修正が何回もされてます。そもそも Armeria には RequestContext の概念があるので、その上に乗っかった方がやりやすいのでは?という方向になり、最終的には RequestContext にずっと保存して、RequestContext のライフサイクルの最後に close すればいいようにした。

f:id:kojilin:20181209225421j:plain
Tracing と Context の関係図

実際自分はこの内容で追いつくまでかなり時間がかかって、他の二名はハイスピードで議論しながら仕上げていました(いろいろ勉強になりました;;。中で面白かったのが、今回の変更で Armeria では絶対に RequestContextCurrentTraceContext を使わないと動かなくなるようになるので、起動時に検査をするにはどうしたらいいかを話してると、PingPongExtraと言うクラスで、ダミーコンテキストを突っ込んで実際に RequestContextCurrentTraceContext を使っているかどうかを検査するとか。もう一つは RequestContext が無い場合、警告を一回しか出したくないから、Lazy class loading で対応したとか。

終わった後に、CurrentTraceContext の元々の継承方式をデコレータにしたとか進んで、色々勉強になった3日だった。こうやって社外の人と一緒に会社が使っているオープンソースプロジェクトの改善をして、自分達がもっと使いやすくなるので、これからも続けてやっていきたいですね。最近は東京でもやっているみたいで zipkin/zipkin-lens at master · openzipkin/zipkin · GitHub ができてます。