- Nginx
- Nginx (engine x) 是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務。
- Openresty
- OpenResty是一個基於 Nginx 與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。用於方便地搭建能夠處理超高併發、擴展性極高的動態 Web 應用、Web 服務和動態網關。通過匯聚各種設計精良的 Nginx 模塊(主要由 OpenResty 團隊自主開發),從而將 Nginx 有效地變成一個強大的通用 Web 應用平臺。這樣,Web 開發人員和系統工程師可以使用 Lua 腳本語言調動 Nginx 支持的各種 C 以及 Lua 模塊,快速構造出足以勝任 10K 乃至 1000K 以上單機併發連接的高性能 Web 應用系統。其目標是讓你的Web服務直接跑在 Nginx 服務內部,充分利用 Nginx 的非阻塞 I/O 模型,不僅僅對 HTTP 客戶端請求,甚至於對遠程後端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進行一致的高性能響應。
- Lua
- Lua 是一種輕量小巧的腳本語言,用標準C語言編寫並以源代碼形式開放, 其設計目的是爲了嵌入應用程序中,從而爲應用程序提供靈活的擴展和定製功能。
- 特性:
- 輕量級: 它用標準C語言編寫並以源代碼形式開放,編譯後僅僅一百餘K,可以很方便的嵌入別的程序裏。
- 可擴展: Lua提供了非常易於使用的擴展接口和機制:由宿主語言(通常是C或C++)提供這些功能,Lua可以使用它們,就像是本來就內置的功能一樣。
- 支持面向過程(procedure-oriented)編程和函數式編程(functional programming);
- 自動內存管理;只提供了一種通用類型的表(table),用它可以實現數組,哈希表,集合,對象;
- 語言內置模式匹配;閉包(closure);函數也可以看做一個值;提供多線程(協同進程,並非操作系統所支持的線程)支持;
- 通過閉包和table可以很方便地支持面向對象編程所需要的一些關鍵機制,比如數據抽象,虛函數,繼承和重載等。
- 應用場景:
- 遊戲開發
- 獨立應用腳本
- Web 應用腳本
- 擴展和數據庫插件如:MySQL Proxy 和 MySQL WorkBench
- 安全系統,如入侵檢測系統
- 業務需求介紹:
- 一個請求到達Nginx後將請求發到所有endpoint上,即配置文件中upstream中的每個server上。業務場景爲:每個用戶連接在同一個服務不同的節點上,如果需要向用戶發出命令傳遞信息,在只發一次請求的前提下,經過Nginx後只能到達服務的某一個節點上,這樣可能導致命令不能轉發到相對應用戶所在的節點上,所以需要將請求轉發到每一個節點上,保證命令傳遞的有效性.
- 分析:
- 正常一個請求發到Nginx後,請求只會轉發到某一個endpoint上(這裏有Nginx的負載均衡作用),要想把這個請求轉發到每個endpoint上,需要在請求到達Nginx後,使得Nginx將請求轉發到每一個endpoint上,而不是其中一個endpoint,經調研發現Openresty可以結合Lua腳本編程實現該功能.
- 思路:
- 具體方案爲:當請求到達Nginx後,Nginx沒有進行轉發前,獲取所有endpoint,然後對每個endpoint進行轉發請求,因此需要在Openresty中使用Lua腳本語言實現該功能.
- 實施過程:
- 創建三個web服務用於實驗
- 使用Docker啓動Openresty
- nginx.conf配置文件如下:
-
#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; # See Move default writable paths to a dedicated directory (#119) # https://github.com/openresty/docker-openresty/issues/119 client_body_temp_path /var/run/openresty/nginx-client-body; proxy_temp_path /var/run/openresty/nginx-proxy; fastcgi_temp_path /var/run/openresty/nginx-fastcgi; uwsgi_temp_path /var/run/openresty/nginx-uwsgi; scgi_temp_path /var/run/openresty/nginx-scgi; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; upstream weblist { server 10.xxx.xxx.xxx:9999; server 10.xxx.xxx.xxx:7777; server 10.xxx.xxx.xxx:8888; } server { listen 80; server_name 127.0.0.1; #resolver 8.8.8.8; location = /upstreams { default_type text/plain; content_by_lua_block { local http = require "resty.http" local httpc = http.new() local upstream = require "ngx.upstream" local get_servers = upstream.get_servers local get_upstreams = upstream.get_upstreams local us = get_upstreams() for _, u in ipairs(us) do ngx.say("upstream ", u, ":") local srvs, err = get_servers(u) if not srvs then ngx.say("failed to get servers in upstream ", u) else for _, srv in ipairs(srvs) do local res, err = httpc:request_uri("http://"..srv["addr"], { method = ngx.var.request_method,--set request method body = ngx.var.request_body,--set request body headers = ngx.req.get_headers()--set request headers }) if res.status == ngx.HTTP_OK then ngx.print(res.body) else ngx.print(res.status) end ngx.print("\n") end end end } } location / { proxy_pass http://weblist; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/openresty/nginx/html; } } }
-
- Dokcer啓動命令
-
docker run -itd -p 80:80 -v ~/dockerapp/openresty/conf/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf -v ~/dockerapp/openresty/lua/lualib/:/usr/local/openresty/lualib/ openresty/openresty
-
- nginx.conf配置文件如下:
-
添加引用庫
-
-
將OpenResty 引用第三方 resty 庫非常簡單,只要將 lua-resty-http/lib/resty/ 目錄下的 http.lua 和http_headers.lua 兩個文件拷貝到 /usr/local/openresty/lualib/resty 目錄下即可(假設你的 OpenResty 安裝目錄爲 /usr/local/openresty)。
-
-
-
同lua-resty-http的操作,在此不再贅述。
-
-
-
注意⚠️
-
在nginx.conf配置文件的編寫過程中發現,代碼的執行順序並不是按照順序執行,可以參考官方文檔https://openresty.org/cn/ebooks.html
-
技術成長---Nginx實現廣播功能
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.