こんにちは。マネーフォワードでエンジニアとして働いている @sters です。普段は別の会社でフルタイム勤務していて、他の時間で マネーフォワード クラウド会計(以下、クラウド会計) のメトリクスやトレースを眺め、パフォーマンス改善をしています。
なぜ分散トレーシングが必要なのか
マネーフォワードでは、マイクロサービスアーキテクチャを採用した開発を進めており、多くのサービスが連携してプロダクトとその価値をユーザに届けています。詳しくはこちらの記事でどうぞ。
マネーフォワードのSRE、インフラエンジニア組織のこれから | Money Forward Engineers' Blog
1つのサービスで1つのプロダクトを届けていたこれまでの形では、何かしらのエラーが発生したり、レイテンシが上昇するなどの問題が起きたときに、自分たちの実装やデータ、インフラストラクチャを気にするだけで十分でした。
しかし、マイクロサービスアーキテクチャとして複数のサービスが連携するようになると、1つの処理を完了するまでに何が起きているかを把握することが難しくなります。問題が起きたとき、自分たちのサービスが原因なのか、他のサービスが原因なのか、がわかりにくくなります。
この課題に対するひとつのアプローチとして、システム連携図のようなものをもったドキュメントを整えることができます。しかし、組織が大きくなれば開発の規模も大きくなり、新しい機能・新しいプロダクト・新しいサービス・新しい連携がどんどん作られます。そのたびにドキュメントを整えていくのはコストもどんどん大きくなっていきます。
どのサービスの、どんな情報を連携しようとしているのか、サービス間の連携はサービス自身が知ることができます。これがオブザーバビリティへの取り組みになります。トレースはオブザーバビリティへの取り組みのひとつで、実態を把握するために活用できます。
それぞれのサービス上で起きていることをそれぞれのサービス自身がトレースすることに加え、他のサービスへのリクエスト上へトレースに関する情報を付与することで、サービスを超えたシステム全体のトレースを取ることができます。これが分散トレーシングです。
マネーフォワードでは、主にDatadogを利用してオブザーバビリティへの取り組み、分散トレーシングを進めています。
Datadogを使った分散トレーシング
私は クラウド会計 というプロダクトの開発を手伝っています。
クラウド会計では少し前からDatadogを利用しています。それによってこのように他のサービスと繋がりがあると観測されていました。
これはDatadogの ServiceMapという機能 のキャプチャです。クラウド会計の本体は丸く囲った箇所にまとまっています。
外に出ていく矢印、外からくる矢印が2本しかなく、ごくわずかな連携だけがされているように見えます。しかし実際には多くのサービスと連携をしています。それらは人の記憶、コード、ドキュメントといった部分でのみ表現されているものでした。
例えば、別のサービスと連携しているはずのエンドポイントをトレースしたものでは、このように空白となっている箇所があります。
全体のトレース(リクエストを受けてからレスポンスを返すまで)のレイテンシが171msで、これはp9 = 9パーセンタイルに位置する値なので問題ないだろう、とは読み取れます。しかし、空白となっていては何が起きているかわからず、これが正しい状態なのか、問題がある状態なのかがわかりません。
クラウド会計はRubyで実装されているので Datadogの公式ドキュメント に従い、使っているgemを確認して足りていないものを追加しました。
直接使っているgemもあれば、特定のgemが内部で使っているものもあります。例えば、一部の通信では fog というgemを使っていますが、その内部では excon を利用しています。通信が発生するような箇所を一通り確認し、Datadogでサポートされるgemであれば設定へ追加しました。
その結果、次のようになりました。※実際には便利に使うためのタグをつけています。
Datadog.configure do |c| c.use :rails c.use :sidekiq + c.use :redis + c.use :ethon + c.use :excon + c.use :faraday + c.use :rest_client + c.use :http + c.use :grpc end
この設定によって今ではこのような観測結果となっています。
囲った範囲がクラウド会計の本体です。別サービスが増えていることもあり、きれいな比較は難しいのですが、囲った範囲から出ていく・入ってくる線が多数増えています。
ちなみに、すぐ隣に密接しているサービス郡はクラウド会計から切り出した別のサービスです。クラウド会計とのやり取りしかないので隣接しているのだと思います。
トレースを見たときにも、クラウド会計から他のサービスを呼び出している様子、他のサービスで何が起きているかを把握することができるようになりました。
これは対応前として出したトレースと同じエンドポイントでのトレースです。
空白だった箇所はgRPCによる通信でした。
リクエストをしてから到達するまでに、60msくらいかかっていて、通信の大部分を占めていることもわかります。
これは、マネーフォワードにはSakura環境とAWS環境が混在しており、環境を超えた通信を行っている部分となるために時間がかかっています。詳しくは冒頭でも出したこちらの記事をどうぞ。
マネーフォワードのSRE、インフラエンジニア組織のこれから | Money Forward Engineers' Blog
いまのところ、環境を超えた通信、連携している箇所は一部分だけのため、大きな問題にはなっていませんが、今後新しいサービスが増えたり、クラウド会計内部の分離が進んだり、などによりサービスの連携が増えると問題になってくるはずです。いろいろな可能性を模索しながらこの問題とも向き合っていきたいと思います。
Datadogはどのように分散トレーシングを収集しているのか
ところでDatadogはどのようにして各サービスの連携を認識しているのでしょうか。Datadogを使った分散トレーシングは、設定に少しの追加をするだけで出来たのが不思議に思えます。
Datadogの公式ドキュメント上では、Rubyの設定ページにしか書かれていなかったのですが、Datadogのライブラリが特定のHTTPヘッダーを設定、参照することで、サービスを超えてトレース情報の連携ができます。
具体的には x-datadog-trace-id
, x-datadog-parent-id
, x-datadog-sampling-priority
というHTTPヘッダーをDatadogのgemがリクエスト時に付与、リクエストを受けたときに展開しています。
- Tracing Ruby Applications - Distributed Tracing
- DataDog/dd-trace-rb での実装
- lib/ddtrace/propagation/http_propagator.rb
- 各連携から #inject! または #extract が呼ばれる。
- lib/ddtrace/distributed_tracing/headers/datadog.rb
- lib/ddtrace/ext/distributed.rb
- B3 Propagation も対応しているようです。
- lib/ddtrace/propagation/http_propagator.rb
これによって、リクエスト元、リクエスト先、どちらも別々のタイミングでトレース情報をDatadogへ送信しますが、一貫したトレースとして扱われ、集約してみることができます。
また、マネーフォワードではGoを使った新しいサービスの開発、本番での運用も進んでいます。Goでの実装を見たところ、クライアント、サーバ、どちらにもRubyのものと同様にトレース情報の受け渡し処理があります。
- ddtrace/tracer/tracer.go
- 各連携からtracer.Inject, tracer.Extractが呼ばれる。
- ddtrace/tracer/textmap.go
Rubyだろうと、Goだろうと、他の言語だとしても、同じやり方でトレース情報を受け渡し、DatadogAgentに送ることで、すべてのトレースを一貫したものとして扱ってくれます。実際に、クラウド会計からGoで実装されたサービスへとリクエストしている箇所も、一貫したトレースとして観測できています。
Datadogは他にもNode.js, Java, Python, PHP, .NET, C++にも公式でライブラリを提供しています。これらを使うことで簡単に分散トレーシングを実現し可視化することができます。
おわりに
この記事では、Datadogを使った分散トレーシングの設定とどのようにそれが動いているのかを紹介しました。
Datadogの設定を追加したことで、これまで観測できていなかった他サービスとの連携が見えるようになりました。
クラウド会計が別サービスと連携している箇所を一通り確認しましたが、嬉しいことに、いまのところ大きな課題は見られませんでした。しかし、未来はどうなるかわかりません。この観測できている状態を続けることで、システム全体の今ある姿を理解できるようにし、課題や問題を発見しやすくすることができます。
また、オブザーバビリティにはトレースだけではなくメトリクスとログも重要です。いずれもDatadogを使うことで簡単に、収集、可視化、さらには各データ同士の連携を行うことができます。これがDatadogの便利なところのひとつだと感じます。
Datadogには他にも様々な機能があるので、これからも活用を進め、様々なものを見えるようにしていきたいと思っています。
・・・ところで!
マネーフォワードでは「Datadogをもっと使いこなしたい」「システムだけでなくプロダクトやカスタマー、デベロッパーのエクスペリエンスも見えるようにしていきたい」「問題や課題を見つけてどんどんよくしていきたい」そんな方々を絶賛募集しています。
こちらからどうぞ!
マネーフォワードでは、エンジニアを募集しています。 ご応募お待ちしています。
【サイトのご案内】 ■マネーフォワード採用サイト ■Wantedly ■福岡開発拠点 ■京都開発拠点
【プロダクトのご紹介】 ■お金の見える化サービス 『マネーフォワード ME』 iPhone,iPad Android
■ビジネス向けバックオフィス向け業務効率化ソリューション 『マネーフォワード クラウド』
■だれでも貯まって増える お金の体質改善サービス 『マネーフォワード おかねせんせい』