OpenResty XRay がどのようにしてアプリケーションの問題特定と効率化を支援するかをご覧ください。

詳細はこちら LIVE DEMO

このビデオでは、OpenResty でストリーミング HTTP レスポンスボディの出力を行う方法をご紹介いたします。

cd ~/
mkdir stream-resp/
cd stream-resp/

まず、いつものようにサブディレクトリ構造を作成します。

mkdir logs conf html

次に、テンプレート設定を迅速に記述します。

vim conf/nginx.conf

そして、このファイルに以下の編集を加えます。

  1. 8080 ポートをリッスンする HTTP サーバーを作成します。
  2. /test ロケーションを追加します。
  3. Chrome ウェブブラウザを満足させるために、application/octet-stream MIME タイプを指定することが重要です。
  4. content_by_lua_block ディレクティブを使用して Lua コードを追加します。
  5. 1秒ごとに1行の出力を行います。
  6. Nginx の書き込みバッファをフラッシュするために、ngx.flush メソッドを明示的に呼び出す必要があります。これは 100% ノンブロッキングな呼び出しです。
  7. そして、各ループの反復で ngx.sleep を使用して 1 秒間スリープします。これもノンブロッキングです。
  8. 最後に、html ディレクトリのルートロケーションを作成します。
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    server {
        listen 8080 reuseport;

        location = /test {
            default_type application/octet-stream;

            content_by_lua_block {
                for i = 1, 4 do
                    ngx.say("hello ", i)
                    ngx.flush(true)
                    ngx.sleep(1) -- sec
                end
            }
        }

        location / {
            default_type text/html;
            root html;
        }
    }
}

ここで、ディレクトリツリー全体を確認しましょう。

tree .

截图 16

良さそうですね。

では、この OpenResty アプリケーションを起動します。

openresty -p $PWD/

截图 18

curl を使用して HTTP ロケーションにクエリを送る時が来ました。

curl 'http://127.0.0.1:8080/test'

截图 19

素晴らしいですね。確かに毎秒1行の文字が生成されています!

この HTTP API が本当にノンブロッキングであるかを検証するために、weighttp ツールを使用してロードテストを行うことができます。ここでは意図的にレスポンスを遅くしているため、時間がかかることにご注意ください。

weighttp -c 500 -k -n 500 127.0.0.1:8080/test

截图 21

このように、500 の同時リクエストがある状況でも、毎秒 120 以上のリクエストを処理できています!各リクエストの完了に 4 秒かかることに注意してください。しかも、これはたった 1 つのワーカープロセスと 1 つの OS スレッドだけで実現しています。

さらに同時接続数を増やすこともできますが、そのためには Nginx の設定を適切に調整する必要があります。

vim conf/nginx.conf

例えば、worker_connections をより大きな値に設定します。

截图 24

アクセスログのバッファリングを有効にすることで、さらなるパフォーマンス向上が期待できます。また、リクエストメモリプールのサイズを減らすこともできます。

では、Web ブラウザでテストするための HTML ページを作成しましょう。

vim html/a.html

このファイルで以下の編集を行います:

  1. 出力を保持するための DIV タグを追加します。
  2. 先ほどの HTTP ロケーションに AJAX リクエストを送信する JavaScript を追加します。
  3. DIV 要素を取得します。
  4. ストリーミングレスポンスを受信するための JavaScript 関数を追加します。
  5. 新しいデータがあることを確認します。
  6. 新しいデータを DIV 要素に追加します。ここでは簡略化のため、特殊な HTML 文字のエスケープは行いません。
  7. 1 秒ごとに新しい受信レスポンスデータをチェックします。
  8. Firefox はより洗練された方法をサポートしていますが、Chrome もサポートする必要があります。
  9. 最後に、レスポンスボディストリームの終了を処理します。
  10. レスポンスデータの最終チェックを行います。
  11. 定期的なタイマーを削除します。
  12. 最終的な出力結果をウェブページに追加します。
  13. 簡潔さを保つため、ここではエラー処理を省略しています。
<!doctype html>
<html>
<body>
<div style="margin: 2em;" id="out"></div>

<script>
(function () {
    let xhttp = new XMLHttpRequest();
    xhttp.open("GET", "/test", true);
    xhttp.send();

    let div = document.getElementById("out")

    let total_len = 0
    let check_resp = function () {
        let resp = xhttp.responseText
        let len = resp.length

        if (len > total_len) {
            let new_data = resp.substring(total_len, len)
            total_len = len;

            div.innerHTML += new_data + "<br/>"
        }
    };

    let timer = setInterval(check_resp, 1000);
    check_resp();

    xhttp.onreadystatechange = function () {
        if (this.readyState == 4) {
            check_resp();
            clearInterval(timer);
            div.innerHTML += "done<br/>";
        }
    };
})();
</script>
</body>
</html>

ディレクトリ構造全体をもう一度確認しましょう。

tree .

截图 44

OpenResty サーバーを再読み込みしたり再起動したりする必要はありません。これは単なる静的 HTML ページだからです。

ps aux|grep nginx|grep -v /tmp/

截图 45

Chrome でこの HTML ページを開く時が来ました。

截图 46

うまく機能しました!以上が本日お伝えしたい内容です。

著者について

章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。

章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵襲的な障害分析および排除ツール)と OpenResty XRay(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!