對請求數據的格式化 html
例如nginx
{body:{}}--->{data:{}}git
執行階段概念 · OpenResty最佳實踐 · 看雲 https://www.kancloud.cn/kancloud/openresty-best-practices/50451github
咱們OpenResty作個測試,示例代碼以下:web
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")'; }
執行結果日誌(截取了一下):spring
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把一個會話分紅了不少階段,這樣第三方模塊就能夠根據本身行爲,掛載到不一樣階段進行處理達到目的。編程
這樣咱們就能夠根據咱們的須要,在不一樣的階段直接完成大部分典型處理了。緩存
實際上咱們只使用其中一個階段content_by_lua,也能夠完成全部的處理。但這樣作,會讓咱們的代碼比較臃腫,越到後期愈加難以維護。把咱們的邏輯放在不一樣階段,分工明確,代碼獨立,後期發力能夠有不少有意思的玩法。安全
列舉360企業版的一個例子:app
# 明文協議版本
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