6

更新(結果に興味がある人向け:)

chrome と node-http2 サーバーの間の次のプロトコル ネゴシエーションが失敗する理由を理解できませんでした。私の疑いは、自己署名証明書または ALPN/NPN サポートの問題でした。そこで、 golang HTTP/2 実装に移行しました。同じセットアップが完全に機能し、単一の多重化された TCP 接続が表示されます (chrome --> golang)


私は HTTP/2 について読んでいて、ホストごとに単一の多重化された TCP 接続を使用して HTTP/1.1 のレイテンシの問題を解決する方法を読んでいたので、試してみることにしました。

実験

  • 1 つの css、1 つの js、およびいくつかの画像への参照を含む単純な html ファイルを作成しました。
  • これらすべてのファイルを提供する Node.js の単純な http サーバー
  • クロムを使用して http リクエストを作成しました
  • Ubuntu で tcptrack ( tcptrack ) を使用して、http サーバーに対して行われている TCP 接続を追跡しました。

tcptrack ウィンドウには、確立された 4 つの接続が表示されます。そのため、ブラウザは画像と css/js リクエストに対して異なる接続を開いています。

Chrome からの http/1.1 リクエストの TCP トラック出力

tcpdump を使用して同様の出力を取得します。参考までに、使用した tcptrack コマンドは

tcptrack -d -i eth0 -r 3600 ポート 8989

および tcpdump も同様の出力を示します

tcpdump -i eth0 -nns 0 "dst ポート 8989 および tcp[tcpflags] == tcp-syn"

これらのファイルを提供する単純なオールインワン http サーバーは、以下のようなものでした (関連するコード)

(function(){
  ...........
  var server = http.createServer(function(request, response) {
      ..........
      fs.readFile(filetoRet, function (err,data) {
      if(filePath.indexOf(".jpg") >-1){
        response.writeHead(200, {"Content-Type": "image/jpg"});
      }.....
      
      response.write(data);
      response.end();
      });

   
  });
   

  server.listen(8989);  
})()

この後、http/2 を使用してみました。

  • http/2 リクエストを送信するための chrome フラグを有効にしました
  • node-http2を使用して http/2 サーバーを作成しました
  • 単純な http サーバーは、手順 2 でインストールした http2 サーバー モジュールを使用することを除いて、http/1.1 と同じコードを持っています。
  • chrome を使用してリクエストを作成しました (HTTP/2 仕様に準拠した https リクエストである必要がありました)
  • キャプチャされた tcptrack/tcpdump 出力

http/2 の tcptrack 出力

したがって、これはまだ複数の TCP 接続が行われていることを示しています。また、html 内の画像の数を増やすと、接続数が増えます。

ですから、これをどう読んでいいのかわかりません。これは HTTP/2 の動作方法ですか (またはこれはクロムのバグですか)? 単純な http/2 クライアント サーバーを使用して HTTP/2 の利益を視覚化するより良い方法はありますか?

注:私はHTTP / 2サーバーに自己署名証明書を使用しているため、クロムはページに進む前に警告をスローし、閉じられた接続がそれを表している可能性がありますが、ページとそのコンポーネントがプロトコルによって要求される方法に影響を与えるべきではないと思います

これを読んでくださった皆さんの忍耐に感謝し、何か提案があれば感謝します。

シン

PS : Wireshark の TCP キャプチャも例外ではありません。ただ、Wireshark でトラフィックを分離するのが難しいことがわかったので、tcpdump と tcptrack を使用しました。

更新: 更新: chrome://net-internals/ を見ると、HTTP/2 要求のネゴシエーションが失敗し、HTTP/1.1 の使用にフォールバックします。理由はまだわかりません。

Chrome の内部ツール イベントが表示されます

t=879052 [st= 0] +HTTP_STREAM_JOB  [dt=19]
                  --> original_url = "https://msinghlinux.ads.com:8900/"
                  --> priority = "HIGHEST"
                  --> url = "https://msinghlinux.ads.com:8900/"
t=879052 [st= 0]   +PROXY_SERVICE  [dt=0]
t=879052 [st= 0]      PROXY_SERVICE_RESOLVED_PROXY_LIST
                      --> pac_string = "DIRECT"
t=879052 [st= 0]   -PROXY_SERVICE
t=879052 [st= 0]   +HOST_RESOLVER_IMPL_REQUEST  [dt=0]
                    --> address_family = 0
                    --> allow_cached_response = true
                    --> host = "msinghlinux.ads.com:8900"
                    --> is_speculative = false
t=879052 [st= 0]      HOST_RESOLVER_IMPL_CACHE_HIT
t=879052 [st= 0]   -HOST_RESOLVER_IMPL_REQUEST
t=879052 [st= 0]   +SOCKET_POOL  [dt=19]
t=879071 [st=19]      SOCKET_POOL_BOUND_TO_CONNECT_JOB
                      --> source_dependency = 26961 (CONNECT_JOB)
t=879071 [st=19]      SOCKET_POOL_BOUND_TO_SOCKET
                      --> source_dependency = 26967 (SOCKET)
t=879071 [st=19]   -SOCKET_POOL
t=879071 [st=19]    HTTP_STREAM_REQUEST_PROTO
                    --> next_proto_status = "negotiated"
                    --> proto = "http/1.1"
t=879071 [st=19]    HTTP_STREAM_JOB_BOUND_TO_REQUEST
                    --> source_dependency = 26910 (URL_REQUEST)
t=879071 [st=19] -HTTP_STREAM_JOB

次のプロトコルの値は http/1.1 (next_proto_status および proto) です。しかし、このフォールバックを引き起こしたネゴシエーションで何が失敗したかはわかりませんか? 自己署名証明書が原因でしょうか?

HTTP/2 サーバー コード

var options = {
  key: fs.readFileSync('./server.key'),
  cert: fs.readFileSync('./server.crt')
};

options.log = bunyan.createLogger(...);
require('http2').createServer(options,function(request, response) {
      .... same code as http/1.1 server


}).listen(8900);

4

1 に答える 1

1

実際には HTTP/2 を使用していないと思われます。FFにはプラグインがあり、アドレスバーで使用されているプロトコルを表示するChromeのオプションがあると思います。

HTTP2 では、さまざまな方法で待ち時間が短縮されることに注意してください。

単一の接続自体では、少なくともフロー制御ウィンドウが増加するまでは、最初はレイテンシが大幅に改善されることはありません。単一の接続のポイントは、ウィンドウを最適なサイズに拡大できることであり、新しい接続が作成されるたびに開始の遅延が遅くなるのを防ぐことができます。

ただし、HTTP/2 にはプッシュ メカニズムもあり、サーバーは CSS、JS、および画像がページに関連付けられていることを認識し、html を取得するためのリクエストと共にそれらをクライアントに積極的にプッシュします。これにより、HTML を解析してから新しい要求を送信するための往復時間が節約されます。リソースの数が 6 (HTTP1 のデファクト接続制限) を超える場合は、さらに多くのラウンドトリップが節約されます。

ウェブサイトで Jetty HTTP2 を実行しており、https: //webtide.com/http2-tests/push/ にデモをプッシュするページがあります。

その画像は多数の小さな画像から作成されており、HTTP/1 では個別に読み込まれる傾向がありますが、HTTP/2 を使用するとブロックとして読み込まれます。

于 2015-04-28T01:40:07.073 に答える