[Nginx 上級編] Lua の基本文法と OpenResty のインストール

目次

I.はじめに

2、Luaの基本文法  

こんにちは世界

予約されたキーワード

ノート

変数

空の値

ブール型

範囲

制御文

if-else

for ループ

関数

割り当て

戻り値 

テーブル

配列

トラバース

メンバー関数

3.openrestyのインストール

(1) プリコンパイル済みインストール

(2) ソースコードのコンパイルとインストール

(3) サービス命令

(4) ファイル形式の lua スクリプトをテストする

コードのホットデプロイメント

nginxリクエストヘッダー情報を取得する

ポストリクエストパラメータを取得する

HTTPプロトコルのバージョン

リクエストメソッド

元のリクエストヘッダーの内容

本文の内容 本文

(5) Nginxキャッシュ

Nginx グローバル メモリ キャッシュ

セカンド・レスト・ルキャッシュ

lua-resty-redis Redis にアクセスします

lua-resty-mysql


I.はじめに

Lua は、ブラジルのリオデジャネイロ教皇庁カトリック大学の研究グループによって 1993 年に開発された軽量でコンパクトなスクリプト言語で、標準の C 言語で書かれ、アプリケーションに組み込むように設計されており、アプリケーションに柔軟な拡張機能とカスタマイズ機能を提供します。 。

公式ウェブサイト:プログラミング言語 Lua

lua 言語を学習する前に、まず lua バージョンをインストールし、理想的なプラグインをダウンロードする必要があります。詳細は次の記事を参照してください。

Lua 環境のインストール + アイデア構成_アイデア構成 lua_xiaowu714 のブログ - CSDN ブログhttps://blog.csdn.net/xiaowu714/article/details/127763087?spm=1001.2014.3001.5506

2、Luaの基本文法  

こんにちは世界

Ideal が新しい lua プロジェクトを作成し、lua ファイルを作成した後、次のように入力します。

local function main()
    print("Hello world!")
end

main()

演算結果

予約されたキーワード

and break do else elseif end false for function 
if in local nil not or repeat return then true 
until while

ノート

-- 两个减号是行注释

--[[

 这是块注释

 这是块注释.

 --]]

変数

数値型

Lua 数値には double 型、64 ビットのみがあります

次のように数値を表すことができます

num = 1024​

num = 3.0​

num = 3.1416

​num = 314.16e-2

​num = 0.31416E1

​num = 0xff​

num = 0x56

一重引用符または二重引用符を使用できます

エスケープ文字 '\n' (改行)、'\r' (キャリッジ リターン)、'\t' (水平集計)、'\v' (垂直集計)、'\' (バックスラッシュ)、' も使用できます。 \"' (二重引用符)、'\" (単一引用符) など。

次の 4 つの方法は、まったく同じ文字列を定義します (2 つの角かっこを使用して、改行を含む文字列を定義できます)。

a = 'alo\n123"'

a = "alo\n123\""

a = '\97lo\10\04923"'

