ngx lua在又拍云的应用 日志收集及作用
如果无法正常显示,请先停止浏览器的去广告插件。
1. ngx_lua
Monkey Zhang (timebug)
2016.07 @ Shenzhen ArchSummit
2.
3. A Systems Engineer at UPYUN
Email: timebug.info@gmail.com
Github: https://github.com/timebug
4. $ ./configure --prefix=/opt/nginx \
--add-module=/path/to/lua-nginx-module
http {
server {
listen 8080;
location /add {
set $res '';
rewrite_by_lua '
local a = tonumber(ngx.var.arg_a) or 0
local b = tonumber(ngx.var.arg_b) or 0
ngx.var.res = a + b
';
content_by_lua '
ngx.say(ngx.var.res)
';
}
}
}
$ curl 'http://localhost:8080/add?a=6&b=7'
13
5. LuaJIT
LuaJIT is a Just-In-Time Compiler (JIT) for the Lua
programming language.
6. How it works
LuaJIT VM embedded into the Nginx
7. cosocket API
ngx.socket.*
sslhandshake
connect send receive
close settimeout etc.
8. UPYUN CDN & API is built on top of
NGINX with ngx_lua
9. UPYUN API
10. Base64 Filter by Lua
http {
lua_package_path “$prefix/app/src/?.lua;;";
server {
listen 8080;
location /base64 {
set $b64_en '';
set $b64_e0 '';
set $b64_e1 '';
echo_duplicate 1000 hello;
header_filter_by_lua '
ngx.header.content_length = nil -- ((n + 2) / 3 ) * 4
ngx.header.content_type = "text/plain"
ngx.header.content_transfer_encoding = "base64"
';
body_filter_by_lua_file app/src/b64_body_filter.lua;
}
}
}
11. local chunk = ngx.arg[1]
Base64 Filter by Lua:
Chunk by Chunk
local e0 = ngx.var.b64_e0 or ''
local e1 = ngx.var.b64_e1 or ''
local en = tonumber(ngx.var.b64_en) or 0
if en == 1 then
chunk = e0 .. chunk
elseif en == 2 then
chunk = e0 .. e1 .. chunk
end
if not ngx.arg[2] then
en = #chunk % 3
if en == 1 then
e0 = chunk:sub(-1)
elseif en == 2 then
e1 = chunk:sub(-1)
e0 = chunk:sub(-2, -2)
end
chunk = chunk:sub(1, #chunk - en)
else -- eof
en = 0
end
ngx.var.b64_en = en
ngx.var.b64_e0 = e0
ngx.var.b64_e1 = e1
ngx.arg[1] = ngx.encode_base64(chunk)
12. location /upload {
proxy_request_buffering off;
...
}
13. Lua Streaming Upload
ngx.req.init_body()
ngx.req.append_body(chunk)
ngx.req.finish_body()
14. UPYUN CDN
15. CDN
5 ~ 10T
16. ✦
✦
✦
✦
17. access_log /path/to/access.log combined buffer=4096 flush=5s;
✦
✦ Logstash / Heka Agent Input File
✦ NGINX 1.7.1+
✦
Logging to syslog
tail -f
18. log_by_lua with cosocket
ngx.timer.at
+ Lua Buffer +
tcp:send to nsqd
_M.nsqd = {
config = {
topic = "marco_ngx_log",
flush_limit = 32768, -- 32KB
drop_limit = 2097152, -- 2MB
},
cluster = {
{
servers = {
{ host = "127.0.0.1", port = 3900 },
},
},
},
}
19. Nginx Internals:
HTTP request phase handlers
✦ POST READ PHASE
✦ SERVER REWRITE PHASE
✦ FIND CONFIG PHASE
✦ REWRITE PHASE
✦ POST REWRITE PHASE
✦ PRE ACCESS PHASE
✦ ACCESS PHASE
✦ POST ACCESS PHASE
✦ TRY FILES PHASE
✦ CONTENT PHASE
✦ LOG PHASE
20. nsqd --mem-queue-size
nsqd
✦
✦
NSQ
nsq_to_http
,
21. ✦
✦
✦
✦
✦
ELK
30
22. Lua Custom Logging:
lua-resty-logger-socket
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
server {
access_log /path/to/access.log combined buffer=4096;
. . .
}
redis slaveof
nsqd -> nsq_to_http
logger.log(cjson.encode(log_msg_table) .. "\n")
bucket:hbimg = {"enable":true,"ratio":0.1}
23. UPYUN LOG Platform:
HAProxy + Heka + Kafka + Elasticsearch + Kibana
24. ✦ show -
✦ size -
✦ retry -
✦ abnormal -
50kb/s
Content-Length
25.
26. ✦
CDN
5
✦
✦
✦
TopN
27. 130+ Edge Nodes
28. ngx_lua
Redis
ES
29.
30. ✦ x-request-id: ce4fc776afd2b74175695d239b67e3ed
✦ via: T.2428.H.1, V.mix-gd-can-007, T.2415.R.1, M.cun-ha-cgo-005
✦ x-source: C/200
31. ✦ first_byte_time
✦ client_block_time
✦ prematurely_closed
32. DNS
DNS
…
timebug@harmless:~$ http http://img.huaban.com/test.mp4
HTTP/1.1 302 Moved Temporarily
Connection: keep-alive
Content-Length: 161
Content-Type: text/html
Location: http://123.150.200.130/img.huaban.com/test.mp4?
_up_sum=a738dc&_up_id=0f8b04a82480906a2a09bfda8d864c84&_up_from=112.21.160.135
Server: marco
112.21.160.135 ->
✦ correct_dns_to
✦ correct_dns_from
123.150.200.130
33. UPYUN DevOps
conf hash + project version + upyun.cfg
Ansible Playbook
✦ rsync code and binary
✦ conf template instantiate
✦ kill -HUP `cat /var/run/nginx.pid` (*)
34.
35. CDN
36. nginx.conf service
server_name *.b0.upaiyun.com Custom Domain Binding
valid_referers, allow, deny Custom Antileech Rules and Redirect:
expires 7d Custom Cache Control:
support specific URI rules etc.
ssl_certificate* ssl_stapling* Custom SSL
upstream { server 127.0.0.1 }
ip, user-agent, referer, token etc.
Custom CDN Origin:
support multi-network routing etc.
health_check (*) Custom Health Check Strategy:
passive, active
round-robin, ip_hash, hash (1.7.2+) Custom Load Balancing Strategy
rewrite Custom URL rewrite
… …
max_fails=3 fail_timeout=30s
37. nginx.conf as a service
powered by ngx_lua
38. http://io.upyun.com/2015/03/09/hello-world/?foo=bar
[scheme] [host] [path] [query]
39. tianchaijz:
"$WHEN($MATCH($_URI, '^/foo/.*'))$ADD_REQ_HEADER(X-Foo, bar)"
Marco: I GOT IT !
Edge Server
40. Lua Custom URL rewrite:
lua-resty-rewrite | variables
$_METHOD
$_HOST
$_HOST_n
$_SCHEME
$_POST_name
$_SYM_sym
$_HEADER_name
$_COOKIE_name
$_GET_name
$_QUERY
$_RANDOM_n
$_URI
$_RANDOM
41. Lua Custom URL rewrite:
lua-resty-rewrite | functions
$ENCODE_BASE64(E)
$ALL(E1, E2, ...)
$ANY(E1, E2, ...)
$UPPER(E)
$DECODE_BASE64(E)
$LOWER(E)
$WHEN(E1, E2, ...)
$SUB(E1, from, to)
$PCALL(E)
$MATCH(E1, E2)
$GT(E1, E2) $ADD_REQ_HEADER(E1, E2)
$GE(E1, E2) $DEL_REQ_HEADER(E1)
$EQ(E1, E2) $ADD_RSP_HEADER(E1, E2)
42. Join our team
©2012-2014 Trybiane
43. Q&A