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
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
hello world
After ideal creates a new lua project and creates a lua file, enter the following
local function main() print("Hello world!")endmain()
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 = 1024num = 3.0num = 3.1416num = 314.16e-2num = 0.31416E1num = 0xffnum = 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 = [[alo123"]]
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 endendmain()
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中字符串的连接用.. endendmain()
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) endendmain()
function
local function main() function myPower(x,y) -- 定义函数 return y+x end power2 = myPower(2,3) -- 调用 print(power2)endmain()
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())endmain()
assignment
local function main() name, age,bGay = "yiming", 37, false, "yimi[emailprotected]" -- 多出来的舍弃 print(name,age,bGay)endmain()
return value
local function main() function isMyGirl(name) return name == 'xiao6' , name end local bol,name = isMyGirl('xiao6') print(name,bol)endmain()
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)endmain()
array
local function main() local function main() arr = {"string", 100, "dog",function() print("wangwang!") return 1 end} print(arr[4]()) end main()endmain()
traverse
local function main() arr = {"string", 100, "dog",function() print("wangwang!") return 1 end} for k, v in pairs(arr) do print(k, v) endendmain()
member function
local function main()person = {name='旺财',age = 18} function person.eat(food) print(person.name .." eating "..food) endperson.eat("骨头")endmain()
(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
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/openresty
the program will be installed into /usr/local/openresty
the 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 --help
to 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 cachengx.say("count=init")if not c then error("failed to create the cache: " .. (err or "unknown"))endfunction _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/>") elsec:set("count",count+1) ngx.say("count=", count, "<br/>")endendreturn _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
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) returnend
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
FAQs
What version of Lua does OpenResty use? ›
OpenResty chooses LuaJIT rather than standard Lua for performance reasons and maintains its LuaJIT branch. LuaJIT is based on the Lua 5.1 syntax and is selectively compatible with some Lua 5.2 and Lua 5.3 syntax to form its system.
Where is OpenResty installed? ›By default, OpenResty is installed into the prefix /usr/local/openresty/ .
How to install OpenResty in Linux? ›- Step 1 : Import GPG Key: GPG key helps in verifying the authenticity of the package. ...
- Step 2 : Add Openresty repository: We need to be sure that 'apt-add-repository' command is available in our server. ...
- Step 3 : Install Openresty. Update the apt index first sudo apt-get update.
This file contains the default OpenResty server configuration and should be located at /usr/local/openresty/nginx/conf/nginx.
What version of nginx does OpenResty use? ›The first part of the OpenResty release version numbers is the version of the bundled NGINX core. For instance, OpenResty 1.7. 10.2 bundles NGINX 1.7.