Slide 1

Slide 1 text

技術的負債と戦略的に戦わざるを 得ない場合の
 オブザーバビリティ活用術
 FUJII Yoshitaka (@yoshiyoshifujii)
 2025-05-22
 オブザーバビリティ / 関ジャバ'25 5月度


Slide 2

Slide 2 text

前提
 - 10年以上運用されているプロダクト
 - 大規模でミリオン以上のユーザー数 
 
 - 技術的負債が多様でどこから手をつけていいのか分からない
 - EOL祭、仕様不明、初期メンバー不在、コードのノリが複数混在、とにかく1ファイルが長い 
 
 - 現場に任せて何とかなるならもうなっている
 - もちろん現場だけでなくマネジメントにも問題ある 
 
 - 新規開発を止めることはできない
 - ほんまか?でもまあそういうことにしておきましょう 
 
 - 戦略的に取り組まないとどうしようもないんじゃないかと素直に思う
 - そう思って過去に取り組んできたけど場当たり的になって本質は変わってない 


Slide 3

Slide 3 text

戦略
 - ストラングラーフィグパターン を基本戦略とする


Slide 4

Slide 4 text

ストラングラーフィグ パターン
 - モダンシステムへの移行を段 階的にできる
 - モダンシステム開発を段階的 にしながらも既存アプリケー ションは機能する 
 - ファサード (プロキシ) は、レガ シーシステムに送信する要求 をインターセプト
 - ファサードは、これらの要求を レガシーまたは新しいサービ スにルーティングもしくはミラー リング
 https://learn.microsoft.com/ja-jp/azure/architecture/patterns/strangler-fig 


Slide 5

Slide 5 text

ストラングラーフィグパターンの懸念
 - 何をもってモダンに切り替えていいよねって判断するの
 - 勘?ユーザーの声?Xでの反応?
 - レガシーと比較して、モダンが同等もしくはそれ以上の品質であると保証してから切 り替えていくんだよね
 - ということは、レガシーの指標とモダンの指標があって
 - それを見比べながら、うん問題ないね、もっとユーザーを増やそうっていう感じにな るよね
 - となると…


Slide 6

Slide 6 text

オブザーバビリティ(可観測性)
 - システム内部の状態を、外部から取得できる情報(ログ、メトリクス、トレースなど) に基づいて推測・把握する能力


Slide 7

Slide 7 text

書籍「オブザーバビリティ・エンジニアリング」
 ソフトウェアシステムにおけるオブザーバビリティとは、システムがどのような状態に陥っ ても、それがいかに斬新で奇妙なものであっても、どれだけ理解し説明できるかを示す 尺度です。
 事前にデバッグの必要性を定義したり予測したりする必要はなく、システムの状態デー タのすべてのディメンションとディメンションの組み合わせで、アドホックな反復調査によ り、その奇妙な状態や新しい状態を比較しながらデバッグできる必要があります。
 もし、新しいコードをリリースすることなく、どんな奇妙な、あるいは新しい状態でも理解 できるのであれば、あなたのシステムにはオブザーバビリティがあると言えるでしょう。


Slide 8

Slide 8 text

レガシーにオブザーバビリティはあるか
 - もちろん無い 
 - あったらレガシーと呼ばれない
 - ただし、ログ、メトリクス、トレースは取れる
 - オブザーバビリティ・エンジニアリングの定義には行けない
 - レガシーは、トレースを自動計装 (Automatic instrumentation) で
 取得しよう
 - https://opentelemetry.io/docs/zero-code/php/ 
 - https://opentelemetry.io/docs/zero-code/java/ 
 - https://docs.datadoghq.com/ja/tracing/trace_collection/automatic_instrumentation/?tab=singlest epinstrumentation
 


Slide 9

Slide 9 text

分散トレーシング
 - レガシーとモダンを切り替えるにあたり、ファサード(プロキシ)が必要
 - クライアント→ファサード→レガシー
 が分散トレーシングできている状態を先に実現しておきたい
 - クライアント→ファサード→モダン
 との比較が容易になる


Slide 10

Slide 10 text

伝播 (Propagation)
 - 分散トレーシングを実現するのに、トレースコンテキストの伝播が必要
 - Trace Context
 - サービス間やプロセス間で「どの範囲のトレースに属しているか」などの情報 
 - 分散システム間でコンテキスト情報(トレースID、親スパンID、サンプリングフラグなど)を伝播し、単 一トレースとして追跡できるように設計されている 
 - 標準的なものと、ベンダー定義
 - https://www.w3.org/TR/trace-context/ 
 - traceparent:固定長のフォーマットでトレースIDや親スパンID、フラグを含む 
 - https://docs.datadoghq.com/ja/tracing/trace_collection/trace_context_propagation/ 
 - x-datadog-trace-id:128 ビットのトレース ID の下位 64 ビットを 10 進数で指定 
 - x-datadog-parent-id :現在のスパンに対応する 64 ビットのスパン ID を 10 進数で指定 


