UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
NGINX + Lua: Using NGINX/OpenResty with embedded Lua
1. NGINX + Lua
Using NGINX/OpenResty
with embedded Lua
Epifanov Ivan,
Lead Developer
2. Lua
• Fast
• Light (241K)
• Simple
• Powerfull
• Embeddable
• Portable
Lua do Pesadelo
(Nightmare Moon)
3. Who uses Lua?
• Games: WoW, Angry Birds, Baldur's
Gate, Civilization V, Crysis, HoMM V,
L.A. Noire, etc.
• Software: Lightroom, MySQL proxy,
MySQL Workbench, Celestia, Far
Manager, GIMP, MediaWiki, etc.
• Misc.: Mercedes Autos, LG Smart TV,
Space Shuttle Gas Detection, etc.
4. LuaJIT
• JIT compilation for lua code
• High performance (3-100x)
• Low memory footprint
• Crossplatform
• Cross-architecture (x86, ARM, MIPS,
PPC
• local ffi = require("ffi")
ffi.cdef[[
int printf(const char *fmt, ...);
]]
ffi.C.printf("Hello %s!", "world")
5. OpenResty/NGINX-LUA
• NGINX bundle with luajit and additional
modules.
• Developed by TaoBao and CloudFlare
• Access to every processing stage of
nginx
• Non-blocking without callback-hell
• co-sockets, shared pool and sub-
requests
6. Full control
• init_by_lua(file)
• init_worker_by_lua(file)
• set_by_lua(file)
• log_by_lua(file)
• content_by_lua(file)
• header_filter_by_lua(file)
• access_by_lua(file)
• rewrite_by_lua(file)
7. What
• Databases: lua-resty-redis, lua-resty-
mysql, etc.
• Templates: lua-resty-template, etlua
• Frameworks: Lapis
• Preprocessors: Moonscript
(coffiescript-like syntax)
8. Where
• Image Server, for image resizes (now)
• Image Server, for queue, API, control
(in the future)
• Mobile detection
• EDGE-side block cache
• Maybe parts of SSO API, like cookie-
setter
9. For example...
Redis RESTfull api for userscores
• GET /scores
return userid list
• GET/PUT/POST/DELETE /scores/<id>
manipulate user scores
10. Init
http {
...
init_by_lua '
json = require "cjson";
redis = require "resty.redis"
';
...
server {
...
set $redis_host "192.168.2.104";
set $redis_port "6379";
set $redis_pass "nightmaremoon";
...
}
...
}
11. Init
local red = redis:new()
local ok, err = red:connect(ngx.var.redis_host, ngx.var.redis_port)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = red:auth(ngx.var.redis_pass)
if not ok then
ngx.say("failed to auth: ", err)
return
end
12. GET /scores
local keys, err = red:keys("*")
local scores = {}
for i, key in ipairs(keys) do
scores[key] = red:get(key)
end
ngx.header.content_type = "text/plain"
ngx.say(json.encode(scores))
13. GET /score/<userid>
location ~* ^/keys/(?<key>.*)$
{
content_by_lua '
-- ... (connect and auth)
local val, err = red:get("user:score:" ..
ngx.var.key)
ngx.say(json.encode({ value = val }))
';
}
14. DELETE /scores/<userid>
local method = ngx.req.get_method()
if method == "GET" then
...
elseif method == "PUT" then
...
elseif method == "DELETE" then
red:delete("user:score:" .. ngx.var.key)
ngx.say(json.encode({result = "success"}))
end
16. GET /scores/max
local max = 0
local keys = redis.call('keys', 'user:score:*');
for i, key in ipairs(keys) do
local value = tonumber(redis.call('get', key));
if value > max then
max = value
end
end
return max
17. GET /scores/max
local sha, err = red:script("load","...")
local val, err = red:evalsha(sha, 0)
ngx.say(json.encode({ max = val }))
18. GET /scores/max/<id1>,...,<idN>
local max = 0
for key in string.gmatch(ngx.var.key, '([^,]+)') do
local res = ngx.location.capture("/scores/" .. key)
data = json.decode(res.body)
if tonumber(data.value) > max then
max = tonumber(data.value)
end
end
ngx.say(json.encode({ max = max }))
19. What to read
• https://gist.github.com/isage/509d99cf4
def36014f5c
• http://wiki.nginx.org/HttpLuaModule
• http://openresty.org
• search github for lua-resty*