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
障害を回避するHttpClient再入門 / Avoiding Failures HttpCl...
Search
Yusuke Uehara
June 06, 2025
Technology
1
150
障害を回避するHttpClient再入門 / Avoiding Failures HttpClient Reintroduction
JJUG CCC 2025 Spring で発表したスライドです
Yusuke Uehara
June 06, 2025
Tweet
Share
More Decks by Yusuke Uehara
See All by Yusuke Uehara
Content Security Policy入門 セキュリティ設定と 違反レポートのはじめ方 / Introduction to Content Security Policy Getting Started with Security Configuration and Violation Reporting
uskey512
2
1.3k
Other Decks in Technology
See All in Technology
AIのための オンボーディングドキュメントを整備する - hirotea
hirotea
9
2.3k
Slackひと声でブログ校正!Claudeレビュー自動化編
yusukeshimizu
3
180
Roo Codeにすべてを委ねるためのルール運用
pharma_x_tech
1
230
セキュリティSaaS企業が実践するCursor運用ルールと知見 / How a Security SaaS Company Runs Cursor: Rules & Insights
tetsuzawa
0
460
プラットフォームとしての Datadog / Datadog as Platforms
aoto
PRO
1
340
アプリケーションの中身が見える!Mackerel APMの全貌と展望 / Mackerel APMリリースパーティ
mackerelio
0
450
Java で学ぶ 代数的データ型
ysknsid25
1
520
Javaアプリケーションの配布とパッケージング / Distribution and packaging of Java applications
hogelog
1
250
ゴリラ.vim #36 ~ Vim x SNS ~ スポンサーセッション
yasunori0418
1
360
MCP で繋ぐ Figma とデザインシステム〜LLM を使った UI 実装のリアル〜
kimuson
2
1.3k
Devin&Cursor、それぞれの「本質」から導く最適ユースケース戦略
empitsu
8
2.5k
オープンソースのハードウェアのコンテストに参加している話
iotengineer22
0
650
Featured
See All Featured
KATA
mclloyd
29
14k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
19k
Typedesign – Prime Four
hannesfritz
41
2.6k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Designing for Performance
lara
608
69k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.6k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
GraphQLとの向き合い方2022年版
quramy
46
14k
Practical Orchestrator
shlominoach
188
11k
The World Runs on Bad Software
bkeepers
PRO
68
11k
Why You Should Never Use an ORM
jnunemaker
PRO
56
9.4k
Transcript
障害を回避する HttpClient 再入門 uskey512 / Yusuke Uehara @JJUG CCC 2025
Spring 2025-06-07
自己紹介 Yusuke Uehara X,GitHub : uskey512 STORES 株式会社
バックエンド8年/フロントエンド2年 Spring Boot, React 開発・運用・監査対応 2
発表のモチベーション 自社サービスの継続的な開発・運用を通じて 大小さまざまな障害が発生して、都度調査や対策を行ってきた 影響の大きい障害が発生した際、原因であることが多かった通信周り 事前にこの部分を深堀りしていれば回避・軽減出来たかもしれない… 実際にあった障害の例をあげて紹介して 似たような問題の発生を防ぐきっかけにしたい
3
本発表の主なターゲット・ゴール 主なターゲット • Javaで外部サービスを利用するシステム開発を行うエンジニア • HttpClient実装に少し詳しくなりたいエンジニア 本発表では皆さんに20分で以下の情報を提供することをゴールとします • HttpClientが何をしてくれるかが改めてわかる •
代表的なHttpClientについて特徴や選定基準がわかる • 実際に発生した障害の例を踏まえてより安全に使うためのポイントがわかる 4
目次 • HttpClient 再入門 ◦ HttpClientとはなにか・何をしてくれるか ◦ 代表的な実装の紹介と選定基準
◦ 障害になるポイント・機能・原因 • 障害事例1. 意図通り動作しないタイムアウト ◦ タイムアウトの設定と難解さ ◦ 対策と考慮すべきポイント • 障害事例2. 使っていないはずのHttpClient ◦ 使っていないはずのHttpClientを見つける ◦ 対策と考慮すべきポイント 5
HttpClientとはなにか HTTPリクエストを送信してHTTPレスポンスを受信するためのライブラリ 6
HttpClientとはなにか HTTPリクエストを送信してHTTPレスポンスを受信するためのライブラリ =ソケット通信+HTTPプロトコル+接続管理+その他 の面倒を肩代わりしてくれるもの 7
HttpClientとはなにか HTTPリクエストを送信してHTTPレスポンスを受信するためのライブラリ =ソケット通信+HTTPプロトコル+接続管理+その他 の面倒を肩代わりしてくれるもの ただ、一言で大きい括りでHttpClientとまとめてしまうと 指す範囲が広く様々な種類があるため、一旦全体を俯瞰して整理する 8
HttpClientではない HttpURLConection HttpClientとはなにか -HttpClient/それ以外- 9 Socket (SSLSocket) SocketChannel HttpClient (大きい括り)
Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … …
HttpClientではない HttpURLConection HttpClientとはなにか -HttpClient/それ以外- 10 Socket (SSLSocket) SocketChannel HttpClient (大きい括り)
Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … … 役割 ・HTTPの操作を抽象化 ・接続管理 ・データの送受信 ・その他実用上で便利になる 様々な補助機能を追加
HttpURLConection HttpClientとはなにか -HttpClient内での分類- 11 Socket (SSLSocket) SocketChannel HttpClient 高機能HttpClient /
HttpClientラッパー Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … …
HttpURLConection HttpClientとはなにか -HttpClient内での分類- 12 Socket (SSLSocket) SocketChannel HttpClient 高機能HttpClient /
HttpClientラッパー Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … … ・宣言的クライアント ・RESTクライアント ・フレームワーク特化 内部でHttpClientを利用 ・通信の確立と維持管理 ・HTTP 送受信処理 ・補助機能 (各実装に依存)
HttpURLConection HttpClientとはなにか -HttpClient内での分類- 13 Socket (SSLSocket) SocketChannel HttpClient 高機能HttpClient /
HttpClientラッパー Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … … ・宣言的クライアント ・RESTクライアント ・フレームワーク特化 内部でHttpClientを利用 ・通信の確立と維持管理 ・HTTP 送受信処理 ・補助機能 (各実装に依存) 今日のテーマはココ
HttpClientは何をしてくれるか 14
HttpClientは何をしてくれるか • HTTPリクエスト/レスポンスの送受信 • コネクションプールと接続の再利用 • タイムアウト, バックオフ, リトライの統合 •
TLS/SSLハンドシェイク, 証明書検証 • 非同期, 並列実行モデルの提供 • HTTP/2, HTTP/3対応 • 自動リダイレクト・Cookie管理 • 認証・プロキシ・ヘッダ共通処理 • 圧縮(gzip/deflate)の透過処理 • etc. 15
代表的なHttpClient実装 16
代表的なHttpClient実装 Apache HttpClient • 現代でも使われているHttpClientでは最も歴史がある • pros : 圧倒的な柔軟性と豊富な機能、拡張できるポイントが多い、知見が得やすい
• cons : 最新プロトコルや新技術への追従が遅い、使用方法がやや冗長で複雑 OkHttp • Square社が開発しているクライアント Androidでの事実上標準 • pros : 便利なデフォルト設定・追加機能の充実など(EventListener, Cache) • cons : 設定の自由度はApacheに劣る、実装言語がKotlinでデバッグ時が辛いかも Java11 HttpClient • Java11で標準搭載された HTTPクライアント • pros : 非同期通信, HTTP/2, WebSocket対応など比較的新しい機能が使える • cons : 高度な認証・自動圧縮展開(gzip等)・リトライが無く、細かな設定が行えない 17
代表的なHttpClient実装 -選定基準- 単なるREST APIを利用するだけならあまり差は無い前提で Apache HttpClient • 高度な認証を利用したい、特殊な要件に対応したい、過去資産があるなどの場合
• 高い耐障害性を出すこともできるが設定はチューニング前提 OkHttp • Androidでは一択。サーバサイドでも新規開発なら利用したい • デフォルト設定が堅実で障害に強い (自動リトライ・IPフォールバック) Java11 HttpClient • カスタマイズ性がそこまで必要ない、外部ライブラリへの依存を避けたい • 外部ライブラリのバージョン管理や脆弱性対策が不要になる 18
HttpClient のどこで障害が発生するのか 19
HttpURLConection HttpClient のどこで障害が発生するのか 20 Socket (SSLSocket) SocketChannel HttpClient 高機能HttpClient /
HttpClientラッパー Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … …
HttpURLConection HttpClient のどこで障害が発生するのか 21 Socket (SSLSocket) SocketChannel HttpClient 高機能HttpClient /
HttpClientラッパー Java 11 HttpClient OkHttp Apache HttpClient RestClient Retrofit OpenFeign … … この部分
HttpClient のどの機能で障害が発生するのか • HTTPリクエスト/レスポンスの送受信 • コネクションプールと接続の再利用 • タイムアウト, バックオフ,
リトライの統合 • TLS/SSLハンドシェイク, 証明書検証 • 非同期, 並列実行モデルの提供 • HTTP/2, HTTP/3対応 • 自動リダイレクト・Cookie管理 • 認証・プロキシ・ヘッダ共通処理 • 圧縮(gzip/deflate)の透過処理 • etc. 22
HttpClient のどの機能で障害が発生するのか • HTTPリクエスト/レスポンスの送受信 • コネクションプールと接続の再利用 • タイムアウト, バックオフ,
リトライの統合 • TLS/SSLハンドシェイク, 証明書検証 • 非同期, 並列実行モデルの提供 • HTTP/2, HTTP/3対応 • 自動リダイレクト・Cookie管理 • 認証・プロキシ・ヘッダ共通処理 • 圧縮(gzip/deflate)の透過処理 • etc. 23 この部分
HttpClient がきっかけで発生する障害の原因はなにか HttpClient単体が障害の直接の原因になることはほぼない 外部で発生した問題に巻き込まれてしまって障害の原因になる 障害の原因になりやすい理由 • タイムアウトやリトライなどの設定ミスは正常時はあまり問題にならない ◦ いざという時にどのように動作して欲しいかの設定
• 通信関連で発生する問題には様々なパターンが存在する ◦ 名前解決できない、500系のエラーが発生する、レスポンスが遅延する 24
目次 • HttpClient 再入門 ◦ HttpClientとはなにか・何をしてくれるか ◦ 代表的な実装の紹介と選定基準
◦ 障害になるポイント・機能・原因 • 障害事例1. 意図通り動作しないタイムアウト ◦ タイムアウトの設定と難解さ ◦ 対策と考慮すべきポイント • 障害事例2. 使っていないはずのHttpClient ◦ 使っていないはずのHttpClientを見つける ◦ 対策と考慮すべきポイント 25
障害その1 - 意図通り動作しないタイムアウト - 外部サービスAPIのレスポンスタイムが悪化して連鎖的に障害発生 HttpClientの設定で細かくタイムアウトは設定しているが 期待したタイムアウトを超過してレスポンスを待ち続けてしまい コネクションプールが枯渇してしまっていた
26
障害その1 - 意図通り動作しないタイムアウト - 1 前提
• Apache HttpClient を利用している • 外部APIサーバへの接続は確立できていた • ただし、レスポンス全体に時間がかかっている 上記の設定でリクエストが打ち切られるのは何秒後になるか? 27 RequestConfig config = RequestConfig.custom() .setConnectionRequestTimeout(2000) // 2秒 .setConnectTimeout(3000) // 3秒 .setSocketTimeout(10000) // 10秒 .build(); // 合計15秒?
障害その1 - 意図通り動作しないタイムアウト - 2 打ち切られない 28
障害その1 - 意図通り動作しないタイムアウト - 2 打ち切られない • connectionRequestTimeout ◦
コネクションプールから接続を取得する際のタイムアウト ◦ HttpClient内での待ち時間 • connectTimeout ◦ 接続先サーバとTCPハンドシェイクが完了するまでのタイムアウト ◦ 接続先サーバとの通信を確立するための待ち時間 • socketTimeout ◦ Socketに流れてくるパケット間のタイムアウト ◦ 次のデータが送られてくるまでの待ち時間 29
障害その1 - 意図通り動作しないタイムアウト - 2 打ち切られない • connectionRequestTimeout ◦
コネクションプールから接続を取得する際のタイムアウト ◦ HttpClient内での待ち時間 • connectTimeout ◦ 接続先サーバとTCPハンドシェイクが完了するまでのタイムアウト ◦ 接続先サーバとの通信を確立するための待ち時間 • socketTimeout ◦ Socketに流れてくるパケット間のタイムアウト ◦ 次のデータが送られてくるまでの待ち時間 30
障害その1 - 意図通り動作しないタイムアウト - 3 • サーバに接続"は"できる • レスポンス"も"返ってくる
• ただし、とても遅い このような場合、先の設定例では タイムアウトに引っかからない 31
障害その1 - 意図通り動作しないタイムアウト - 3 • サーバに接続"は"できる • レスポンス"も"返ってくる
• ただし、とても遅い このような場合、先の設定例では タイムアウトに引っかからない 本来欲しいのはリクエスト全体での タイムアウト設定 Hard Timeout とも呼ばれる 32
障害その1 - 意図通り動作しないタイムアウト - 4 リクエスト全体を制限するタイムアウトを設定する項目 • Apache HttpClient
: • OkHttp : • Java 11 HttpClient : 33
障害その1 - 意図通り動作しないタイムアウト - 4 リクエスト全体を制限するタイムアウトを設定する項目 • Apache HttpClient
: 無し • OkHttp : callTimeout • Java 11 HttpClient : HttpRequest.timeout HttpClient実装毎に設定できるタイムアウトは複数種類あるが それぞれ設定できる箇所や名前の意図するところが異なる 他実装での設定が一対一で対応しない 34
障害その1 - 意図通り動作しないタイムアウト - まとめ タイムアウトやリトライなどの設定項目について • 各種設定値のリファレンスやソースを注意して読む
◦ 理解が不正確なまま書かれている二次資料も多い ◦ 賢い生成AIでも間違える • 異常時の処理について検証を行って実際の挙動を確認する ◦ CharlesなどのProxyで試したりサーバを書いて試すなど ◦ 本来はここまで試したい 35
目次 • HttpClient 再入門 ◦ HttpClientとはなにか・何をしてくれるか ◦ 代表的な実装の紹介と選定基準
◦ 障害になるポイント・機能・原因 • 障害事例1. 意図通り動作しないタイムアウト ◦ タイムアウトの設定と難解さ ◦ 対策と考慮すべきポイント • 障害事例2. 使っていないはずのHttpClient ◦ 使っていないはずのHttpClientを見つける ◦ 対策と考慮すべきポイント 36
障害その2 - 使っていないはずのHttpClient - 外部向けに提供しているAPIサーバの 特定のエンドポイントでレスポンスタイムが悪化 メール送信機能を含むAPI呼び出しでレスポンスタイムが悪化 他のエンドポイントにも少しずつ波及し、スレッドが枯渇したことによって アプリケーションサーバ全体のレスポンスタイムが悪化
37
障害その2 - 使っていないはずのHttpClient - 1 一部機能内で明示的にHttpClientを利用している箇所は無かったが 外部サービスのSDKを利用しており、その外部サービスがダウンしていた 外部サービスSDKは更に別のSDKに依存しており 依存先のSDKが内包しているApache
HttpClientが完全に未設定 外部サービスSDKには初期化時にHttpClientを差し替える機能があったものの ドキュメント化されておらず取りこぼしてしまっていた 38
39
障害その2 - 使っていないはずのHttpClient - 2 コード内で直接HttpClientを使っていなければ大丈夫! とはならないのが要注意ポイント • 使ってるのREST
APIじゃなくてGraphQLだから関係なさそう • アプリケーションコード内でHttpClient使ってないし関係なさそう 40
障害その2 - 使っていないはずのHttpClient - 2 コード内で直接HttpClientを使っていなければ大丈夫! とはならないのが要注意ポイント • 使ってるのREST
APIじゃなくてGraphQLだから関係なさそう • アプリケーションコード内でHttpClient使ってないし関係なさそう とはならない 外部へ通信する処理を持つ ${任意の技術} のJavaライブラリについて 通信部分の処理は内部のHttpClientに委譲されていることがしばしばある 41
HttpURLConection 障害その2 - 使っていないはずのHttpClient - 3 42 Socket (SSLSocket) Socke
HttpClient 高機能HttpClient / HttpClientラッパー Java 11 HttpClient OkHt Apache HttpClient RestClient Retro OpenFeign GraphQLClient 外部サービス SDK Apollo Kotlin Netflix DGS … AWS Stripe SendGrid Spring GraphQL Client …
HttpURLConection 障害その2 - 使っていないはずのHttpClient - 3 43 Socket (SSLSocket) Socke
HttpClient 高機能HttpClient / HttpClientラッパー Java 11 HttpClient OkHt Apache HttpClient RestClient Retro OpenFeign GraphQLClient 外部サービス SDK Apollo Kotlin Netflix DGS … AWS Stripe SendGrid Spring GraphQL Client … ・高機能HttpClient ・SaaS SDK ・GraphQLClient やってることはほぼ同じ
障害その2 - 使っていないはずのHttpClient - まとめ 通信を伴うライブラリ・SDKを利用するにあたって • デフォルト設定を過信しない
◦ 引数が少ないコンストラクタを警戒する ◦ 外からどんな項目を設定できるのか調べる ◦ 最適な値はそれぞれ異なるので適切な値は何かを考える • 内部で何が動いているのかについてイメージする ◦ 通信部がどうなっているか ◦ どこにリスクがあるかを考える 44
漏れのある抽象化の法則 (Joel on Software) すべての非自明な抽象化は、ある程度漏れるものだ All non-trivial abstractions, to
some degree, are leaky. 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう 45
漏れのある抽象化の法則 (Joel on Software) すべての非自明な抽象化は、ある程度漏れるものだ All non-trivial abstractions, to
some degree, are leaky. 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう • HTTPリクエストを送信したいだけなのに TCPレイヤのSocketやSocketTimeoutについて理解をする必要がある • 外部サービスのSDKを利用して機能を便利に使いたいだけなのに HTTPレベルではどのような制御がされているかを調べる必要がある 46
漏れのある抽象化の法則 (Joel on Software) すべての非自明な抽象化は、ある程度漏れるものだ All non-trivial abstractions, to
some degree, are leaky. 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう • HTTPリクエストを送信したいだけなのに TCPレイヤのSocketやSocketTimeoutについて理解をする必要がある • 外部サービスのSDKを利用して機能を便利に使いたいだけなのに HTTPレベルではどのような制御がされているかを調べる必要がある → 抽象化の下層を追わざるを得ない状況は必ず来る 47
漏れのある抽象化の法則 (Joel on Software) すべての非自明な抽象化は、ある程度漏れるものだ All non-trivial abstractions, to
some degree, are leaky. 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう • HTTPリクエストを送信したいだけなのに TCPレイヤのSocketやSocketTimeoutについて理解をする必要がある • 外部サービスのSDKを利用して機能を便利に使いたいだけなのに HTTPレベルではどのような制御がされているかを調べる必要がある → 抽象化の下層を追わざるを得ない状況は必ず来る、と腹をくくれる! 48
まとめ これまでの発表で以下の情報を提供しました • HttpClientが何をしてくれるかが改めてわかる ◦ HttpClientの分類を行い、どのような機能があるのかを改めて確認しました • 代表的なHttpClientについて特徴や選定基準がわかる ◦
Apache HttpClient, OkHttp, Java11 HttpClientについて特徴と比較をしました • 障害の例を踏まえて実装時に気をつけるポイントがわかる ◦ 2つの事例を踏まえて、HttpClientの設定時に気をつける箇所 外部サービスのSDKを利用する際に注意するべき箇所を紹介しました 49