[Nginx Advanced Chapter] Lua Basic Grammar and OpenResty Installation

Table of contents

I. Introduction

Two, Lua basic grammar  

hello world

reserved keywords

note

variable

string

empty value

Boolean type

scope

control statement

if-else

for loop

function

assignment

return value 

Table

array

traverse

member function

3. Installation of openresty

(1) Precompiled installation

(2) Source code compilation and installation

(3) Service order

(4) Test the lua script in the form of a file

Code hot deployment

Get nginx request header information

Get post request parameters

Http protocol version

request method

original request header content

body content body

(5) Nginx cache

Nginx global memory cache

second-resty-lrucache

lua-resty-redis access redis

lua-resty-mysql


I. Introduction

Lua is a lightweight, compact scripting language developed in 1993 by a research group at the Pontifical Catholic University of Rio de Janeiro in Brazil, written in standard C language, and designed to be embedded in applications , thus providing flexible extension and customization functions for applications.

Official Website: The Programming Language Lua

Before learning the lua language, you need to install the lua version first, and download the plug-in in ideal. For details, please refer to the following article

Lua environment installation + Idea configuration_idea configuration lua_xiaowu714's blog - CSDN blog https://blog.csdn.net/xiaowu714/article/details/127763087?spm=1001.2014.3001.5506

Two, Lua basic grammar  

hello world

After ideal creates a new lua project and creates a lua file, enter the following

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

main()

operation result

reserved keywords

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

note

-- 两个减号是行注释

--[[

 这是块注释

 这是块注释.

 --]]

variable

number type

Lua numbers only have double type, 64bits

You can represent numbers as follows

num = 1024​

num = 3.0​

num = 3.1416

​num = 314.16e-2

​num = 0.31416E1

​num = 0xff​

num = 0x56

string

You can use single quotes or double quotes

You can also use the escape characters '\n' (newline), '\r' (carriage return), '\t' (horizontal tabulation), '\v' (vertical tabulation), '\' (backslash ), '\"' (double quotes), and '\" (single quotes) etc.

The following four ways define exactly the same string (the two square brackets can be used to define a string with newlines)

a = 'alo\n123"'

a = "alo\n123\""

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

a = [[alo

123"]]

empty value

NULL in C language is nil in Lua, for example, if you access a variable that has not been declared, it is nil

Boolean type

Only nil and false are false

Number 0, '' empty string ('\0') are true

scope

All variables in lua are global variables unless otherwise specified, even in statement blocks or functions.

Variables preceded by the local keyword are local variables.

control statement

while loop

local function main()

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

main()

operation result

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 loop

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()

function

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()

assignment

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

    print(name,age,bGay)
end

main()

return value 

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

    local bol,name = isMyGirl('xiao6')

    print(name,bol)
end

main()

 

Table

KV form, similar to map

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()

array

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

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

main()

traverse

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()

member function

local function main()

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

  function  person.eat(food)

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

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

3. Installation of openresty

(1) Precompiled installation

Take CentOS as an example to refer to other systems: OpenResty - OpenResty® Linux Package

You can add the openresty repository to your CentOS system so that you can install or update our packages in the future (via yum update command). Run the following command to add our repository:

 yum install yum-utils

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

Then you can install packages like openresty like this:

 yum install openresty

If you want to install the command-line tool resty, you can install the openresty-resty package like this:

 sudo yum install openresty-resty

(2) Source code compilation and installation

Download the tar.gz package from the official website

OpenResty - Download

The minimum version is based on nginx1.21

./configure

Then enter openresty-VERSION/the directory , and enter the following command to configure:

./configure

By default, --prefix=/usr/local/openrestythe program will be installed into /usr/local/openrestythe directory.

relygcc openssl-devel pcre-devel zlib-devel

Install:yum install gcc openssl-devel pcre-devel zlib-devel postgresql-devel

You can specify various options such as

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

            --with-luajit \

            --without-http_redis2_module \

            --with-http_iconv_module \

            --with-http_postgres_module

Try using ./configure --helpto see more options.

make && make install

View the directory of openresty

(3) Service order

start up

Service openresty start

stop

Service openresty stop

Check if the configuration file is correct

Nginx -t

reload configuration file

Service openresty reload

View installed modules and version numbers

Nginx -V

Test Lua script

在Nginx.conf 中写入
   location /lua {

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

start nginx

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

(4) Test the lua script in the form of a file


       location /lua {

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

 Create a lua directory under the nginx directory and write the hello.lua file, the file content

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

Code hot deployment

The hello.lua script needs to restart nginx every time it is modified, which is very cumbersome, so hot deployment can be enabled through configuration

 lua_code_cache off;

 It will prompt that enabling this function may affect the performance of nginx

Get nginx request header information

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  

 

Get post request parameters

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 protocol version

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

request method

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

original request header content

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

body content body

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

(5) Nginx cache

Nginx global memory cache

Add in the http block of the nginx configuration file

lua_shared_dict shared_data 1m; # Apply for one megabyte of memory as a memory cache, which can be shared by all processes and can maintain atomicity

hello.lua script content

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/>")

Every time I visit ii, I will +1

second-resty-lrucache

A simple LRU cache implemented by Lua is suitable for directly caching complex Lua data structures in Lua space: compared with ngx_lua shared memory dictionary, it can save expensive serialization operations, and compared with external services such as memcached, it can save Go to more expensive socket operations

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

quote lua file

       location /lua {

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

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

When you don’t know which file nginx is looking for, you can restart nginx first, then try to access the error report, and then you can see which files are searched by default in the error.log file

We create the my directory under lualib, and create the cache.lua script under the my directory. The content of the script is as follows:

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

Remember to enable lua_code_cache, that is, code cache, otherwise the code will be executed repeatedly every time, and the value of count will never be obtained

lua-resty-redis access redis

官网:GitHub - openresty/lua-resty-redis: Lua redis client driver for the ngx_lua based on the cosocket API

common method

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

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

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

create connection

red, err = redis:new()

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

timeout

red:set_timeout(time)

keepalive

red:set_keepalive(max_idle_timeout, pool_size)

close

ok, err = red:close()

pipeline

red:init_pipeline()

results, err = red:commit_pipeline()

certified

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

    if not res then

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

        return
end

nginx configuration

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 script

  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)

access results

 verify

Summary :

Lua-resty-redis directly accessing redis can save some original steps, such as:

Client request --nginx--tomcat--redis--tomcat--nginx--client

optimized to:

client request --nginx--redis--nginx--client

This method can be used for some infrequently updated resources placed in redis, saving unnecessary steps

lua-resty-mysql

官网: GitHub - openresty/lua-resty-mysql: Nonblocking Lua MySQL driver library for ngx_lua or OpenResty

configuration file

    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
 

Guess you like

Origin blog.csdn.net/m0_62946761/article/details/130516015