Table of contents
(2) Source code compilation and installation
(4) Test the lua script in the form of a file
Get nginx request header information
original request header content
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
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
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 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
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