對請求資料的格式化
例如
{body:{}}--->{data:{}}

執行階段概念 · OpenResty最佳實踐 · 看雲 https://www.kancloud.cn/kancloud/openresty-best-practices/50451
我們OpenResty做個測試,示例代碼如下:
location /mixed {
set_by_lua $a 'ngx.log(ngx.ERR, "set_by_lua")';
rewrite_by_lua 'ngx.log(ngx.ERR, "rewrite_by_lua")';
access_by_lua 'ngx.log(ngx.ERR, "access_by_lua")';
header_filter_by_lua 'ngx.log(ngx.ERR, "header_filter_by_lua")';
body_filter_by_lua 'ngx.log(ngx.ERR, "body_filter_by_lua")';
log_by_lua 'ngx.log(ngx.ERR, "log_by_lua")';
content_by_lua 'ngx.log(ngx.ERR, "content_by_lua")';
}
執行結果日志(截取了一下):
set_by_lua
rewrite_by_lua
access_by_lua
content_by_lua
header_filter_by_lua
body_filter_by_lua
log_by_lua
這幾個階段的存在,應該是openresty不同于其他多數web server程式設計的最明顯特征了。由于nginx把一個會話分成了很多階段,這樣第三方子產品就可以根據自己行為,挂載到不同階段進行處理達到目的。
這樣我們就可以根據我們的需要,在不同的階段直接完成大部分典型處理了。
- set_by_lua: 流程分之處理判斷變量初始化
- rewrite_by_lua: 轉發、重定向、緩存等功能(例如特定請求代理到外網)
- access_by_lua: IP準入、接口權限等情況集中處理(例如配合iptable完成簡單防火牆)
- content_by_lua: 内容生成
- header_filter_by_lua: 應答HTTP過濾處理(例如添加頭部資訊)
- body_filter_by_lua: 應答BODY過濾處理(例如完成應答内容統一成大寫)
- log_by_lua: 回話完成後本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機器)
實際上我們隻使用其中一個階段content_by_lua,也可以完成所有的處理。但這樣做,會讓我們的代碼比較臃腫,越到後期越發難以維護。把我們的邏輯放在不同階段,分工明确,代碼獨立,後期發力可以有很多有意思的玩法。
列舉360企業版的一個例子:
# 明文協定版本
location /mixed {
content_by_lua '...'; # 請求處理
}
# 加密協定版本
location /mixed {
access_by_lua '...'; # 請求加密解碼
content_by_lua '...'; # 請求處理,不需要關心通信協定
body_filter_by_lua '...'; # 應答加密編碼
}
内容處理部分都是在content_by_lua階段完成,第一版本API接口開發都是基于明文。為了傳輸體積、安全等要求,我們設計了支援壓縮、加密的密文協定(上下行),痛點就來了,我們要更改所有API的入口、出口麼?
最後我們是在access_by_lua完成密文協定解碼,body_filter_by_lua完成應答加密編碼。如此一來世界都甯靜了,我們沒有更改已實作功能的一行代碼,隻是利用ngx-lua的階段處理特性,非常優雅的解決了這個問題。
前兩天看到春哥的微網誌,裡面說到github的某個應用裡面也使用了openresty做了一些東西。發現他們也是利用階段特性+lua腳本處理了很多使用者證書方面的東東。最終在性能、穩定性都十分讓人滿意。使用者選型很準,不愧是github的工程師。
不同的階段,有不同的處理行為,這是openresty的一大特色。學會他,适應他,會給你打開新的一扇門。這些東西不是openresty自身所創,而是nginx c module對外開放的處理階段。了解了他,也能更好的了解nginx的設計思維。
ngx lua子產品之ngx.location.capture子請求學習-壞男孩-51CTO部落格 https://blog.51cto.com/5ydycm/1900279
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8080;
location / { # any query
# default_type text/html;
content_by_lua_file lualib/app001.lua;
}
}
}
--學習body&args
--ngx.location.capture 傳回res.status res.body res.header res.truncated
ngx.say("First")
res = ngx.location.capture("/flumelog",{method=ngx.HTTP_GET,body="name=zzj&age=33&name=badboy",args={arg_a=2,arg_b=3}})
for key,val in pairs(res) do
if type(val) == "table" then
ngx.say(key,"=>",table.concat(val,","))
else
ngx.say(key,"=>",val)
end
end
ngx.exit(123789)
# curl http://localhost:8080/flumelog?name=zj&age=3&name=ba
2019/05/25 13:17:13 [error] 9063#0: *4 attempt to set status 123789 via ngx.exit after sending out the response status 200, client: 127.0.0.1, server: , request: "GET /flumelog?name=zj HTTP/1.1", host: "localhost:8080"
[root@flink logs]# tail error.log
Spring Cloud Gateway https://spring.io/projects/spring-cloud-gateway
Spring Cloud Gateway features:
- Built on Spring Framework 5, Project Reactor and Spring Boot 2.0
- Able to match routes on any request attribute.
- Predicates and filters are specific to routes.
- Hystrix Circuit Breaker integration.
- Spring Cloud DiscoveryClient integration
- Easy to write Predicates and Filters
- Request Rate Limiting
- Path Rewriting