Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
アドフリくんにおけるマイクロサービス間での一貫したトレース実現
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
gree_tech
PRO
October 17, 2025
Technology
350
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
アドフリくんにおけるマイクロサービス間での一貫したトレース実現
GREE Tech Conference 2025で発表された資料です。
https://techcon.gree.jp/2025/session/TrackB-1
gree_tech
PRO
October 17, 2025
More Decks by gree_tech
See All by gree_tech
変わるもの、変わらないもの :OSSアーキテクチャで実現する持続可能なシステム
gree_tech
PRO
0
4.6k
マネジメントに役立つ Google Cloud
gree_tech
PRO
0
60
今この時代に技術とどう向き合うべきか
gree_tech
PRO
3
2.7k
生成AIを開発組織にインストールするために: REALITYにおけるガバナンス・技術・文化へのアプローチ
gree_tech
PRO
0
420
安く・手軽に・現場発 既存資産を生かすSlack×AI検索Botの作り方
gree_tech
PRO
0
410
生成AIを安心して活用するために──「情報セキュリティガイドライン」策定とポイント
gree_tech
PRO
1
2.2k
あうもんと学ぶGenAIOps
gree_tech
PRO
0
530
MVP開発における生成AIの活用と導入事例
gree_tech
PRO
0
560
機械学習・生成AIが拓く事業価値創出の最前線
gree_tech
PRO
0
430
Other Decks in Technology
See All in Technology
なぜ Platform Engineering の土台に Kubernetes を選ぶのか
r4ynode
1
560
AGENTS.mdとSkillsで始めるAIエージェント活用
sonoda_mj
2
190
2026TECHFRESH畢業分享會 - Lightning Talk - E起 See See : 電商推薦讀心術? 數據說了算
line_developers_tw
PRO
0
670
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
0
1.3k
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
RSA暗号を手計算したくなること、ありますよね?? (20260615_orestudy6_rsa)
thousanda
0
160
2026 TECHFRESH 畢業分享會 - 開發日常大解密!從領域驅動到企業級上線
line_developers_tw
PRO
0
670
2026TECHFRESH畢業分享會 - Lightning Talk - 打造精準高效的 MCP 設計模式與測試實務
line_developers_tw
PRO
0
670
AI Engineering Summit Tokyo 2026 AIの前に、やることがある 〜医療データ企業の4フェーズ〜
dtaniwaki
0
2.5k
「エンジニア進化論」2028年の開発完全自動化、エンジニアはどう進化するか
cyberagentdevelopers
PRO
4
4.3k
機械学習を「社会実装」するということ 2026年夏版 / Social Implementation of Machine Learning June 2026 Version
moepy_stats
4
1.2k
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
670
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
270
How GitHub (no longer) Works
holman
316
150k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
420
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
A Soul's Torment
seathinner
6
2.9k
Exploring anti-patterns in Rails
aemeredith
3
400
Transcript
アドフリくんにおけるマイクロサービ ス間における一貫したトレース実現 - アドフリくんRTBシステムにおけるObservabilityの実装事例 - グリーエックス社 エンジニア 樋口雅拓
樋口雅拓 Go / k8s / RecSys / Android / Kotlin
/ Scala / PHP / Python / Swift / AWS / GCP グリーグループのグリーエックス株式会社で、ソフトウェ ア開発に従事。広告システム開発、GREE Platformの立ち 上げ、不正利用対策、チャットアプリ開発、メディア開発 を経て2025年2月より現職。 グリーエックス社 エンジニア 2
背景と目的 • 複数のマイクロサービスを連携して1つのHTTPリ クエストを処理するシステムを構築した。 • ログやトレース情報がマイクロサービス毎に生成 され、統合して確認することができなかった。 • これを統合して確認できるようにしたため、その 事例について発表する。
発表構成 • 前提知識 ◦ サービス及びシステム概要 ◦ システムの一部であるRTBシステムについて ◦ RTBシステムのObservabilityについて • 提案方式 ◦ 一貫したトレースの実現方法 前提知識を説明した後、提案方式について説明します。 アドフリくん管理画面などRTB以外のサーバー機能、レ ポート機能については、時間の都合で割愛させていただ きます。 3
サービス及びシステム概要 4
アドフリくん - サービス概要 • モバイルアプリ向けの広告配信プラット フォーム • 「動画リワード広告」の取扱量は国内No.1 5 動画リワード広告とは
Pangle/Unity/APP LOVIN/Mintegral/Info Source/AdMob/Digital Turbine/LINE Ads Network/nend/Zucks/ maio/AMoAD
アドフリくん - システム概要 モバイルアプリ向けの広告配信プラットフォーム • メディエーション: 複数のアドネットワークを統合管理 • 収益最適化: リアルタイムでの配信比率調整
• RTB対応: Real-Time Biddingによる高収益化 • 運用効率: 自動化された管理・監視システム 6 アドフリくんは、以下のコンポーネントから構成されています。 • アドフリくんサーバー: 配信設定(利用するアドネットワークのリストや条件)をSDKに伝える。 • アドフリくんSDK: モバイルアプリに組み込み、サーバーから受け取った配信設定に従って広告を取得する。 つまり、アドフリくんはSDKとサーバーが連携して価値を提供しています。 次のスライドでは、アドフリくんサーバーが配信設定を作る方法について説明します。
アドフリくん - SDK概要 • init()で広告設定を読み込みます。 ◦ 広告設定には、アドネットワークの配信比 率や優先順位が含まれています。 • load()で広告を読み込みます。
◦ 配信設定を元に選択されたアドネットワー クに要求します。 • play()で広告を表示します。 7 // SDK初期化 AdfurikunSdk.init(activity) // 広告読み込み AdfurikunSdk.load("REWARD_APP_ID") // 再生準備確認・表示 if (AdfurikunSdk.isPrepared("REWARD_APP_ID")) { AdfurikunSdk.play("REWARD_APP_ID") } 実装例: Android
アドフリくん - アドフリくんサーバー概要 アドフリくんサーバーは、複数のアドネットワークの配信比率を適 切に調整して、収益最大化するものです。 アドフリくんでは、以下3種類に対応しています。 ウォーターフォール配信 優先度を予め設定しておき、その順序で問い合わせる。 一般的に単価が高いDSPほどターゲティングやキャップがキツく、 在庫が少ないため高単価から順番に問い合わせることが合理的。
ウォーターフォールRTBコンビネーション配信 ウォーターフォールとRTBの良い所取りをしたもの。 過去の実績からRTBのeCPMを計算し、ウォーターフォールのeCPM と比較して適切な場所に差し込む。 これにより、確実に高単価が見込めるDSPへの問い合わせをRTBよ り優先させることができる。 8 優先度1: AdMob (eCPM: $5.0) ↓ (広告なし) 優先度2: AppLovin (eCPM: $4.0) ↓ (広告表示) 並列入札: ├─ AdMob: $4.2 ├─ Unity Ads: $4.7 ← 勝者(広告表示) └─ AppLovin: $4.5 RTB (Real-Time Bidding) リクエスト毎にDSPに問い合わせ、最も高い入札額を提示した DSPの広告を配信する。 確実に最高額の広告を表示できるが、仕組みが複雑。 まとめ • ウォーターフォール配信: 対象アプリに最適な配信設定 • RTB: 対象アプリとユーザーに最適な配信設定 • ウォーターフォールRTBコンビネーション配信: 良い所 取り 直感的にはRTBが最適に見えます。 しかし、RTBと通常配信で在庫が分かれているケースが多いた め、組み合わせる事でさらに良い結果を得られる事が多い。 優先度1: AdMob (eCPM: $5.0) ↓ (広告なし) 優先度2: RTB(Unity Ads) (eCPM: $4.7) ↓ (広告表示)
システムの一部である RTBシステムについて 9
RTBシステム RTB機能を提供するシステムです。以下のよう な特徴があります。 ここでは、Observability以外の部分について説 明します。 システム特徴 • 組織: スクラム開発の導入と運用 •
設計: ドメイン駆動設計(DDD)とC4 Modelsによる可視化 • 実装: Clean Architectureの適用とテスト 駆動開発の実践 • 構築: マイクロサービスとして機能ごとに 分離されたサービス群 • 運用: Google Cloud Observabilityを利用 したログ、トレース、メトリックス 10
RTBシステムの特徴 - 組織 スクラム開発の採用 1週間スプリント - 新規技術と不明確な要件への対応 - 素早い学習サイクルの実現 -
課題の早期発見と対応 会議体の制定 - スプリントプランニング: 毎週1時間 - デイリースクラム: 毎日30分 - レトロスペクティブ: 毎週1時間 透明性の向上 - スプリントバックログの可視化 - バーンダウンチャートによる進捗管理 - ステークホルダーとの情報共有 導入効果と課題 メリット - チームコミュニケーションの改善 - 問題解決の文化醸成 - プロジェクト進捗の可視化 - 適切なフィードバックの獲得 デメリット - ベロシティの不安定化 - 中長期スケジュール見積もりの困難 - 会議コストの増加 今後の改善 - 2週間スプリントへの移行を検討 - より安定したベロシティの確立 11
RTBシステムの特徴 - 設計 C4 Modelsは、ソフトウェアアーキテクチャを4つの抽象レベルで表現する設計手法です。 従来のUMLや複雑な設計書に比べ、ステークホルダー全員が理解しややすい図で表現できます。 4階層の構成 • Level 1
(Context): システム全体と外部システムとの関係 • Level 2 (Container): システム内の主要コンポーネントと技術スタック • Level 3 (Component): 各コンテナ内部の詳細設計 • Level 4 (Code): クラス図やシーケンス図レベルの実装詳細 DDDとC4 Modelsの組み合わせにより、複雑なドメインを適切に設計・可視化できます。 チーム全員での設計議論が活発化し、より良い設計につながりました。 12
RTBシステムの特徴 - 実装 Clean Architecture 依存関係の制御 - MVCアーキテクチャの密結合問題解決 - ビジネスロジックの外部技術からの独立
- レイヤー間の責務分離 テスタビリティの向上 - 依存性注入とインターフェース活用 - 外部APIやデータベースのモック化 - 純粋なビジネスロジックのテスト 変更容易性の確保 - 特定層の変更が他層に影響しにくい構造 - データベース変更時のリポジトリ層のみ修正 レイヤー構成と責務 - Controller: HTTP、外部とのデータ変換 - UseCase: ワークフロー、アプリ固有ルール - Entity: ドメインモデル、ビジネスロジック - Repository: DB/APIなど外部技術の詳細実装 依存関係の方向性 13 - 外側の層は内側の層に依存 - 内側の層は外側の層を知らない - インターフェースによる疎結合 Controller → UseCase → Entity
RTBシステムの特徴 - 構築 マイクロサービス 機能ごとにマイクロサービスとして構築してい ます。マイクロサービスには、以下のものがあ ります。 • info API:
SDKからのリクエストを受け、 オークションAPIを使ってオークション処 理を行い、レスポンスを構築する。 • オークションAPI: オークション処理を行 い、広告コンテンツをストレージに保 存。 • Ad API: 広告コンテンツを応答する。 • DSP Notifier: オークション結果をDSPに 通知する。 CI/CDパイプライン GitHubActionsとCloudDeployを利用しています。 14
RTBシステムの Observabilityについて 15
Observabilityの三本柱 📝 ログ (Logs) イベントの詳細情報を記録 • 構造化ログ: JSON形式で の統一 •
コンテキスト: TraceIDと の関連付け • 検索性: クエリによる高速 検索 16 🔍 トレース (Traces) リクエストの流れを追跡 • レイテンシ分析: ボトル ネックの特定 • 依存関係: サービス間の関 係性把握 • エラー伝搬: 障害の原因追 跡 📊 メトリクス (Metrics) システムの健康状態を数値で把握 • エラー率: HTTP 4xx/5xx エラーの割合 • スループット: 秒間リクエ スト数 • リソース使用率: CPU・メ モリ・ネットワーク
Observability - ログ Cloud Logging SDKを利用しています。 これにより、Traceのような直感的なKeyで構造化ログを書き 込むことができます。 (逆に使わない場合、"logging.googleapis.com/trace"と いった分かりづらいKeyが必要。)
17 ## ログ出力例 { "severity": "INFO", "trace": "projects/gree-peridot/traces/37e8e45b2fc23fd035b235bcc3a58555", "spanId": "9fb57bf9f69ab602", "logName": "projects/gree-peridot/logs/info", "jsonPayload": { … }, ... } func (l *LoggingClient) OutputSpan(...) { entry := logging.Entry{ Severity: severity, Trace: fmt.Sprintf("projects/%s/traces/%s", l.projectID, traceID), SpanID: spanID, Payload: payload, } logger.Log(entry) ログパッケージ設計 ログ出力例
Observability - トレース - トレースの各要素は、スパンと呼ばれる。こ のスパンは、実装で範囲を決める。 - ログにtraceIdとspanIdを追加すると、トレー スとログを紐付けることができる。 18
_, span := tracer.Start(ctx, "AuctionEntity", trace.WithSpanKind(trace.SpanKindInternal), trace.WithAttributes( attribute.String("component", "info"), attribute.String("layer", "entity"), ), ) defer span.End() traceID := span.SpanContext().TraceID().String() spanID := span.SpanContext().SpanID().String() e.logger.OutputJsonSpan(..., traceID, spanID, トレーシング実装
Observability - メトリクス - システムメトリクスは自動収集される。 - ビジネスメトリクスは明示的に送信する必要 がある。 19 meter
:= otel.GetMeterProvider().Meter("adfurikun-business") auctionCounter, _ := meter.Int64Counter( "business_auctions_total", metric.WithDescription("Total number of auctions processed"), ) m.auctionCounter.Add(ctx, 1, metric.WithAttributes( attribute.String("auction_type", auctionType), ), ) ビジネスメトリクス実装例
一貫したトレースの実現方法 20
課題: GCPとアプリケーションのトレース連携 Cloud Load BalancingとGKEアプリケーション間のトレース情報の問題 21 Application Span (ルートスパン) ├──
Business Logic Span └── Request └── Other Micro Service └── Business Logic Span Load Balancer Span (見えない) └── Application Span (孤立) ├── Business Logic Span └── Request Other Micro Service └── Business Logic Span 実際の結果 全体のトレースが確認できない。 期待していたトレース RTBシステムは、複数のマイクロサービスを使って HTTPリクエストを処理する。 HTTP Request全体のトレースを確認したい。
解決策1: トレース情報の伝播 トレース情報の伝播はPropagatorの責務。そこで、以下のようにPropagatorを設定。 22 Load Balancer Span (見えない) └── Application
Span (孤立) ├── Business Logic Span └── Request └── Other Micro Service └── Business Logic Span これにより階層構造になったが、ルートスパンが見えないため探しづらい。 X-Cloud-Trace-Context: TRACE_ID/SPAN_ID;o=TRACE_TRUE HTTP RequestのHeaderに付与されるTRACE_IDがリクエスト側から引き継がれるようになる。 otel.SetTextMapPropagator( propagation.NewCompositeTextMapPropagator( gcppropagator.CloudTraceFormatPropagator{},... )) Load Balancer Spanが見えないのは、Load BalancerがSpan情報をCloud Traceに送信できないため。 それなら、消してしまおう。
解決策2: Load Balancer Spanの削除 // middlewareが生成するスパンにattributeを設定 otelfiber.WithCustomAttributes(func(...) ... { return
[]attribute.KeyValue{ // middlewareで生成するスパンに印をつける attribute.Bool("parent_span_is_lb", true), }}), processors: # otelFiberのMiddlewareで作成したスパンの親スパン IDを削除する transform: trace_statements: - context: span conditions: # 条件に一致するスパンの親スパン ID を持つ場合 - span.attributes["parent_span_is_lb"] == true statements: # 条件に一致するスパンの親スパン ID を削除 - set(span.parent_span_id, SpanID(0x00000)) # span情報を編集したことを記録 - set(span.status.message, "span edited") 23 Application Span (ルートスパン) ├── Business Logic Span └── Request └── Other Micro Service └── Business Logic Span トレース表示 期待通りの表示となった。 OpenTelemetry Collector設定 Application Spanの親スパン情報を消し、ルートスパンと した。 アプリケーション側の実装
OTTL実装の詳細 OTTL構文の解説 バージョン注意点 OTTLの仕様は変更されることがあります 24 よく使用される関数 - set(): 値の設定 -
delete_key(): キーの削除 - replace_pattern(): パターン置換 - truncate_all(): 文字列の切り詰め 主要な構文要素 - context: 処理対象の指定(span, spanevent, metric, log) - conditions: 変換を適用する条件 - statements: 実際の変換処理 transform: trace_statements: - context: span # スパンコンテキスト で処理 conditions: # 条件部分 - span.attributes["parent_span_is_lb"] == true statements: # 実行部分 - set(span.parent_span_id, SpanID(0x00000)) - set(span.status.message, "span edited") 他のプロセッサーとの使い分け - Filter Processor: 単純なフィルタリング - Attributes Processor: 属性の追加・削除 - Transform Processor: 複雑な変換ロジック 用途に応じて適切なプロセッサーを選択することが重要 # v0.120.0以降 processors: transform: trace_statements: - context: span statements: - set(span.parent_span_id, SpanID(0x00000)) # v0.120.0以前 processors: transform: trace_statements: - context: span statements: - set(parent_span_id, SpanID(0x00000))
今後の展望 25
CloudDeployとPrometheusの連携によるカナリアデプロイ 課題 - リスクの高いデプロイ: 一度に全てのトラ フィックが新バージョンに流れる - 障害の影響範囲: 問題発生時に全ユーザーに影 響
- ロールバック時間: 手動での判断と実行が必要 RTBシステム特有の要件 - 低レイテンシ: 50ms以下のレスポンス要求 - 高可用性: 99.9%以上の稼働率必要 - 収益への直接影響: デプロイ失敗が売上に直結 自動判定指標 - エラー率: 0.1%以下を維持 - レスポンス時間: P99で50ms以下 - DSP成功率: 95%以上 - 収益指標: 前バージョン比で5%以上の下落なし 26 現在のデプロイフロー カナリアデプロイフロー
まとめ 27
まとめ • アドフリくんを導入することで、メディアの広告収益を最大化することが できます。 • アドフリくんは、継続的に改善を行う仕組みとなっています。 • 同様の取り組みを行うことで、担当プロジェクトが継続的な改善可能とな ります。 28
ご清聴ありがとうございました 29
None