1

シンプルな REST スタイルの HTTP 投稿を介して、継続的に実行され、頻繁に (平均して 1 秒あたり 1 回以上) 外部 API を呼び出すプロセスを最適化しようとしています。私が気づいたことの 1 つは、現在、HttpUrlConnection が作成され、次の構造に従ってすべての API 呼び出しに対して閉じられていることです (重要でないコードとエラー処理は読みやすくするために削除されています)。

//every API call
try {
  URL url = new URL("..remote_site..");
  conn = (HttpURLConnection) url.openConnection();
  setupConnectionOptions(conn); //sets things like timeoout and usecaches false
  outputWriter = new OutputStreamWriter(new BufferedOutputStream(conn.getOutputStream()));
  //send request
} finally {
  conn.disconnect();
  outputWriter.close();
}

httpプロトコルを直接扱った経験はあまりありませんが、一般的なソケットの常識/知識に基づいて、接続を一度だけ作成して再利用し、再初期化するだけの方がはるかに効率的であるように思われます問題が発生した場合、毎回接続ネゴシエーションを回避するには、次のようにします。

//on startup, or error
private void initializeConnection()
{
  URL url = new URL("..remote_site..");
  conn = (HttpURLConnection) url.openConnection();
  setupConnectionOptions(conn); //sets things like timeoout and usecaches false
}

//per request
try {
  outputWriter = new OutputStreamWriter(new BufferedOutputStream(conn.getOutputStream()));
  //send request
} catch (IOException) {
  try conn.disconnect();
  initializeConnection();
} finally {
  outputWriter.close();
}

//on graceful exit
conn.disconnect();

私の質問は次のとおりです。

  • これは一般的に合理的な最適化ですか (速度の向上は顕著でしょうか)?

はいと仮定します:

  • 出力ストリームと接続を再利用する必要がありますか?
  • エラー時にのみ接続を再初期化するのは合理的ですか、それとも特定の数のリクエスト/時間の後に再初期化する必要がありますか?
4

1 に答える 1

2

基本的に、はい、そして多くの時間を節約できます --- ソケットのセットアップにはかなりの労力がかかり、SSL の場合はさらに悪化します。そのため、昔は「キープアライブ」が実装されていました。これは REST の哲学に少し反するものですが、パフォーマンスの最適化です。

1 つ言えることは、ソケットは限られたリソースであるということです。非常に頻繁に使用される環境では、新しい接続用のソケットがなくなる可能性があります。これは悪いことです。

于 2008-12-19T22:08:03.993 に答える