ホームページ  >  記事  >  バックエンド開発  >  Lua を nginx に統合して Web サービスを開発する

Lua を nginx に統合して Web サービスを開発する

WBOY
WBOYオリジナル
2016-08-08 09:20:33919ブラウズ

背景紹介

プロジェクト開発中、以前に私たちが扱ったサービスは生成されたデータをredisに保存し、クライアントは特定のキーを介してredis内の特定のデータを取得しました。以前の開発では、nginx+wsgi+python のアーキテクチャ ソリューションが採用されました。 Python を通じてプロジェクトを迅速に実装することもでき、テスト環境へのプッシュが使用されています。
時間が経つにつれて、このプロジェクトについてゆっくり考えてみると、この実装方法にはいくつかの欠点があることがわかりました。このサービスには複雑なロジックがないため、nginx はリクエストを受信し、それをバックグラウンドの Python サービスに転送します。その後、Python サービスは特定のリクエストを取得し、redis からデータを取り出し、呼び出しのためにクライアントに返します。実際、プロセス全体は比較的シンプルで明確です。nginx と redis の間に Python サービスのレイヤーを追加する必要がないため、このアーキテクチャの実装を最適化できないか検討しています。

nginx と lua

その後、nginx+redis を簡単に検索したところ、nginx+lua+openresty に関連するキーワードがいくつか見つかりました。次のステップは、openresty の調査を開始することです。関連ドキュメントを見ると、openresty は nginx コア モジュールとさまざまなサードパーティ モジュールを統合するプロジェクト セットであることがわかりました。 openresty を使用すると、さまざまな追加のサードパーティ パッケージをインストールする必要がなくなり、それらはすべてそのインストール パッケージに継承されます。これは間違いなく怠け者にとって良い選択です。

lua の紹介

lua は、グルー言語としても知られるスクリプト言語です。これは他の言語と簡単に組み合わせることができる非常に小さな言語です。 Lua 自体の特性と、それに付属する言語により、1 つのサービスで 2 つの言語の特性を使用することは、通常ほど強力ではありません。 Lua を接着型関数型言語として使用した素晴らしいゲームをいくつか見てきました。
しかし、簡単に使用してみると、Lua の文字列処理は十分強力ではないことがわかりました。Lua は C ライブラリを直接使用しており、その文字列処理は C ライブラリによって提供されるインターフェイスのみであり、インターフェイスの追加の強化や補完は行われていないためです。多くのシナリオでは、分割などのいくつかの一般的なインターフェイスを自分で実装する必要があります。

lua と ngxin の統合

lua は接着型言語なので、lua を nginx に直接結合できますか? 答えは「はい」です。 Lua は nginx で直接実行して、論理処理とログ制御を行うことができます。次に、nginx + lua を使用して、ニーズを満たす Web サービスを開発し、他のサーバーサイド言語では完了できない利便性と迅速な開発を完了することを検討できます。
上記のトラバーサルに加えて、nginx+lua によってどのような利点がもたらされます:
1. 転送のレイヤーを 1 つ削減し、他のサービス言語を使用してサービスを開発します。nginx とサーバー間の直接通信には必ずプロトコルが使用されます。 cgi、fcig、wsgi など。 lua を使用する場合、lua は nginx で直接実行されるため、追加の nginx 転送を行う必要があります。
2. イベントベースの応答。Lua は nginx を直接実行するランタイム環境であるため、Lua は nginx のすべての機能を継承します。通常の状況では、nginx はイベント、select または epoll に基づいてサービスを提供します。パフォーマンスの面では間違いなく非常に印象的なものとなるでしょう。
以上の理由からnginx+luaを開始しました。怠け者は openresty インストール戦略全体を直接採用するため、もちろん、nginx を個別にインストールし、次に lua をインストールし、その後 nginx_lua_module をインストールすることもできます。 openresty をインストールした後、簡単なテストを書き始めました。実際、openresty の github に関連するサンプルがあり、これに基づいていくつかの簡単なテスト開発を行うことができます。
インストールとテスト例の作成の最初のステップが完了したら、lua+nginx は統合が成功したことを意味します。次のステップは独自のビジネス ロジックを開発することです。ここで注意する必要があるのは、openresty は実際には nginx を統合しているため、1 台のマシン上で 2 つの nginx を実行すると、対応する問題が発生する可能性があるということです。したがって、openresty をインストールした後、マシン上の既存の nginx に一定の影響が生じる可能性があります。

