Apache HttpClientでKeep-Aliveを設定する

2020/10/30

java 開発

t f B! P L
記事内に広告が含まれています。

プログラムから外部のWeb APIを呼び出すことはよくあることで、HttpURLConnectionクラスを使ったり、OkHttpなどのライブラリを使ったりするようです。ちょっと古い?HttpClientを使っているプロジェクトで、HTTPのKeep Aliveを見直す必要があったので簡単にまとめます。

Apache HttpComponents

Apache Http Clientなんて聞きましたが、今ではApache HttpComponentsというようです。バージョンが上がるときにAPIが大きく変わったことがあるらしく、どのバージョンについて説明している記事か確認するように気をつけましょう。この記事では4.5について説明します。

Apache HttpComponents – HttpComponents HttpClient Overview

Although the java.net package provides basic functionality for accessing resources via HTTP, it doesn't provide the full flexibility or functionality needed by many applications. HttpClient seeks to fill this void by providing an efficient, up-to-date, and feature-rich package implementing the client side of the most recent HTTP standards and recommendations.

HTTP Keep-Alive

HTTPはステートレスなプロトコルなので、毎回サーバに繋いで処理が終わったら切断して、というのが基本です。が、いちいち繋ぎなおすのは効率がよくないため、接続しっぱなしにする、Keep-Aliveという仕組みがあります。Real World HTTPを読んでみるのがよいでしょう。


HTTP Connectionが維持される時間は?

HTTP/1.1では、Keep-Aliveがデフォルトです。

Connection: Close
のヘッダーをつけてサーバかクライアントがリクエスト/レスポンスを投げることで、明示的に接続を切断します。そうでない場合、タイムアウトするまでは接続が維持されます。

タイムアウト?何秒でタイムアウトするか、どこにも書いてありません。何秒にするか、決まりもないようです。Apache HTTP Serverで、Keep-Aliveの設定値を短めにしてサーバの負荷を下げるなんてことを見かけたこともあるので、サーバー管理者が適切な値を設定するもののようです。

問題なのは、何秒接続が維持されるのか、クライアント側にはわからないことです。クライアントが想定している維持時間(例えば60秒)よりも、サーバ側の設定が短い(例えば30秒)場合、クライアントでは、既に閉じられているコネクションを使おうとして、通信がエラーになります。エラーリトライすればよいのかもしれませんが、すぐにリトライしてよいものなのかどうか、判断する必要があります。

Keep-Aliveの拡張情報をApache Http Clientで使う

何秒接続が維持されるかわからないのでは不便だと思っている人は多いようで、Keep-Aliveのヘッダーを独自拡張しているサーバがあります。とあるApache http serverは

Keep-Alive: timeout=5, max=100
となっていましたし、Nginxでの動きを検証した記事もありました。

Nginx の keep-alive の設定と検証 - How old are you?

このエントリは nginx Advent Calendar 2014 の7日目です。 1 はじめに Webサーバを運用する時に気になる設定の1つとして keep-alive の設定があります。 今まで調べようと思ってできていなかったので、nginx Advent Calendar 2014 の勢いに乗って調べてみました。このエントリの概要は以下の通り。 クライアント Nginx 間の keep-a

では、Http Clientでどう対応すればよいかというと、チュートリアルにコードが載っています。

Connection keep alive strategy

The HTTP specification does not specify how long a persistent connection may be and should be kept alive. Some HTTP servers use a non-standard Keep-Alive header to communicate to the client the period of time in seconds ...

Keep-Aliveのtimeoutが検出できなかった場合のコードを少し手直しする必要がありますが、あとは使えそうです。ただ、

  • サーバから提示されたtimeoutをそのまま使う?(少し短めの値にしなくても大丈夫?)
  • timeoutの値がなかった場合、何秒にする?(チュートリアルのコードでは30秒になっているけど?)

といった部分は、検討した方がよいでしょう。

いい感じにやってくれるライブラリはそのうち?

Java11で、HTTPクライアントAPIは大幅に進化したようです。

イマドキのJava徹底入門(10) HTTP接続を劇的に改善したHTTPクライアントAPIとは?(その1)

Javaの標準APIでHTTP接続を行う場合、HttpURLConnectionクラスを使う方法が一般的だった。しかしこのクラスは実装が古く、HTTP/2プロトコルにも対応していないため、実用に耐えない。そこで、Java 11からHTTPクライアントAPIが登場した。今回は、この新しいAPIを使ってHTTP接続を行う方法を紹介する。

サードパーティーのhttp client ライブラリも、いろいろ進化することでしょう。HTTP/2に移行しないサーバもあるでしょうから、HTTP/1.1でも手間をかけずに効率的に利用できるようなライブラリが出てくることを期待しています。

人気の投稿

ブログ アーカイブ

自己紹介

ストックオプションを半分しか行使していなかったけど、パワハラをなぁなぁで済まそうとする会社から転職。アーリーリタイアを目指し、自分で稼ぐ術を模索中。

改正電気通信事業法に関する表記

・掲載内容

当サイトでは成果報酬型広告/クリック型広告の効果測定のため、利用者の方のアクセス情報を外部事業者に送信しております。
当該の情報は個人を特定する情報ではございません。また当該の情報が目的外利用される事は一切御座いません。

1.送信される情報の内容
  • 広告の表示日時
  • 広告のクリック日時
  • 広告の計測に必要なクッキー情報
  • 広告表示時及び広告クリック時のIPアドレス
  • 広告表示時及び広告クリック時に使用されたインターネット端末およびインターネットブラウザの種類
2.送信先となる事業者の氏名又は名称
  • グーグル合同会社
  • 楽天グループ株式会社
  • アマゾンジャパン合同会社
  • ヤフー株式会社
  • 株式会社ファンコミュニケーションズ
  • 株式会社もしも
3.利用目的

成果報酬型広告/クリック型広告の効果測定および不正防止のため

QooQ