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
160
障害を回避する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
Eight Engineering Unit 紹介資料
sansan33
PRO
0
3.2k
データプレーンプログラミングとは? DPU&スイッチASICの開発経験から語る
ebiken
PRO
1
270
Java 30周年記念! Javaの30年をふりかえる
skrb
2
1.3k
Digitization部 紹介資料
sansan33
PRO
1
3.8k
Devin&Cursor、それぞれの「本質」から導く最適ユースケース戦略
empitsu
8
2.5k
AIに実況させる / AI Streamer
motemen
3
1.4k
カンファレンスのつくりかた / The Conference Code: What Makes It All Work
tomzoh
8
930
会社員しながら本を書いてきた知見の共有
sat
PRO
3
690
やさしいClaude Code入門
minorun365
PRO
32
25k
アプリケーションの中身が見える!Mackerel APMの全貌と展望 / Mackerel APMリリースパーティ
mackerelio
0
450
積み上げられた技術資産と向き合いながら、プロダクトの信頼性をどう守るか
plaidtech
PRO
0
940
大規模PaaSにおける監視基盤の構築と効率化の道のり
lycorptech_jp
PRO
0
180
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
41
2.6k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.5k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
52
2.8k
Unsuck your backbone
ammeep
671
58k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Git: the NoSQL Database
bkeepers
PRO
430
65k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
123
52k
The Cult of Friendly URLs
andyhume
78
6.4k
A Tale of Four Properties
chriscoyier
159
23k
The Cost Of JavaScript in 2023
addyosmani
49
8.1k
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