AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

ngx_lua在又拍云的应用日志收集、性能调优与服务化 by Monkey Zhang

发布者 jser
发布于 1473210204578  浏览 7983 关键词 Nginx 
分享到

第1页

ngx_lua

Monkey Zhang (timebug)

2016.07 @ Shenzhen ArchSummit



第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.* connect send receive

sslhandshake 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页

Base64 Filter by Lua:



local chunk = ngx.arg[1]

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)



Chunk by 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





✦ NSQ



nsqd



nsq_to_http ,



第21页









ELK

















第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; ...

}

bucket:hbimg = {"enable":true,"ratio":0.1}

redis slaveof

nsqd -> nsq_to_http

logger.log(cjson.encode(log_msg_table) .. "\n")



UPYUN LOG Edge Server



第23页

UPYUN LOG Platform:

HAProxy + Heka + Kafka + Elasticsearch + Kibana



第24页

✦ show ✦ size ✦ retry ✦ abnormal -



50kb/s



Content-Length



第26页

✦ CDN

✦ ✦

✦ TopN





第27页

130+ Edge Nodes



第28页

ngx_lua



Redis ES



第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 ->



123.150.200.130



✦ correct_dns_to ✦ correct_dns_from



第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` (*)



第35页

CDN



第36页

nginx.conf



service



server_name *.b0.upaiyun.com



Custom Domain Binding



valid_referers, allow, deny

expires 7d

ssl_certificate* ssl_stapling*

upstream { server 127.0.0.1 }

max_fails=3 fail_timeout=30s

health_check (*)

round-robin, ip_hash, hash (1.7.2+)



Custom Antileech Rules and Redirect:

ip, user-agent, referer, token etc.

Custom Cache Control:

support specific URI rules etc.

Custom SSL

Custom CDN Origin:

support multi-network routing etc.

Custom Health Check Strategy: passive, active

Custom Load Balancing Strategy



rewrite



Custom URL rewrite



……



第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 $_SCHEME



$_HOST $_POST_name



$_SYM_sym



$_HOST_n $_HEADER_name



$_COOKIE_name



$_URI



$_GET_name

$_QUERY



$_RANDOM_n $_RANDOM



第41页

Lua Custom URL rewrite:

lua-resty-rewrite | functions



$ENCODE_BASE64(E)

$ALL(E1, E2, ...) $UPPER(E)



$ANY(E1, E2, ...) $DECODE_BASE64(E) $LOWER(E)

$WHEN(E1, E2, ...)



$SUB(E1, from, to) $PCALL(E) $MATCH(E1, E2)



$GT(E1, E2) $GE(E1, E2) $EQ(E1, E2)



$ADD_REQ_HEADER(E1, E2) $DEL_REQ_HEADER(E1) $ADD_RSP_HEADER(E1, E2)



第42页

Join our team

©2012-2014 Trybiane



第43页

Q&A



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。