a = [[alo

123"]]

空の値

C 言語の NULL は Lua では nil です。たとえば、宣言されていない変数にアクセスすると nil になります。

ブール型

nil と false だけが false です

数値 0、'' 空の文字列 ('\0') は true

範囲

lua のすべての変数は、特に指定がない限り、ステートメント ブロックや関数内であってもグローバル変数です。

local キーワードが前に付いている変数はローカル変数です。

制御文

while ループ

local function main()

    local i = 0
    local max = 10
    while i <= max do
        print(i)
        i = i + 1
    end
end

main()

演算結果

if-else

local function main()

    local age = 30

    local sex = 'Malee'

    if age <= 40 and sex == "Male" then
        print("男人四十一枝花")
    elseif age > 40 and sex ~= "Female" then -- ~=  等于 !=
        io.write("old man")
    elseif age < 20 then
        print("too young too simple")
    else
        print("Your age is "..age)   --Lua中字符串的连接用..

    end

end

main()

for ループ

local function main()

    for i = 10, 1 , -1 do   -- i<=1, i--
        print(i)
    end
    for i = 1, 10 , 1 do    -- i<=10, i++
        print(i)
    end

end

main()

関数

local function main()

    function myPower(x,y) -- 定义函数

        return      y+x

    end

    power2 = myPower(2,3)  -- 调用

    print(power2)
end

main()
local function main()

    function newCounter()

        local i = 0
        return function()     -- anonymous function(匿名函数)

            i = i + 1

            return i

        end
    end



    c1 = newCounter()

    print(c1())  --> 1

    print(c1())  --> 2

    print(c1())
end

main()

割り当て

local function main()
    name, age,bGay = "yiming", 37, false, "[email protected]" -- 多出来的舍弃

    print(name,age,bGay)
end

main()

戻り値 

local function main()
    function isMyGirl(name)
        return name == 'xiao6' , name
    end

    local bol,name = isMyGirl('xiao6')

    print(name,bol)
end

main()

 

テーブル

地図に似た KV 形式

local function main()
    dog = {name='111',age=18,height=165.5}

    dog.age=35

    print(dog.name,dog.age,dog.height)

    print(dog)

end

main()

配列

local function main()
    local function main()
        arr = {"string", 100, "dog",function() print("wangwang!") return 1 end}

        print(arr[4]())
    end
    main()
end

main()

トラバース

local function main()
    arr = {"string", 100, "dog",function() print("wangwang!") return 1 end}

    for k, v in pairs(arr) do

        print(k, v)
    end
end

main()

メンバー関数

local function main()

person = {name='旺财',age = 18}

  function  person.eat(food)

    print(person.name .." eating "..food)

  end
person.eat("骨头")
end
main()

3.openrestyのインストール

(1) プリコンパイル済みインストール

CentOS を例として他のシステムを参照します: OpenResty - OpenResty® Linux Package

openresty リポジトリを CentOS システムに追加すると、将来 (yum update コマンド経由で) パッケージをインストールまたは更新できるようになります。次のコマンドを実行してリポジトリを追加します。

 yum インストール yum-utils

 yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

次に、次のように openresty のようなパッケージをインストールできます。

 openrestyをyumインストールします

コマンドラインツールrestyをインストールしたい場合は、次のようにopenresty-restyパッケージをインストールできます。

 sudo yum install openresty-resty

(2) ソースコードのコンパイルとインストール

公式 Web サイトから tar.gz パッケージをダウンロードします。

OpenResty - ダウンロード

最小バージョンは nginx1.21 に基づいています

./configure

次に、openresty-VERSION/ディレクトリ、次のコマンドを入力して設定します。

./configure

デフォルトでは、--prefix=/usr/local/openrestyプログラムは/usr/local/openrestyディレクトリにインストールされます。

頼るgcc openssl-devel pcre-devel zlib-devel

インストール:yum install gcc openssl-devel pcre-devel zlib-devel postgresql-devel

などのさまざまなオプションを指定できます。

./configure --prefix=/opt/openresty \

            --with-luajit \

            --without-http_redis2_module \

            --with-http_iconv_module \

            --with-http_postgres_module

./configure --helpさらに多くのオプションを表示するには、を使用してみてください。

make && make install

openrestyのディレクトリを表示する

(3) サービス命令

起動

Service openresty start

ストップ

Service openresty stop

設定ファイルが正しいか確認してください

Nginx -t

設定ファイルをリロードする

Service openresty reload

インストールされているモジュールとバージョン番号を表示する

Nginx -V

Lua スクリプトをテストする

在Nginx.conf 中写入
   location /lua {

        default_type text/html;
        content_by_lua '
           ngx.say("<p>Hello, World!</p>")
         ';
      }

nginxを起動する

./nginx -c /usr/local/openresty/nginx/conf/nginx.conf

(4) ファイル形式の lua スクリプトをテストする


       location /lua {

        default_type text/html;
        content_by_lua_file lua/hello.lua;
      }

 nginx ディレクトリの下に lua ディレクトリを作成し、hello.lua ファイル、ファイルの内容を書き込みます。

ngx.say("<p>hello world!!!</p>")

コードのホットデプロイメント

hello.lua スクリプトは変更されるたびに nginx を再起動する必要がありますが、これは非常に面倒なので、設定を通じてホット デプロイメントを有効にできます。

 lua_code_cache オフ;

 この機能を有効にすると nginx のパフォーマンスに影響を与える可能性があるというメッセージが表示されます。

nginxリクエストヘッダー情報を取得する

local headers = ngx.req.get_headers()                         

ngx.say("Host : ", headers["Host"], "<br/>")  

ngx.say("user-agent : ", headers["user-agent"], "<br/>")  

ngx.say("user-agent : ", headers.user_agent, "<br/>")

for k,v in pairs(headers) do  

    if type(v) == "table" then  

        ngx.say(k, " : ", table.concat(v, ","), "<br/>")  

    else  

        ngx.say(k, " : ", v, "<br/>")  

    end  

end  

 

ポストリクエストパラメータを取得する

ngx.req.read_body()  

ngx.say("post args begin", "<br/>")  

local post_args = ngx.req.get_post_args()  

for k, v in pairs(post_args) do  

    if type(v) == "table" then  

        ngx.say(k, " : ", table.concat(v, ", "), "<br/>")  

    else  

        ngx.say(k, ": ", v, "<br/>")  

    end  
end

 

HTTPプロトコルのバージョン

ngx.say("ngx.req.http_version : ", ngx.req.http_version(), "<br/>")

リクエストメソッド

ngx.say("ngx.req.get_method : ", ngx.req.get_method(), "<br/>")  

元のリクエストヘッダーの内容

ngx.say("ngx.req.raw_header : ",  ngx.req.raw_header(), "<br/>")  

本文の内容 本文

ngx.say("ngx.req.get_body_data() : ", ngx.req.get_body_data(), "<br/>")

(5) Nginxキャッシュ

Nginx グローバル メモリ キャッシュ

nginx設定ファイルのhttpブロックに追加します。

lua_shared_dictshared_data 1m; # すべてのプロセスで共有でき、アトミック性を維持できるメモリ キャッシュとして 1 メガバイトのメモリを適用します

hello.lua スクリプトの内容

local shared_data = ngx.shared.shared_data  

  

local i = shared_data:get("i")  

if not i then  

    i = 1  

    shared_data:set("i", i)  

    ngx.say("lazy set i ", i, "<br/>")  
end  
 

i = shared_data:incr("i", 1)  

ngx.say("i=", i, "<br/>")

ii にアクセスするたびに +1 します

セカンド・レスト・ルキャッシュ

Lua によって実装されたシンプルな LRU キャッシュは、より複雑な Lua データ構造を Lua 空間に直接キャッシュするのに適しています。ngx_lua 共有メモリ ディクショナリと比較して、コストのかかるシリアル化操作を節約でき、memcached などの外部サービスと比較して、Go to キャッシュも節約できます。より高価なソケット操作

https://github.com/openresty/lua-resty-lrucache

lua ファイルを引用する

       location /lua {

        default_type text/html;
#        content_by_lua_file lua/hello.lua;

            content_by_lua_block {
                require("my/cache").go()
            }
      }

nginx がどのファイルを探しているのかわからない場合は、まず nginx を再起動し、次にエラー レポートにアクセスしてみると、error.log ファイルでデフォルトでどのファイルが検索されるかを確認できます。

lualib配下にmyディレクトリを作成し、myディレクトリ配下にcache.luaスクリプトを作成します。スクリプトの内容は以下のとおりです。

local _M = {}


lrucache = require "resty.lrucache"

c, err = lrucache.new(200)  -- allow up to 200 items in the cache
ngx.say("count=init")


if not c then
    error("failed to create the cache: " .. (err or "unknown"))
end

function _M.go()

count = c:get("count")


c:set("count",100)
ngx.say("count=", count, " --<br/>")


if not count then  


    c:set("count",1)

    ngx.say("lazy set count ", c:get("count"), "<br/>")  

else


c:set("count",count+1)
 


ngx.say("count=", count, "<br/>")
end


end
return _M

lua_code_cache、つまりコード キャッシュを有効にすることを忘れないでください。有効にしないと、コードが毎回繰り返し実行され、count の値が取得されなくなります。

lua-resty-redis Redis にアクセスします

公式サイト:GitHub - openresty/lua-resty-redis: cosocket API に基づく ngx_lua 用の Lua redis クライアント ドライバー

一般的な方法

local res, err = red:get("key")

local res, err = red:lrange("nokey", 0, 1)

ngx.say("res:",cjson.encode(res))

接続を作成する

red, err = redis:new()

ok, err = red:connect(host, port, options_table?)

タイムアウト

red:set_timeout(time)

生き続ける

red:set_keepalive(max_idle_timeout, pool_size)

近い

ok, err = red:close()

パイプライン

red:init_pipeline()

results, err = red:commit_pipeline()

認証済み

    local res, err = red:auth("foobared")

    if not res then

        ngx.say("failed to authenticate: ", err)

        return
end

nginxの設定

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    lua_code_cache off;
    lua_shared_dict shared_data 1m;
    server {
        listen       888;
        server_name  localhost;

       location /lua {

        default_type text/html;
        content_by_lua_file lua/redis.lua;

        }
        location / {
            root   html;
            index  index.html index.htm;
        }


        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

redis.lua スクリプト

  local redis = require "resty.redis"
                local red = redis:new()

                red:set_timeouts(1000, 1000, 1000) -- 1 sec

  local ok, err = red:connect("127.0.0.1", 6379)
  local res, err = red:auth("zjy123...000")

    if not res then

        ngx.say("failed to authenticate: ", err)

        return
  end
 if not ok then
                    ngx.say("failed to connect: ", err)
                    return
                end

                ok, err = red:set("dog", "an animal")
                if not ok then
                    ngx.say("failed to set dog: ", err)
                    return
                end

                ngx.say("set result: ", ok)

                local res, err = red:get("dog")
                if not res then
                    ngx.say("failed to get dog: ", err)
                    return
                end

                if res == ngx.null then
                    ngx.say("dog not found.")
                    return
                end


              ngx.say("dog: ", res)

アクセス結果

 確認

概要:

Redis に直接アクセスする Lua-resty-redis では、次のような元の手順をいくつか保存できます。

クライアントリクエスト --nginx--tomcat--redis--tomcat--nginx--client

以下に最適化されています:

クライアントリクエスト --nginx--redis--nginx--client

この方法は、Redis に配置された、更新頻度が低いリソースに使用でき、不必要な手順を節約できます。

lua-resty-mysql

公式サイト:GitHub - openresty/lua-resty-mysql: ngx_lua または OpenResty 用のノンブロッキング Lua MySQL ドライバー ライブラリ

設定ファイル

    charset utf-8;
    lua_code_cache off;
    lua_shared_dict shared_data 1m;
    server {
        listen       888;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;


       location /lua {

        default_type text/html;
        content_by_lua_file lua/mysql.lua;

       }
    }

 mysql.lua

local mysql = require "resty.mysql"
                local db, err = mysql:new()
                if not db then
                    ngx.say("failed to instantiate mysql: ", err)
                    return
                end

                db:set_timeout(1000) -- 1 sec


                local ok, err, errcode, sqlstate = db:connect{
                    host = "192.168.102.100",
                    port = 3306,
                    database = "atguigudb1",
                    user = "root",
                    password = "123456",
                    charset = "utf8",
                    max_packet_size = 1024 * 1024,
                }


                ngx.say("connected to mysql.<br>")



                local res, err, errcode, sqlstate = db:query("drop table if exists cats")
                if not res then
                    ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
                    return
                end


                res, err, errcode, sqlstate =
                    db:query("create table cats "
                             .. "(id serial primary key, "
                             .. "name varchar(5))")
                if not res then
                    ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
                    return
                end

                ngx.say("table cats created.")



                res, err, errcode, sqlstate =
                    db:query("select * from student")
                if not res then
                    ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
                    return
                end

                local cjson = require "cjson"
                ngx.say("result: ", cjson.encode(res))


                local ok, err = db:set_keepalive(10000, 100)
                if not ok then
                    ngx.say("failed to set keepalive: ", err)
                    return
                end
 

おすすめ

転載: blog.csdn.net/m0_62946761/article/details/130516015