Upgrade to Pro — share decks privately, control downloads, hide ads and more …

障害を回避するHttpClient再入門 / Avoiding Failures HttpCl...

障害を回避するHttpClient再入門 / Avoiding Failures HttpClient Reintroduction

JJUG CCC 2025 Spring で発表したスライドです

Avatar for Yusuke Uehara

Yusuke Uehara

June 06, 2025
Tweet

More Decks by Yusuke Uehara

Other Decks in Technology

Transcript

  1. 自己紹介
 
 Yusuke Uehara
 X,GitHub : uskey512 
 STORES 株式会社

    
 バックエンド8年/フロントエンド2年
 Spring Boot, React 開発・運用・監査対応
 2
  2. 目次
 • HttpClient 再入門 
 ◦ HttpClientとはなにか・何をしてくれるか 
 ◦ 代表的な実装の紹介と選定基準

    
 ◦ 障害になるポイント・機能・原因 
 • 障害事例1. 意図通り動作しないタイムアウト
 ◦ タイムアウトの設定と難解さ 
 ◦ 対策と考慮すべきポイント 
 • 障害事例2. 使っていないはずのHttpClient
 ◦ 使っていないはずのHttpClientを見つける 
 ◦ 対策と考慮すべきポイント 
 5
  3. HttpClientではない
 HttpURLConection
 HttpClientとはなにか -HttpClient/それ以外-
 9 Socket
 (SSLSocket)
 SocketChannel
 HttpClient (大きい括り)

    
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …

  4. HttpClientではない
 HttpURLConection
 HttpClientとはなにか -HttpClient/それ以外-
 10 Socket
 (SSLSocket)
 SocketChannel
 HttpClient (大きい括り)

    
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …
 役割
 ・HTTPの操作を抽象化 
  ・接続管理
  ・データの送受信
 ・その他実用上で便利になる 
  様々な補助機能を追加 

  5. HttpURLConection
 HttpClientとはなにか -HttpClient内での分類-
 11 Socket
 (SSLSocket)
 SocketChannel
 HttpClient
 高機能HttpClient /

    HttpClientラッパー 
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …

  6. HttpURLConection
 HttpClientとはなにか -HttpClient内での分類-
 12 Socket
 (SSLSocket)
 SocketChannel
 HttpClient
 高機能HttpClient /

    HttpClientラッパー 
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …
 ・宣言的クライアント 
 ・RESTクライアント
 ・フレームワーク特化 
 内部でHttpClientを利用 
 ・通信の確立と維持管理 
 ・HTTP 送受信処理 
 ・補助機能 (各実装に依存) 

  7. HttpURLConection
 HttpClientとはなにか -HttpClient内での分類-
 13 Socket
 (SSLSocket)
 SocketChannel
 HttpClient
 高機能HttpClient /

    HttpClientラッパー 
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …
 ・宣言的クライアント 
 ・RESTクライアント
 ・フレームワーク特化 
 内部でHttpClientを利用 
 ・通信の確立と維持管理 
 ・HTTP 送受信処理 
 ・補助機能 (各実装に依存) 
 今日のテーマはココ 

  8. HttpClientは何をしてくれるか
 • HTTPリクエスト/レスポンスの送受信
 • コネクションプールと接続の再利用
 • タイムアウト, バックオフ, リトライの統合
 •

    TLS/SSLハンドシェイク, 証明書検証
 • 非同期, 並列実行モデルの提供
 • HTTP/2, HTTP/3対応
 • 自動リダイレクト・Cookie管理
 • 認証・プロキシ・ヘッダ共通処理
 • 圧縮(gzip/deflate)の透過処理
 • etc.
 15
  9. 代表的な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
  10. 代表的なHttpClient実装 -選定基準-
 単なるREST APIを利用するだけならあまり差は無い前提で 
 Apache HttpClient
 • 高度な認証を利用したい、特殊な要件に対応したい、過去資産があるなどの場合 


    • 高い耐障害性を出すこともできるが設定はチューニング前提 
 OkHttp
 • Androidでは一択。サーバサイドでも新規開発なら利用したい 
 • デフォルト設定が堅実で障害に強い (自動リトライ・IPフォールバック) 
 Java11 HttpClient
 • カスタマイズ性がそこまで必要ない、外部ライブラリへの依存を避けたい 
 • 外部ライブラリのバージョン管理や脆弱性対策が不要になる 
 18
  11. HttpURLConection
 HttpClient のどこで障害が発生するのか
 20 Socket
 (SSLSocket)
 SocketChannel
 HttpClient
 高機能HttpClient /

    HttpClientラッパー 
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …

  12. HttpURLConection
 HttpClient のどこで障害が発生するのか
 21 Socket
 (SSLSocket)
 SocketChannel
 HttpClient
 高機能HttpClient /

    HttpClientラッパー 
 Java 11
 HttpClient
 OkHttp
 Apache
 HttpClient
 RestClient
 Retrofit
 OpenFeign
 …
 …
 この部分

  13. HttpClient のどの機能で障害が発生するのか
 
 • HTTPリクエスト/レスポンスの送受信
 • コネクションプールと接続の再利用
 • タイムアウト, バックオフ,

    リトライの統合
 • TLS/SSLハンドシェイク, 証明書検証
 • 非同期, 並列実行モデルの提供
 • HTTP/2, HTTP/3対応
 • 自動リダイレクト・Cookie管理
 • 認証・プロキシ・ヘッダ共通処理
 • 圧縮(gzip/deflate)の透過処理
 • etc.
 22
  14. HttpClient のどの機能で障害が発生するのか
 • HTTPリクエスト/レスポンスの送受信
 • コネクションプールと接続の再利用 
 • タイムアウト, バックオフ,

    リトライの統合 
 • TLS/SSLハンドシェイク, 証明書検証
 • 非同期, 並列実行モデルの提供
 • HTTP/2, HTTP/3対応
 • 自動リダイレクト・Cookie管理
 • 認証・プロキシ・ヘッダ共通処理
 • 圧縮(gzip/deflate)の透過処理
 • etc.
 23 この部分

  15. 目次
 • HttpClient 再入門
 ◦ HttpClientとはなにか・何をしてくれるか 
 ◦ 代表的な実装の紹介と選定基準 


    ◦ 障害になるポイント・機能・原因 
 • 障害事例1. 意図通り動作しないタイムアウト 
 ◦ タイムアウトの設定と難解さ 
 ◦ 対策と考慮すべきポイント 
 • 障害事例2. 使っていないはずのHttpClient
 ◦ 使っていないはずのHttpClientを見つける 
 ◦ 対策と考慮すべきポイント 
 25
  16. 障害その1 - 意図通り動作しないタイムアウト - 1 
 
 
 
 前提


    • Apache HttpClient を利用している
 • 外部APIサーバへの接続は確立できていた
 • ただし、レスポンス全体に時間がかかっている
 上記の設定でリクエストが打ち切られるのは何秒後になるか?
 27 RequestConfig config = RequestConfig.custom() .setConnectionRequestTimeout(2000) // 2秒 .setConnectTimeout(3000) // 3秒 .setSocketTimeout(10000) // 10秒 .build(); // 合計15秒?
  17. 障害その1 - 意図通り動作しないタイムアウト - 2 
 打ち切られない
 • connectionRequestTimeout
 ◦

    コネクションプールから接続を取得する際のタイムアウト 
 ◦ HttpClient内での待ち時間 
 • connectTimeout
 ◦ 接続先サーバとTCPハンドシェイクが完了するまでのタイムアウト 
 ◦ 接続先サーバとの通信を確立するための待ち時間 
 • socketTimeout
 ◦ Socketに流れてくるパケット間のタイムアウト 
 ◦ 次のデータが送られてくるまでの待ち時間 
 29
  18. 障害その1 - 意図通り動作しないタイムアウト - 2 
 打ち切られない
 • connectionRequestTimeout
 ◦

    コネクションプールから接続を取得する際のタイムアウト 
 ◦ HttpClient内での待ち時間 
 • connectTimeout
 ◦ 接続先サーバとTCPハンドシェイクが完了するまでのタイムアウト 
 ◦ 接続先サーバとの通信を確立するための待ち時間 
 • socketTimeout
 ◦ Socketに流れてくるパケット間のタイムアウト 
 ◦ 次のデータが送られてくるまでの待ち時間 
 30
  19. 障害その1 - 意図通り動作しないタイムアウト - 3 
 • サーバに接続"は"できる
 • レスポンス"も"返ってくる


    • ただし、とても遅い
 
 このような場合、先の設定例では
 タイムアウトに引っかからない
 
 
 31
  20. 障害その1 - 意図通り動作しないタイムアウト - 3 
 • サーバに接続"は"できる
 • レスポンス"も"返ってくる


    • ただし、とても遅い
 
 このような場合、先の設定例では
 タイムアウトに引っかからない
 
 本来欲しいのはリクエスト全体での
 タイムアウト設定
 Hard Timeout とも呼ばれる
 32
  21. 障害その1 - 意図通り動作しないタイムアウト - 4 
 リクエスト全体を制限するタイムアウトを設定する項目
 • Apache HttpClient

    : 無し
 • OkHttp : callTimeout
 • Java 11 HttpClient : HttpRequest.timeout
 
 HttpClient実装毎に設定できるタイムアウトは複数種類あるが
 それぞれ設定できる箇所や名前の意図するところが異なる
 他実装での設定が一対一で対応しない
 34
  22. 障害その1 - 意図通り動作しないタイムアウト - まとめ 
 タイムアウトやリトライなどの設定項目について
 
 • 各種設定値のリファレンスやソースを注意して読む


    ◦ 理解が不正確なまま書かれている二次資料も多い
 ◦ 賢い生成AIでも間違える
 • 異常時の処理について検証を行って実際の挙動を確認する
 ◦ CharlesなどのProxyで試したりサーバを書いて試すなど
 ◦ 本来はここまで試したい
 35
  23. 目次
 • HttpClient 再入門
 ◦ HttpClientとはなにか・何をしてくれるか 
 ◦ 代表的な実装の紹介と選定基準 


    ◦ 障害になるポイント・機能・原因 
 • 障害事例1. 意図通り動作しないタイムアウト
 ◦ タイムアウトの設定と難解さ 
 ◦ 対策と考慮すべきポイント 
 • 障害事例2. 使っていないはずのHttpClient 
 ◦ 使っていないはずのHttpClientを見つける 
 ◦ 対策と考慮すべきポイント 
 36
  24. 39

  25. 障害その2 - 使っていないはずのHttpClient - 2
 コード内で直接HttpClientを使っていなければ大丈夫!
 とはならないのが要注意ポイント
 
 • 使ってるのREST

    APIじゃなくてGraphQLだから関係なさそう
 • アプリケーションコード内でHttpClient使ってないし関係なさそう
 
 
 
 
 40
  26. 障害その2 - 使っていないはずのHttpClient - 2
 コード内で直接HttpClientを使っていなければ大丈夫!
 とはならないのが要注意ポイント
 
 • 使ってるのREST

    APIじゃなくてGraphQLだから関係なさそう
 • アプリケーションコード内でHttpClient使ってないし関係なさそう
 とはならない
 
 外部へ通信する処理を持つ ${任意の技術} のJavaライブラリについて
 通信部分の処理は内部のHttpClientに委譲されていることがしばしばある
 41
  27. 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
 …

  28. 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
  やってることはほぼ同じ 

  29. 障害その2 - 使っていないはずのHttpClient - まとめ 
 通信を伴うライブラリ・SDKを利用するにあたって
 
 • デフォルト設定を過信しない


    ◦ 引数が少ないコンストラクタを警戒する
 ◦ 外からどんな項目を設定できるのか調べる
 ◦ 最適な値はそれぞれ異なるので適切な値は何かを考える
 • 内部で何が動いているのかについてイメージする
 ◦ 通信部がどうなっているか
 ◦ どこにリスクがあるかを考える
 44
  30. 漏れのある抽象化の法則 (Joel on Software)
 すべての非自明な抽象化は、ある程度漏れるものだ 
 All non-trivial abstractions, to

    some degree, are leaky. 
 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう
 45
  31. 漏れのある抽象化の法則 (Joel on Software)
 すべての非自明な抽象化は、ある程度漏れるものだ 
 All non-trivial abstractions, to

    some degree, are leaky. 
 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう
 • HTTPリクエストを送信したいだけなのに
 TCPレイヤのSocketやSocketTimeoutについて理解をする必要がある
 • 外部サービスのSDKを利用して機能を便利に使いたいだけなのに
 HTTPレベルではどのような制御がされているかを調べる必要がある
 
 46
  32. 漏れのある抽象化の法則 (Joel on Software)
 すべての非自明な抽象化は、ある程度漏れるものだ 
 All non-trivial abstractions, to

    some degree, are leaky. 
 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう
 • HTTPリクエストを送信したいだけなのに
 TCPレイヤのSocketやSocketTimeoutについて理解をする必要がある
 • 外部サービスのSDKを利用して機能を便利に使いたいだけなのに
 HTTPレベルではどのような制御がされているかを調べる必要がある
 → 抽象化の下層を追わざるを得ない状況は必ず来る
 47
  33. 漏れのある抽象化の法則 (Joel on Software)
 すべての非自明な抽象化は、ある程度漏れるものだ 
 All non-trivial abstractions, to

    some degree, are leaky. 
 抽象化が隠してくれるはずの下層の細部が思わぬところで表に出てきてしまう
 • HTTPリクエストを送信したいだけなのに
 TCPレイヤのSocketやSocketTimeoutについて理解をする必要がある
 • 外部サービスのSDKを利用して機能を便利に使いたいだけなのに
 HTTPレベルではどのような制御がされているかを調べる必要がある
 → 抽象化の下層を追わざるを得ない状況は必ず来る、と腹をくくれる!
 48
  34. まとめ
 これまでの発表で以下の情報を提供しました
 • HttpClientが何をしてくれるかが改めてわかる
 ◦ HttpClientの分類を行い、どのような機能があるのかを改めて確認しました 
 • 代表的なHttpClientについて特徴や選定基準がわかる
 ◦

    Apache HttpClient, OkHttp, Java11 HttpClientについて特徴と比較をしました 
 • 障害の例を踏まえて実装時に気をつけるポイントがわかる
 ◦ 2つの事例を踏まえて、HttpClientの設定時に気をつける箇所 
 外部サービスのSDKを利用する際に注意するべき箇所を紹介しました 
 
 49