nginx?openresty?快速入門指南
一、什么是openresty?
官網(wǎng): https://openresty.org/cn/
OpenResty® 是一個(gè)基于 Nginx 與 Lua 的高性能 Web 平臺(tái),其**內(nèi)部集成了大量精良的 Lua 庫(kù)、第三方模塊以及大多數(shù)的依賴項(xiàng)。**用于方便地搭建能夠處理超高并發(fā)、擴(kuò)展性極高的動(dòng)態(tài) Web 應(yīng)用、Web 服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)。
總結(jié):openresty 內(nèi)部已經(jīng)幫你集成了許多依賴項(xiàng),編譯時(shí)只需要–with-xxx 激活這些依賴模塊。
二、openresty編譯安裝
官網(wǎng)參考: https://openresty.org/cn/installation.html
安裝路徑 選擇 /usr/local/openresty,如果不配置安裝路徑,默認(rèn)安裝路徑即 /usr/local/openresty
因?yàn)楣緶?zhǔn)生產(chǎn) 使用的是 1.9.15.1
單純編譯openresty比較簡(jiǎn)單,openresty強(qiáng)大在很多第三方拓展模塊,你需要提前下載好這些模塊源碼,在配置 openresty編譯選項(xiàng)時(shí),把這些模塊加進(jìn)來。當(dāng)然openrest以及集成大量模塊,直接可以使用–with-xxx編譯加入這些模塊。
1. 編譯安裝命令
相關(guān)命令如下:
tar -zxvf openresty-1.13.6.2.tar.gz ## --with-http_ssl_module依賴openssl yum install openssl openssl-devel export INSTALL_DIR=/usr/local/openresty ./configure --prefix=${INSTALL_DIR} --sbin-path=${INSTALL_DIR}/nginx/sbin/nginx --conf-path=${INSTALL_DIR}/nginx/conf/nginx.conf --pid-path=${INSTALL_DIR}/nginx/logs/nginx.pid --lock-path=${INSTALL_DIR}/nginx/logs/nginx.lock --user=root --group=root --with-luajit --without-http_redis2_module --with-http_iconv_module --with-stream --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_auth_request_module --with-pcre --with-pcre-jit --with-debug --with-http_v2_module gmake gmake install
1.1 編譯完成后路徑
安裝完成后,nginx命令路徑為
/usr/local/openresty/nginx/sbin/nginx
配置文件路徑
/usr/local/openresty/nginx/conf/nginx.conf
/usr/local/openresty/nginx/conf/http_vhost/.conf
/usr/local/openresty/nginx/conf/http_upstream/.conf
# nginx重載 /usr/local/openresty/nginx/sbin/nginx -s reload
1.2 常用編譯選項(xiàng)解釋
- –with-stream
ngx_stream_core_module模塊自1.9.0版開始提供。默認(rèn)情況下不構(gòu)建此模塊,應(yīng)使用–with-stream 配置參數(shù)啟用它。用來實(shí)現(xiàn)四層協(xié)議的轉(zhuǎn)發(fā)、代理或者負(fù)載均衡等。stream 模塊用于一般的 TCP 代理和負(fù)載均衡。
- –with-http_ssl_module
Nginx虛擬主機(jī)、Nginx模塊的安裝使用(加密模塊–with-http_ssl_module)
參考URL: http://www.dbjr.com.cn/article/91933.htm
報(bào)錯(cuò): SSL moudules require the OpenSSL library
解決,執(zhí)行
yum -y install openssl openssl-devel
- –with-http_realip_module
這個(gè)模塊主要功能就是 在nginx訪問日志中去除代理IP,顯示客戶的真實(shí)IP。作用呢,一般就是統(tǒng)計(jì)客戶地域或?qū)憘€(gè)統(tǒng)計(jì)腳本看有沒有流量攻擊。
然后nginx.conf中
在這里加上"http_x_forwarded_for"’ 段,獲取真實(shí)IP用的 log_format main ’
HTTP模塊,不要在server中用,要在HTTP區(qū)用。這樣就是全局使用。
–with-http_v2_module
支持http2協(xié)議。
2. nginx配置文件配置
## 復(fù)制配置好的nginx.conf到conf目錄 ${INSTALL_DIR}為你前面定義的安裝目錄 cp -rf nginx.conf ${INSTALL_DIR}/nginx/conf/ # 修改nginx.conf中的工作線程數(shù)為CPU核數(shù) CPU_NUM=`cat /proc/cpuinfo | grep processor|wc -l | awk -F' ' '{print $NF}' | sed -n '$p'` sed -i "s/^worker_processes.*/worker_processes ${CPU_NUM};/g" ${INSTALL_DIR}/nginx/conf/nginx.conf
創(chuàng)建nginx日志目錄(你的nginx.conf中配置的,這里創(chuàng)建好目錄)
# create nginx logs dirtory mkdir -p /home/logs/nginx
2.1 nginx.conf模板
# nginx的工作進(jìn)程運(yùn)行時(shí)的身份,也就是進(jìn)程文件的屬主和屬組屬性,如果在源碼安裝時(shí)configure配置已經(jīng)指定用戶和組,這里可以注釋掉 #user root; # 定義nginx的工作進(jìn)程的數(shù)量,一般為CPU核數(shù)或核數(shù)的倍數(shù),該參數(shù)與并發(fā)量有關(guān) worker_processes 4; #worker_cpu_affinity 0001 0010 0100 1000; # 錯(cuò)誤日志的位置 error_log /home/logs/nginx/error.log error; # nginx的master進(jìn)程的pid存儲(chǔ)文件 pid /usr/local/openresty/nginx/logs/nginx.pid; worker_rlimit_nofile 307200; events { use epoll; # 每一個(gè)工作進(jìn)程可以接收的請(qǐng)求連接數(shù),一般與系統(tǒng)的進(jìn)程可以打開的文件描述符數(shù)量相同, worker_connections 51200; } #流模塊 stream { include tcp_vhost/*.conf; include tcp_upstream/*.conf; } http { # mime.types文件含有nginx支持的媒體類型,include可以加載該文件 include mime.types; include fastcgi.conf; # 訪問日志的格式,可以自定義 log_format main '$remote_addr $host $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" "$upstream_response_time" "$upstream_addr" "$upstream_status" "$request_time"'; # 指定訪問日志的位置和格式main access_log off; client_header_buffer_size 64k; large_client_header_buffers 8 64k; client_max_body_size 500m; proxy_next_upstream error timeout invalid_header http_502 http_504; # 調(diào)用系統(tǒng)的方法傳輸文件,速度更快, sendfile on; tcp_nopush on; keepalive_requests 10000; keepalive_timeout 10; ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM; # 隱藏nginx版本號(hào),不再瀏覽顯示 server_tokens off; include http_vhost/*.conf; include http_upstream/*.conf; lua_package_path 'lua/?.lua;../lua/?.lua;/usr/local/openresty/nginx/conf/lua/?.lua;/usr/local/openresty/lualib/?.lua;;'; }
注意: 配置文件中的相對(duì)路徑,是當(dāng)前nginx.conf同級(jí)目錄,注意理解。
比如
include http_vhost/*.conf; include http_upstream/*.conf;
對(duì)應(yīng)路徑為
/usr/local/openresty/nginx/conf/http_vhost
/usr/local/openresty/nginx/conf/http_upstream
3. nginx常見配置
Nginx常用配置有這一篇就夠了
參考URL: http://www.dbjr.com.cn/article/50899.htm
一個(gè)站點(diǎn)配置多個(gè)域名
server { listen 80; server_name aaa.cn bbb.cn; }
server_name 后跟多個(gè)域名即可,多個(gè)域名之間用空格分隔
nginx配置中l(wèi)ocation匹配規(guī)則
nginx配置中l(wèi)ocation匹配規(guī)則詳解
參考URL: http://www.dbjr.com.cn/article/182472.htm
nginx官方文檔給出location語(yǔ)法如下:
location [=|~|~*|^~] uri { … }
其中,方括號(hào)中的四種標(biāo)識(shí)符是可選項(xiàng),用來改變請(qǐng)求字符串和uri的匹配方式。uri是待匹配的請(qǐng)求字符串,可以是不包含正則的字符串,這種模式被稱為**“標(biāo)準(zhǔn)的uri";也可以包含正則,這種模式被稱為"正則uri"**。
- location = /uri
= 開頭表示精確匹配。
- location ^~ /uri
^~ 開頭對(duì)URL路徑進(jìn)行前綴匹配,并且在正則之前
- location ~ 正則表達(dá)式
~開頭表示區(qū)分大小寫的正則匹配
- location ~*正則表達(dá)式
~*開頭表示不區(qū)分大小寫的正則匹配
- location /uri
不帶任何修飾符,也表示前綴匹配,但是在正則匹配之后
- location /
通用匹配,任何未匹配到其它location的請(qǐng)求都會(huì)匹配到,相當(dāng)于switch中的default
如果匹配規(guī)則以^開頭,就是匹配以指定字符串開頭的路徑,如果沒有就是匹配url中的內(nèi)容是否包含指定字符串
如果匹配規(guī)則以$結(jié)尾,就是匹配以指定字符串結(jié)尾的路徑
多個(gè)location配置的情況下匹配順序?yàn)椋?strong>當(dāng)有匹配成功時(shí)候,停止匹配,按當(dāng)前匹配規(guī)則處理請(qǐng)求):
優(yōu)先匹配 =
其次匹配 ^~
按照文件中的匹配順序執(zhí)行
最后匹配 /
普通匹配(最長(zhǎng)字符匹配)
總結(jié)為: (location =) > (location 完整路徑) > (location ^~ 路徑) > (location ,* 正則順序) > (location 部分起始路徑) > (/)
三、OpenResty工作原理
OpenResty工作原理
Nginx采用的是master-worker模型,也就是一個(gè)master進(jìn)程管理多個(gè)worker進(jìn)程,基本的事件處理都放在worker進(jìn)程中,master進(jìn)程負(fù)責(zé)全局初始化以及對(duì)worker進(jìn)行的管理。
OpenResty中,每個(gè)worker進(jìn)程使用一個(gè)LuaVM,當(dāng)請(qǐng)求被分配到worker時(shí),將在這個(gè)LuaVM中創(chuàng)建一個(gè)coroutine協(xié)程,協(xié)程之間數(shù)據(jù)隔離,每個(gè)協(xié)程都具有獨(dú)立的全局變量。
Nginx設(shè)計(jì)為主進(jìn)程和多個(gè)工作進(jìn)程的工作模式,每個(gè)進(jìn)程是單線程來處理多個(gè)連接,每個(gè)工作進(jìn)程采用了非阻塞I/O來處理多個(gè)連接,從而減少線程上下文切換,從而實(shí)現(xiàn)高性能、高并發(fā)。因此,生產(chǎn)環(huán)境中會(huì)通過將CPU綁定給Nginx工作進(jìn)程,從而提升性能。
OpenResty處理請(qǐng)求流程
Nginx會(huì)把一個(gè)請(qǐng)求分成不同階段,第三方模塊可以根據(jù)自己的行為,掛在到不同階段中以達(dá)到自身目的。OpenResty采用了同樣的特性,不同階段有著不同的處理行為。
Nginx架構(gòu) 的 好處
Nginx采用多進(jìn)程模式,對(duì)于每個(gè)worker進(jìn)程都是獨(dú)立的,因此不需要加鎖,所以節(jié)省了鎖帶來的性能開銷。采用獨(dú)立的進(jìn)程的好處在于worker進(jìn)程之間相互不會(huì)影響,當(dāng)一個(gè)進(jìn)程退出后,其他進(jìn)程依然工作,以保證服務(wù)不會(huì)終端。
Nginx采用異步非堵塞的方式去處理請(qǐng)求,異步非堵塞就是當(dāng)一個(gè)線程調(diào)用出現(xiàn)阻塞而等待時(shí),其他線程可以去處理其他任務(wù)。
ngx_lua
ngx_lua是將Lua嵌入Nginx,讓Nginx執(zhí)行Lua腳本,并且高并發(fā)、非阻塞的處理各種請(qǐng)求。Lua內(nèi)建協(xié)程,可以很好的將異步回調(diào)轉(zhuǎn)換成順序調(diào)用的形式。ngx_lua在Lua中進(jìn)行的IO操作都會(huì)委托給Nginx的事件模型,從而實(shí)現(xiàn)非阻塞調(diào)用。開發(fā)者可以采用串行的方式編寫程序,ngx_lua會(huì)自動(dòng)的在進(jìn)行阻塞的IO操作中終端,保存上下文,然后將IO操作委托給Nginx事件處理機(jī)制,在IO操作完成后,ngx_lua會(huì)恢復(fù)上下文,程序繼續(xù)執(zhí)行,這些操作都是對(duì)用戶程序透明的。
每個(gè)Nginx的worker進(jìn)程持有一個(gè)Lua解釋器或LuaJIT實(shí)例,這個(gè)worker處理的所有請(qǐng)求共享這個(gè)實(shí)例。每個(gè)請(qǐng)求的context上下文會(huì)被Lua輕量級(jí)的協(xié)程分隔,從而保證各個(gè)請(qǐng)求時(shí)獨(dú)立的。
ngx_lua模塊的原理
- 每個(gè)工作進(jìn)程worker創(chuàng)建一個(gè)Lua虛擬機(jī)(LuaVM),工作進(jìn)程worker內(nèi)部協(xié)議共享VM。
- -每個(gè)Nginx I/O原語(yǔ)封裝后注入Lua虛擬機(jī),并允許Lua代碼直接訪問。
- 每個(gè)外部請(qǐng)求都由一個(gè)Lua協(xié)程處理,協(xié)程之間數(shù)據(jù)隔離。
- Lua代碼調(diào)用I/O操作等異步時(shí),會(huì)掛起當(dāng)前協(xié)程,而不阻塞工作機(jī)進(jìn)程。
- I/O等異步操作完成時(shí),還原相關(guān)協(xié)程相關(guān)協(xié)議的上下文,并繼續(xù)運(yùn)行。
協(xié)程
協(xié)程,又稱微線程,纖程。英文名Coroutine。
協(xié)程的概念很早就提出來了,但直到最近幾年才在某些語(yǔ)言(如Lua)中得到廣泛應(yīng)用。
子程序,或者稱為函數(shù),在所有語(yǔ)言中都是層級(jí)調(diào)用,比如A調(diào)用B,B在執(zhí)行過程中又調(diào)用了C,C執(zhí)行完畢返回,B執(zhí)行完畢返回,最后是A執(zhí)行完畢。
所以子程序調(diào)用是通過棧實(shí)現(xiàn)的,一個(gè)線程就是執(zhí)行一個(gè)子程序。
子程序調(diào)用總是一個(gè)入口,一次返回,調(diào)用順序是明確的。而協(xié)程的調(diào)用和子程序不同。
協(xié)程看上去也是子程序,但執(zhí)行過程中,在子程序內(nèi)部可中斷,然后轉(zhuǎn)而執(zhí)行別的子程序,在適當(dāng)?shù)臅r(shí)候再返回來接著執(zhí)行。
注意,在一個(gè)子程序中中斷,去執(zhí)行其他子程序,不是函數(shù)調(diào)用,有點(diǎn)類似CPU的中斷。
Java語(yǔ)言里面解決并發(fā)問題靠的就是多線程,但線程是個(gè)重量級(jí)對(duì)象,不能頻繁創(chuàng)建和銷毀,且線程切換成本也很高,為了解決這個(gè)問題,java采用了線程池。Java沒有官方的協(xié)程支持,不過有一些庫(kù)可以支持,如:Quasar。而一些其他語(yǔ)言本身就支持協(xié)程,如:go就內(nèi)置支持協(xié)程。
所謂的協(xié)程,可以理解為是一種輕量級(jí)的線程,它與線程的主要區(qū)別在于
a. 線程切換的過程是由系統(tǒng)內(nèi)核完成,切換的過程中會(huì)進(jìn)入到內(nèi)核態(tài)。而協(xié)程則完全工作在用戶態(tài)。
b. 線程是否發(fā)生切換是由操作系統(tǒng)決定的(搶占式調(diào)度),工作線程本身沒有決定權(quán)。而協(xié)程的切換是需要工作協(xié)程主動(dòng)放棄CPU,這樣調(diào)度器才能讓另外一個(gè)協(xié)程繼續(xù)運(yùn)行。
NIO編程(同步阻塞與同步非阻塞詳解)
NIO編程(同步阻塞與同步非阻塞詳解)
參考URL: http://www.dbjr.com.cn/article/131810.htm
- BIO與NIO
IO為同步阻塞形式,NIO為同步非阻塞形式,NIO并沒有實(shí)現(xiàn)異步,在JDK1.7后升級(jí)NIO庫(kù)包,支持異步非阻塞模型NIO2.0(AIO)
- BIO(同步阻塞式IO)
同步阻塞式IO,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開銷,當(dāng)然可以通過線程池機(jī)制改善。
- NIO(同步非阻塞式IO)
同步非阻塞式IO,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請(qǐng)求一個(gè)線程,即客戶端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。
- AIO(異步非阻塞式IO)
異步非阻塞式IO,服務(wù)器實(shí)現(xiàn)模式為一個(gè)有效請(qǐng)求一個(gè)線程,客戶端的I/O請(qǐng)求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理。
- 什么是阻塞?
應(yīng)用程序在獲取網(wǎng)絡(luò)數(shù)據(jù)的時(shí)候,如果網(wǎng)絡(luò)傳輸數(shù)據(jù)很慢,就會(huì)**一直等待,**直到傳輸完畢為止。
- 什么是非阻塞?
應(yīng)用程序直接可以獲取已經(jīng)準(zhǔn)備就緒好的數(shù)據(jù),無需等待。
同步時(shí),應(yīng)用程序會(huì)直接參與IO讀寫操作,并且我們的應(yīng)用程序會(huì)直接阻塞到某一個(gè)方法上,直到數(shù)據(jù)準(zhǔn)備就緒;或者采用輪訓(xùn)的策略實(shí)時(shí)檢查數(shù)據(jù)的就緒狀態(tài),如果就緒則獲取數(shù)據(jù).
異步時(shí),則所有的IO讀寫操作交給操作系統(tǒng),與我們的應(yīng)用程序沒有直接關(guān)系,我們程序不需要關(guān)系IO讀寫,當(dāng)操作系統(tǒng)完成了IO讀寫操作時(shí),會(huì)給我們應(yīng)用程序發(fā)送通知,我們的應(yīng)用程序直接拿走數(shù)據(jù)極即可。
四、工作遇坑細(xì)節(jié)總結(jié)
inlude相對(duì)路徑、lua相對(duì)路徑問題
比如nginx啟動(dòng)如下:
/home/she/openresty/nginx/sbin/nginx -c /home/she/openresty/nginx/conf/nginx.conf
如下則配置中的include 指的就是當(dāng)前配置nginx.conf所在的路徑,即
/home/she/openresty/nginx/conf/http_vhost/*.conf
include http_vhost/*.conf; include http_upstream/*.conf;
假如其中一個(gè)conf有配置如下: 那么這里的conf/lua/access_check.lua 是哪個(gè)路徑呢?從剛才的經(jīng)驗(yàn)來看,配置中寫的相對(duì)路徑都是相關(guān)該配置當(dāng)前的路徑
location ~* /api/auth/([-_a-zA-Z0-9/]+) { access_by_lua_file conf/lua/access_check.lua; }
工作中,竟然發(fā)現(xiàn) /home/she/openresty/nginx/conf/lua/access_check.lua 修改打印一直打不出來?
猜測(cè)思考:openresty找lua腳本位置,應(yīng)該有一個(gè)配置查找路徑有優(yōu)先級(jí)。
經(jīng)過百度,果然有配置項(xiàng),lua_package_path可以配置openresty的文件尋址路徑
lua_package_path 'lua/?.lua;../lua/?.lua;/opt/openresty/nginx/conf/lua/?.lua;/opt/openresty/nginx/conf/lua/dialer/?.lua;;';
經(jīng)過測(cè)試,配置生效。
access_log 和 error_log有什么區(qū)別
日志-nginx的access_log與error_log
參考URL:http://www.dbjr.com.cn/server/298054hhs.htm
- access_log 訪問日志
access_log為訪問日志,記錄所有對(duì)apache服務(wù)器進(jìn)行請(qǐng)求的訪問,它的位置和內(nèi)容由CustomLog指令控制,LogFormat指令可以用來簡(jiǎn)化該日志的內(nèi)容和格式。
- error_log 錯(cuò)誤日志
error_log為錯(cuò)誤日志,記錄下任何錯(cuò)誤的處理請(qǐng)求,它的位置和內(nèi)容由ErrorLog指令控制,通常服務(wù)器出現(xiàn)什么錯(cuò)誤,首先對(duì)它進(jìn)行查閱**,是一個(gè)最重要的日志文件**。
總結(jié):
error_log 我們可以配置日志等級(jí),我們的lua中的ngx.log打印日志就是根據(jù)日志級(jí)別打印到該配置項(xiàng)配置的文件路徑中。
每個(gè)service配置項(xiàng)中,都可以配置自己的 access_log和error_log。從而每個(gè)服務(wù)看自己的access_log和error_log。
到此這篇關(guān)于nginx openresty 快速入門指南的文章就介紹到這了,更多相關(guān)nginx openresty內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Windows nginx安裝教程及簡(jiǎn)單實(shí)踐
這篇文章主要介紹了Windows nginx安裝教程及簡(jiǎn)單實(shí)踐的相關(guān)資料,需要的朋友可以參考下2016-10-10nginx中proxy_set_header參數(shù)的實(shí)現(xiàn)
本文詳細(xì)介紹了Nginx中proxy_set_header指令的用法,通過設(shè)置不同的請(qǐng)求頭信息,可以實(shí)現(xiàn)更靈活的反向代理功能,具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12Nginx正則表達(dá)式相關(guān)的參數(shù)和規(guī)則介紹
這篇文章主要給大家介紹了關(guān)于Nginx正則表達(dá)式相關(guān)的參數(shù)和規(guī)則的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Nginx正則表達(dá)式具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Nginx實(shí)現(xiàn)靜態(tài)資源的反向代理實(shí)例
這篇文章主要介紹了Nginx實(shí)現(xiàn)靜態(tài)資源的反向代理實(shí)例,本文通過分析github發(fā)現(xiàn)這個(gè)應(yīng)用,可以避免在https的網(wǎng)站中出現(xiàn)http鏈接,需要的朋友可以參考下2015-03-03Nginx服務(wù)器配置https安全協(xié)議的實(shí)現(xiàn)
HTTP是互聯(lián)網(wǎng)中最常用的協(xié)議,用于從服務(wù)器傳輸超文本到瀏覽器,HTTPS是HTTP的安全版本,本文就來介紹一下Nginx服務(wù)器配置https安全協(xié)議的實(shí)現(xiàn),感興趣的可以了解一下2024-09-09