現在JavaScriptの設定が無効になっています。このページを利用するにはJavaScriptの設定を有効にしてください。参加報告はじめにこんにちは。Server(以下、ATS)のHTTP/2サポートに向けた活動の続報をお伝えします。Summitというイベントに参加した件について記述致します。HTTP/2やATSに関する基礎的な内容については以前の記事にて紹介させていただいていますので、本稿では割愛させていただきます。入門と前回の記事をご覧の上で本稿を読んでいただければ幸いです。ATSのHTTP/2サポートに向けた新たな活動まず前回以降のアップデートについて紹介致します。結論から申しあげますと、前回の記事で紹介したパッチはマージされない方向に進み、コミッタとの相談の結果新たにスクラッチで実装を進めることになりました。現在はコミッタと協力し新たな実装を進めております。その過程でいくつかのパッチを投稿し、そのうち半数程度は既にマージされています。実装の進捗としては、ある程度簡単な動作が確認できるプロトタイプが出来上がっている状態になっています。以前投げたパッチのその後2014年6月時点では、前回の記事でご紹介した通りオープンソースのHTTP/2ライブラリnghttp2を利用する形で実装を進め、パッチを投稿しました。その後コミッタと相談した結果、性能面の懸念やプラグイン向けのフックの提供の容易さから外部ライブラリに依存しない形での実装が望まれ、投稿したパッチはマージされない運びとなってしまいました。PeachによりHTTP/2フレーム処理の基礎部分のコードがコミットされました。この時のコードはHTTP/2セッションの開始と終了、フレームヘッダのパース、SETTINGSフレームのペイロードのパース、GOAWAYフレームの送信処理などHTTP/2フレーム処理の共通部分に関する内容であり、HTTP/2リクエストを処理可能なレベルまでは実装が進んでいませんでした。このコミットを受けて、私も引き続きATSのHTTP/2実装を進める旨を伝え、Jamesの実装を拡張する形で作業に着手し、その過程でいくつかのパッチを投稿しました。投稿したパッチの内容としては下記のものになります。draft-14への追従HPACKエンコーダ/デコーダ(詳細は後述)プロトタイプ実装(詳細は後述)これらのHTTP/2サポートに関するパッチ投稿や議論については、前回に引き続きATSのバグ管理がされているJIRAのチケット上で行っております。HPACKエンコーダ/デコーダの実装について上記の方針が決定してから、最初にHTTP/2の仕様の中でもHPACKと呼ばれる独自のヘッダ圧縮形式に関する実装に着手しました。HPACKのドラフトはHTTP/2とは分離されており、2014年11月現在draft-09が最新です。HPACKでは下記のような圧縮を行うことでヘッダサイズを削減します。使用されるヘッダのフィールド名もしくはフィールド名と値のペア(仕様であらかじめ定められている)をインデックスで参照可能にする以前送ったヘッダのフィールド名もしくはフィールド名と値のペアをインデックスで再参照可能にするヘッダのフィールド名もしくは値をハフマン符号化するHTTP/2でもHTTP/1.xと同様リクエストやレスポンスのメッセージがやり取りされる際にボディの前にヘッダをやり取りします。(HTTP/2ではHEADERSフレームとして表現されます)クライアントから送信されるリクエストヘッダの内容を解釈する為にHPACKデコーダを、クライアントにレスポンスヘッダを渡すためにHPACKエンコーダを実装する必要があります。HPACKエンコーダについては上記の圧縮方式をサポートしない最低限の実装を、デコーダについては上記全ての圧縮形式を網羅してかつヘッダフィールドとインデックスを対応付けるテーブルのサイズ変更機能の実装を行いパッチを投稿しました。(*1)このパッチについては既にマージされています。プロトタイプについて上記のHPACKエンコーダ、デコーダ実装に合わせて、下記のような機能追加を行いHTTP/2リクエストを処理可能なプロトタイプの実装を行いました。受信したHEADERS,DATA,CONTINUATIONフレームのハンドリングHTTP/2とHTTP/1.1のヘッダフォーマット相互変換オリジンサーバーへのリクエストのフォワードとそれに対するレスポンスのハンドリングHEADERS,DATAフレーム送信ここでは簡単にプロトタイプ実装でHTTP/2リクエストを処理できることを確認しました。実験環境としてローカルでATSとnginxを動作させ、ATSに到達したリクエストをnginxに転送するように設定した状態でnghttpでリクエストを送った際の出力を確認しました。nginxはここでは数行程度のシンプルなHTMLを返すようにします。下記出力内容により、正常にリクエストヘッダを解釈し、nginxへリクエストを転送し、レスポンスをクライアントに返すことができているのが分かります。opaque_data(0)=[])こちらのプロトタイプ実装のパッチもJIRAに投稿済です。パッチのファイル名はh2_prototype.patchです。現状十分にデバッグできておらず、HTTP/2レスポンスを返せるまで最低限必要な実装しか行っていないので、今後作り込む必要があります。実装の詳細に絡む話になってしまいますが、このプロトタイプの実装を進める上で「ATSが受けたHTTP/2リクエストをどのようにオリジンサーバーに転送するか」が課題となりました。ATSにおいてHTTP/1.1のトランザクションはこのドキュメントの図のようなフローで処理されます。これは大ざっぱに説明しますと下記のようになります。リクエストヘッダを読み、設定ファイルで対応付けられているオリジンサーバーを決定するキャッシュを探索する。キャッシュヒットすればそれを読み込む(キャッシュミスした場合は)オリジンサーバーからコンテンツを取得する。オリジンサーバーからのレスポンスがキャッシュ可能であれば新たにキャッシュするクライアントにレスポンスを返すこれらのトランザクション状態の管理や処理は現状、主にHttpSMとHttpTransactクラスによって担われています。HttpSMとHttpTransactはクライアントとATS間、ATSとオリジンサーバー間どちらもHTTP/1.xが使用されることを想定した実装がされており、今回のプロトタイプでサポートしたい「クライアントとATS間のみHTTP/2を使用し、ATSとオリジンサーバー間はHTTP/1.xを使用する」という構造にすることが容易ではありません。これらの実装はコードが複雑かつ行数も多く、既存の振る舞いを壊さずにクライアントとATS間のプロトコルを切替可能なよう修正するのは非常に難しい課題といえます。code”)この問題はSPDY対応の際にも直面しており、その際にはFetchSMを使用することになりました。FetchSMはプラグイン用に提供されているAPIの内部処理で使われており、これによりHTTP/1.1リクエストを発行することが可能です。現状ATSではSPDYリクエストが来た際にFetchSMを用いて自身にHTTP/1.1リクエストを投げ直すことでオリジンサーバーへのリクエストの転送を賄っています。FetchSMを用いることで実装上の問題は回避されるのですが、同時にいったんリクエストとレスポンスをHTTP/1.1でやり取りする際に無駄なメモリ間コピーやヘッダのパース処理などが発生しているという懸念点が存在します。今回作成したプロトタイプではSPDYと同様FetchSMを使用する形で実装しています。これはHttpSMやHttpTransactの構造を修正する困難さと、それらを含めた今後のHTTP/2実装の進め方に関して後述するATSSummitというイベントでコミッタ達と合意が取れたことによります。Summitというイベントがアメリカカリフォルニア州サニーベールのLinkedInのオフィスにて開催されました。JAPANから私を含めて2名が参加し、HTTP/2の今後の実装方針(特に上で紹介したATSとオリジンサーバーの通信方法)について相談する目的で発表を行いました。ここでは興味深かった発表内容と私の行った発表、雑感について簡単に記述します。Carrollによるセッション。ATSのプロセスや周辺ツールの基本構成から始まり、コア部分(上で挙げたようなHTTPのトランザクション処理やキャッシュ管理、オリジンサーバーのドメインの名前解決、イベントシステム周りなど)の実装に関する丁寧な説明がされました。Callによるセッション。ATSの設定値やViaヘッダによる簡単なデバッグ方法から、GDBによるデバッグ、メモリリーク発見方法などコミッタのプラクティスが共有されました。HTTP/2前半では私がHTTP/2実装の進捗報告と、FetchSMを用いた実装方針の是非、リリーススケジュールに関しての相談を行いました。この時発表した資料はSlideShareにて公開済です。Yahoo!デベロッパーネットワーク相談内容については、下記のような議論がされました。FetchSMを使うことに関する懸念点の確認。どのようなオーバーヘッドがあるかの認識合わせ。FetchSMを使用する方針でOK。既存のHttpSM周辺の実装を修正するのは非常に難しい。後半では現在のATSのHTTP/2フレーム処理部分の実装を書いたJamesによる、現在の実装の説明が行われました。現在HTTP/2に関するソースコードはproxy/http2に配置されおり、Jamesによってここで実装されているHttp2Frame(HTTP/2フレームを表現)、Http2SessionAccept(HTTP/2セッションを受け入れた際の処理を担う)、Http2ClientSession(HTTP/2フレームのヘッダやネットワークI/Oの管理を担う)、Http2ConnectionState(HTTP/2セッションの状態管理を担う)の4つのコンポーネントに関する説明がされました。Hedstromが、JIRAに投稿したプロトタイプのパッチを適用したATSを、ドキュメントをホストしているhttps://docs.trafficserver.apache.org/に導入してみるという豪快な場面もありました。Summitの感想としては「刺激的だった」との一言に集約されます。そもそもOSSのコミッタとじかに話す経験がなかったので、コミッタとの濃い技術の話を英語で行う事にも大きな新鮮味を感じていました。(同時に力量不足も痛感しました)ちなみに今回が私にとっての初の渡米だったため、風景やら食文化やら多くのものが新鮮に感じました。Burgersの裏メニューのバーガーを収めたものです。謝辞(*1):HPACKデコーダの実装作業についてはサマーインターンシップ2014に参加してくれたD.A.くんに大部分を担当してもらいました。彼にはインターンシップにはおよそ10日間ほどの非常に限られた期間の中で英語の仕様のドラフトを読み、上記のデコーダの実装を行い、日本でHTTP/2に関する活動をしている有志によって提供されているhpack-test-caseのいくつかのテストケースを用いて正常にデコードが可能なことを確認してもらいました。彼の貢献により本ブログで紹介した活動がスムーズに行えました。この場を借りて御礼申しあげます。JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。JAPANのサービス開発を支える技術やデザイン、文化を発信しています。Reserved.このページの先頭へ。