元のサービスをアップグレードします

開発環境が構成されました。次のステップは、ビジネス ロジックを直接開発することです。つまり、redis にアクセスするリクエストを受信し、データを読み取り、クライアント リクエストを返します。なぜなら、Lua は nginx 設定ファイルに直接書き込むことができますが、これは良い戦略ではありません。 Lua は他の言語と直接結合されていますが、結合の程度にはソフトウェア エンジニアリング関連の問題も考慮する必要があります。たとえば、後のコードの保守性や nginx 設定ファイルの読みやすさなどです。
上記の理由を考慮して、Lua の関数実装を別のファイルに記述し、nginx 設定ファイルで宣言して nginx にロードして実行するように指示することもお勧めします。機能の実装に基づいて、コードの結合度と保守性の度合いを避けるようにしてください。
特定の実装では、サービス自体が単純であるため、2 つのファイルがサービス全体を処理します。
-redis.conf #redis ホスト、ポート
-init.lua #初期化設定ファイル
実装にはnginxの共有メモリの概念が利用されています。

<code><span>--redis.conf</span>
host:<span>127.0</span><span>.0</span><span>.1</span>
port:<span>6379</span><span>--init.lua</span>
tmp = {}
<span>for</span> l <span>in</span> io.<span>lines</span>(<span>"lua/redis.conf"</span>) <span>do</span><span>for</span> i <span>in</span><span>string</span>.gmatch(l, <span>"([^:]+)"</span>) <span>do</span>
                table.insert(tmp, i)
        <span><span>end</span></span><span><span>end</span></span>
ngx.shared.config:<span>set</span>(tmp[<span>1</span>], tmp[<span>2</span>])
ngx.shared.config:<span>set</span>(tmp[<span>3</span>], tmp[<span>4</span>])</code>

ここでは、nginx の起動時に redis.conf を読み取る必要があるため、nginx に設定を追加して、起動時に init.lua を実行する必要があることを nginx に伝える必要があります。また、nginxの共有メモリ設定も宣言する必要があるので、nginxの設定は以下のようになります

<code>lu<span>a_shared</span>_dict config <span>1</span>m<span>;</span>
init_by_lu<span>a_file</span> 'lua/init.lua'<span>;</span></code>

第一步已经完成,就是redis相关配置的读取,共享内存的声明和初始化,那接下来就是具体的逻辑实现,几十行代码分分钟搞定。

<code>     location  /vector{
                content_by_lua '
                        <span>local</span> redis = require <span>"resty.redis"</span><span>local</span> server = redis:new()
                        <span>local</span> conf = ngx.shared.config 

                        <span>local</span> ok, err = server:connect(conf:<span>get</span>(<span>"host"</span>), conf:<span>get</span>(<span>"port"</span>))
                        ngx.header.content_type = <span>"text/plain"</span><span>if</span><span>not</span> ok <span>then</span>
                                ngx.<span>log</span>(ngx.ERR, err)
                                ngx.<span>exit</span>(ngx.HTTP_SERVICE_UNAVAILABLE)
                        <span>end</span><span>local</span> x = ngx.var.arg_x;
                        <span>local</span> y = ngx.var.arg_y;
                        <span>local</span> z = ngx.var.arg_z;

                        <span>if</span> x == nil <span>or</span> y == nil <span>or</span> z == nil <span>then</span>                                ngx.<span>say</span>(<span>"{\\\"ret\\\": -1}"</span>)
                                ngx.<span>exit</span>(ngx.HTTP_SERVICE_UNAVAILABLE)
                        <span>end</span><span>local</span> key = z..<span>"_"</span>..x..<span>"_"</span>..y
                        <span>local</span> data = server:<span>get</span>(key)
                ';
        }</code>

版权声明:本文为博主原创文章,转载请注明来源。

以上就介绍了nginx中集成lua开发web服务,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:PHPテストFTP接続次の記事:PHPテストFTP接続