Slide 11

Slide 11 text

そもそもTraceってなんだ
 - Traceは、アプリケーションに対してリクエストされたとき、何が起こるのかの全体像 を教えてくれるもの
 - アプリケーションが、単一のデータベースを持つモノリスであろうと、分散システムで あろうと
 - リクエストがアプリケーション内でたどる完全な "パス "を理解するために不可欠な もの


Slide 12

Slide 12 text

Traceの構成要素
 - Trace は、 Span と呼ばれる意味のある操作の記録から構成される
 - Span は、システム内の作業単位を表す
 - 例: サービスへのリクエスト、データベース呼び出し、関数呼び出し 
 - TraceID, SpanID, ParentSpanID, Name, StartTime, EndTime 
 - 親子関係があり、トレースツリーを形成できる
 - ParentSpanID を持たない Span は、 Root Span となる 
 - Span Attributes があり、その操作の詳細を示す属性を追加できる
 - https://opentelemetry.io/docs/concepts/signals/traces/#attributes 
 - これが、オブザーバビリティにとても重要 
 - なお、Open Telemetry のセマンティクスがあるので、これに従うべし 
 - https://opentelemetry.io/docs/specs/semconv/general/trace/ 


Slide 13

Slide 13 text

レガシーのTraceをどう取るか
 - そりゃできれば OpenTelemetry に準拠したい
 - が、事情によっては難しい場合もある
 - すでに、ベンダーロックインされている 
 - DatadogやNewRelicに強い依存がある状態 
 - レガシーゆえに取り除くとバグる可能性がある 
 - それでも工数をかけてやるべしもあり得る 
 - ベンダーは OpenTelemetry 互換を持っている
 - https://docs.datadoghq.com/ja/opentelemetry/ 
 - https://docs.newrelic.com/jp/docs/opentelemetry/opentelemetry-introduction/ 
 - レガシーに大きく手を入れることは避けたい
 - なるだけ安く Trace を取る、ただし、取らない選択肢はないので、
 何かはするべし


Slide 14

Slide 14 text

監視ツールの選定
 - そりゃ Honeycomb 一択でしょ と言いたいが…
 - オブザーバビリティ・エンジニアリングの著者が所属している 
 - 大人の事情を考慮する
 - 既に導入されているツールが最優先
 - Datadog, NewRelic, Mackerel, Jaegerとかですかね 
 - 何はともあれ、トレースが繋っていることを最優先とする


Slide 15

Slide 15 text

モダンシステムは OpenTelemetry 一択
 - OpenTelemetry
 - https://opentelemetry.io 
 - OpenTelemetryの核となるミッション
 - 「高品質でポータブルなテレメトリーをユビキタスにすることで、効果的なオブザーバビリティを実現 する」
 - オブザーバビリティのための標準化
 - ベンダー非依存
 - 主要な構成要素
 - API, SDK (Javaあるよ), Collector, Protocol (OTLP), Context Propagation, Semantic 
 - モダンにしたあとレガシーになるのを遅延させるためにも標準をなるだけ採用して いきたい


Slide 16

Slide 16 text

モダンがレガシーを払拭したと言える状態の定義
 - クライアント→ファサード→レガシーorモダン 
 のトレーサビリティを獲得した後にすること
 - モダンがレガシーの要件を満たしているか
 - 要件とは何か
 - 機能/非機能の両面を考える


Slide 17

Slide 17 text

品質特性
 ソフトウェア品質特性・品質 副特性の種類 (ISO/IEC 25010)
 - 観点を漏らさず、モダン システムで満たすべき ことを検討


Slide 18

Slide 18 text

SLO を定義する
 SLO の定義は難しい…だがやる
 - CUJ → SLI → SLO(仮)→とりあえず運用してみる
 
 - CUJ
 - クリティカル ユーザー ジャーニー 
 - 様々なユーザージャーニー(顧客体験)の中でビジネス上もっとも重要なジャーニー 
 - これが失なわれると、著しくユーザー満足度を低下する要因となること 
 - SLI
 - サービスの可用性の目標を測定するために使用する指標 
 - システムの状態を「良い」と「悪い」に分類する 
 - 取りだすといくらでも取れちゃう 
 - CUJ に着目して、CUJ に関係する指標を最初に取る 


Slide 19

Slide 19 text

SLO を定義する
 - SLO
 - SLI を使用して測定されるサービスの可用性に関する「合意された目標」を定量化したもの 
 - あくまで目標値
 - 契約上の合意 (SLA) とは違う 
 - 柔軟に変更したり更新したりできる 
 - 最初から正確な値を目指さない(というかできない) 
 - 運用しながら徐々に自分たちの能力に合わせていく 
 - 費用対効果も重要
 - やり過ぎは過剰な品質 
 - お客様は充分満足しているのに過度に頑張るとコスパ悪いよね 


Slide 20

Slide 20 text

SLI に Trace を使う
 - SLI はサービスの信頼性を測る重要な指標
 - システムリソースやエラー率では不十分
 - ユーザーが実際に「良い体験」をしているかどうかを正確に測る
 - 「モダンにしたけどユーザー満足度が低下しました!」は最も避けるべき
 - クライアント→ファサード→モダンをトレーシングしてSLIを取る
 - Span Attributesを最大限活用する
 - 関数単位でSpanを作るとするなら、InputとOutputを全てSpan Attributesに入れる 
 - Outputは、正常系/異常系を両方捉えて逃さないようにする 
 - 関数内で複数のステップを踏むのであれば、関数内での状態変化もSpan Attributesに入れたい 
 - 参照透過性の高い関数設計なら関数のIOでSpanを構築しまくるといいかも 


Slide 21

Slide 21 text

SLO → SLI → Trace をつなげる
 - SLO に異常が発生したら
 - SLI を確認し
 - Trace に辿りつく
 - その際、Traceは、いつ、どこで、だれが、何をして、どうなったという情報に直結して おり
 - それは、全体における割合を把握でき
 - 異常なのか正常なのか奇妙なのかを調べる手段が一般化されている
 - これがオブザーバビリティのある状態と言えそう


Slide 22

Slide 22 text

レガシーのSLOはどうするの
 - モダンシステムは、モダンなので、ちゃんとSLOやるよね
 - レガシーはどうなのか
 - レガシーシステムはだいたいSLOあってもCUJと異なる指標だったり不十分だったり 運用されていなかったり、そもそも無いことが多い
 - モダンは、SLOを定義した
 - レガシーに同等のSLOは適用できない
 - だが、よく考えてみると、今までSLOなくてもやってこれた
 - ってことは、肌勘はあるのだろう
 - その肌勘と、モダンなSLOでやっていくでもいいんじゃないだろうか
 - それとも、レガシーに頑張ってSLOを入れますか…捨てるけど…


Slide 23

Slide 23 text

モダンへの移行判断
 - レガシーとモダンを同じ指標で比較することは困難な場合が多い
 - モダンに移行したユーザー満足度の低下が無いことを観測しながら移行の判断を していくことになる
 - モダンで問題が起こったとき、レガシーにすぐに戻せる場合と無理な場合がある
 - データ移行を伴う場合は、簡単に戻せない
 - その場合は、モダン側で一度低下したユーザー満足度の回復をしていくことになる
 - それってつまり運用するってことで、今もレガシーでやってるよね


Slide 24

Slide 24 text

Four Keys の観測も必要
 - ストラングラーフィグパターンにおいて、レガシーからモダンに移行し、SLOを計測 し、ユーザー満足度を満たしつつ、モダン化していくのであれば、モダンも常に進化 できる仕組みが必要
 - 進化していく指標に、Four Keys が使える
 - デプロイの頻度
 - 変更のリードタイム
 - 変更失敗率
 - デプロイ失敗時の復元までの時間 
 - モダンシステムは、エリートを目指す


Slide 25

Slide 25 text

まとめ
 - 10年以上稼働している大規模システムにおける技術的負債
 - 生産性をマイナスにする要因を取り除くにしても戦略的にやらざるを得ない
 - ストラングラーフィグパターンを軸にオブザーバビリティを考える
 - レガシーをモダンに切り替えても問題ないよねって言える状態を作る
 - CUJに基づいたSLOを定義しTraceと繋げてオブザーバビリティを獲得
 - モダンのSLOを確認しながらレガシーを移行していく
 - ユーザー満足度を低下させないようFour Keysを観測しながらDevOps


Slide 26

Slide 26 text

参考
 - オブザーバビリティ・エンジニアリング - オライリー
 - https://www.oreilly.co.jp/books/9784814400126/ 
 - SLO サービスレベル目標 - オライリー
 - https://www.oreilly.co.jp/books/9784814400348/ 
 - 実践 OpenTelemetry - オライリー
 - https://www.oreilly.co.jp/books/9784814401031/ 
 - OpenTelemetry
 - https://opentelemetry.io/ja/