nginx配置文件
一. Nginx工作原理
Nginx由內核和模塊組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用于URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應的工作。
Nginx的模塊從結構上分為核心模塊、基礎模塊和第三方模塊:
核心模塊:HTTP模塊、EVENT模塊和MAIL模塊
基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊和HTTP Rewrite模塊,
第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊。
用戶根據自己的需要開發的模塊都屬于第三方模塊。正是有了這么多模塊的支撐,Nginx的功能才會如此強大。
Nginx的模塊從功能上分為如下三類。
Handlers(處理器模塊)。此類模塊直接處理請求,并進行輸出內容和修改headers信息等操作。Handlers處理器模塊一般只能有一個。
Filters (過濾器模塊)。此類模塊主要對其他處理器模塊輸出的內容進行修改操作,最后由Nginx輸出。
Proxies (代理類模塊)。此類模塊是Nginx的HTTP Upstream之類的模塊,這些模塊主要與后端一些服務比如FastCGI等進行交互,實現服務代理和負載均衡等功能。
圖1-1展示了Nginx模塊常規的HTTP請求和響應的過程。
Nginx本身做的工作實際很少,當它接到一個HTTP請求時,它僅僅是通過查找配置文件將此次請求映射到一個location block,而此location中所配置的各個指令則會啟動不同的模塊去完成工作,因此模塊可以看做Nginx真正的勞動工作者。通常一個location中的指令會涉及一個handler模塊和多個filter模塊(當然,多個location可以復用同一個模塊)。handler模塊負責處理請求,完成響應內容的生成,而filter模塊對響應內容進行處理。
Nginx的模塊直接被編譯進Nginx,因此屬于靜態編譯方式。啟動Nginx后,Nginx的模塊被自動加載,不像Apache,首先將模塊編譯為一個so文件,然后在配置文件中指定是否進行加載。在解析配置文件時,Nginx的每個模塊都有可能去處理某個請求,但是同一個處理請求只能由一個模塊來完成。
二. Nginx的進程模型
在工作方式上,Nginx分為單工作進程和多工作進程兩種模式。在單工作進程模式下,除主進程外,還有一個工作進程,工作進程是單線程的;在多工作進程模式下,每個工作進程包含多個線程。Nginx默認為單工作進程模式。
Nginx在啟動后,會有一個master進程和多個worker進程。
1、master進程:管理進程
master進程主要用來管理worker進程,具體包括如下4個主要功能:
(1)接收來自外界的信號。
(2)向各worker進程發送信號。
(3)監控woker進程的運行狀態。
(4)當woker進程退出后(異常情況下),會自動重新啟動新的woker進程。
用戶交互接口:master進程充當整個進程組與用戶的交互接口,同時對進程進行監護。它不需要處理網絡事件,不負責業務的執行,只會通過管理worker進程來實現重啟服務、平滑升級、更換日志文件、配置文件實時生效等功能。
重啟work進程:我們要控制nginx,只需要通過kill向master進程發送信號就行了。比如kill -HUP pid,則是告訴nginx,從容地重啟nginx,我們一般用這個信號來重啟nginx,或重新加載配置,因為是從容地重啟,因此服務是不中斷的。
master進程在接收到HUP信號后是怎么做的呢?
1)、首先master進程在接到信號后,會先重新加載配置文件,然后再啟動新的worker進程,并向所有老的worker進程發送信號,告訴他們可以光榮退休了。
2)、新的worker在啟動后,就開始接收新的請求,而老的worker在收到來自master的信號后,就不再接收新的請求,并且在當前進程中的所有未處理完的請求處理完成后,再退出。
直接給master進程發送信號,這是比較傳統的操作方式,nginx在0.8版本之后,引入了一系列命令行參數,來方便我們管理。比如,./nginx -s reload,就是來重啟nginx,./nginx -s stop,就是來停止nginx的運行。如何做到的呢?我們還是拿reload來說,我們看到,執行命令時,我們是啟動一個新的nginx進程,而新的nginx進程在解析到reload參數后,就知道我們的目的是控制nginx來重新加載配置文件了,它會向master進程發送信號,然后接下來的動作,就和我們直接向master進程發送信號一樣了。
2、worker進程:處理請求
而基本的網絡事件,則是放在worker進程中來處理了。多個worker進程之間是對等的,他們同等競爭來自客戶端的請求,各進程互相之間是獨立的。一個請求,只可能在一個worker進程中處理,一個worker進程,不可能處理其它進程的請求。worker進程的個數是可以設置的,一般我們會設置與機器cpu核數一致,這里面的原因與nginx的進程模型以及事件處理模型是分不開的。
worker進程之間是平等的,每個進程,處理請求的機會也是一樣的。當我們提供80端口的http服務時,一個連接請求過來,每個進程都有可能處理這個連接,怎么做到的呢?
Nginx采用異步非阻塞的方式來處理網絡事件,類似于Libevent,具體過程如下:
1)接收請求:首先,每個worker進程都是從master進程fork過來,在master進程建立好需要listen的socket(listenfd)之后,然后再fork出多個worker進程。所有worker進程的listenfd會在新連接到來時變得可讀,每個work進程都可以去accept這個socket(listenfd)。當一個client連接到來時,所有accept的work進程都會受到通知,但只有一個進程可以accept成功,其它的則會accept失敗。為保證只有一個進程處理該連接,Nginx提供了一把共享鎖accept_mutex來保證同一時刻只有一個work進程在accept連接。所有worker進程在注冊listenfd讀事件前搶accept_mutex,搶到互斥鎖的那個進程注冊listenfd讀事件,在讀事件里調用accept接受該連接。
2)處理請求:當一個worker進程在accept這個連接之后,就開始讀取請求,解析請求,處理請求,產生數據后,再返回給客戶端,最后才斷開連接,這樣一個完整的請求就是這樣的了。
我們可以看到,一個請求,完全由worker進程來處理,而且只在一個worker進程中處理。worker進程之間是平等的,每個進程,處理請求的機會也是一樣的。
nginx的進程模型,可以由下圖來表示:
3.Nginx服務器的Web請求處理機制
Web服務器和客戶端是一對多的關系,Web服務器必須有能力同時為多個客戶端提供服務。
一般來說,完成并行處理請求工作的有三種方式可供選擇:多進程方式,多線程方式和異步方式。
多進程方式
多進程方式是指,服務器每當接收到一個客戶端時,就由服務器主進程生成一個子進程出來和客戶端建立連接進行交互,直到連接斷開,該子進程就結束。
多進程方式的優點在于,設計和實現相對簡單,各個子進程之間相互獨立,處理客戶端請求的過程彼此不受到干擾,并且當一個子進程產生問題時,不容易將影響漫延到其他進程中,這保證了提供服務的穩定性。
當子進程退出時,其占用資源會被操作系統回收,也不會留下任何垃圾。而其缺點也是明顯的。操作系統中生成一個子進程需要進行內存復制等操作,在資源和時間上會產生一定的額外開銷,因此,如果Web服務器接收大量并發請求,就會對系統資源造成壓力,導致系統性能下降。
初期的Apache服務器就是采用這種方式對外提供服務的。為了應對大量并發請求,Apache服務器采用“預生成進程”的機制對多線程方式進行了改進。“預生成進程”的工作方式很好理解。
它將生成子進程的時機提前,在客戶端請求還沒有到來之前就預先生成好,當請求到來時,主進程分配一個子進程和該客戶端進行交互,交互完成之后,該進程也不結束,而被主進程管理起來等待下一個客戶端請求的到來。
改進的多進程方式在一定程度上緩解了大量并發請求情形下Web服務器對系統資源造成的壓力。但是由于Apache服務器在最終的架構設計上采用了多進程方式,因此這不能從根本上解決問題。
多線程方式
多線程方式和多進程方式相似,它是指,服務器每當接收到一個客戶端時,會有服務器主進程派生一個線程出來和該客戶端進行交互。
由于操作系統產生一個線程的開銷遠遠小于產生一個進程的開銷,所以多線程方式在很大程度上減輕了Web服務器對系統資源的要求。
該方式使用線程進行任務調度,開發方面可以遵循一定的標準,這相對來說比較規范和有利于協作。但在線程管理方面,該方式有一定的不足。
多個線程位于同一個進程內,可以訪問同樣的內存空間,彼此之間相互影響。同時,在開發過程中不可避免地要由開發者自己對內存進行管理,其增加了出錯的風險。服務器系統需要長時間連續不停的運轉,錯誤的逐漸積累可能最終對整個服務器產生重大影響。
IIS服務器使用了多線程方式對外提供服務,它的穩定性相對來說還是不錯的,但對于經驗豐富的Web服務器管理人員而言,他們通常還是會定期檢查和重啟服務器,以預防不可預料的故障發生。
異步方式
異步方式是和多進程方式及多線程方式完全不同的一種處理客戶端請求的方式。在介紹該方式之前,我們先復習一下同步、異步以及阻塞、非阻塞的概念。
網絡通信中的同步機制和異步機制是描述通信模式的概念。同步機制,是指發送方發送請求后,需要等待接收到接收方發回的響應后,才接著發送下一個請求。
異步機制,和同步機制正好相反,在異步機制中,發送方發出一個請求后,不等待接收方響應這個請求,就繼續發送下個請求。在同步機制中,所有的請求在服務器端得到同步,發送方和接收方對請求的處理步調是一致的。在異步機制中,所有來自發送方的請求形成一個隊列,接收方處理完成后通知發送方。
阻塞和非阻塞用來描述進程處理調用的方式,在網絡通信中,主要指網絡套接字Socket的實質也就是IO操作。
Socket的阻塞調用方式為,調用結果返回之前,當前線程從運行狀態被掛起,一定等到調用結果返回之后,才進入就緒狀態,獲取CPU后繼續執行。
Socket的非阻塞調用方式和阻塞調用方式正好相反,在非阻塞方式中,如果調用結果不能馬上返回,當前線程也不會被掛起,而是立即返回執行下一個調用。 在網絡通信中,經常可以看到有人將同步和阻塞等同、異步和非阻塞等同。事實上,這兩對概念有一定的區別,不能混淆。兩對概念的組合,就會產生四個新的概念,同步阻塞、異步阻塞、同步非阻塞、異步非阻塞。
同步阻塞方式,發送方接收方發送請求后,一直等待響應。接收方處理請求時進行的IO操作如果不能馬上得到結果,就一直等到返回結果后,才響應發送方,期間不能進行其他工作。
比如,在超市排隊付賬時,客戶(發送方)向收款員(接收方)付款(發送請求)后需要等待收款員找零,期間不能做其他的事情。而收款員要等待收款機返回結果(IO操作)后才能把零錢取出來交給客戶(響應請求),期間也只能等待,不能做其他事情。這種方式實現簡單,但是效率不高。
同步非阻塞方式,發送方向接收方發送請求后,一直等待響應。接收方處理請求時進行的IO操作如果補鞥呢馬上得到結果,就立刻返回,去做其他事情,但由于沒有得到請求處理結果,不響應發送方,發送方一直等待,一直到IO操作完成后,接收方獲得結果響應發送方后,接收方才進入下一次請求過程。在實際中不適用這種方式。
異步阻塞方式,發送方向接收方發送請求后,不用等待響應,可以接著進行其他工作。接收方處理請求時進行的IO操作如果不能馬上得到結果,就一直等到返回結果后,才響應發送方,期間不能進行其他工作。這種方式在實際中也不使用。
異步非阻塞方式,發送方向接收方發送請求后,不用等待響應,可以繼續其他工作。接收方處理請求時進行的IO操作如果不能馬上得到結果,也不等待,而是馬上返回去做其他事情,當IO操作完成以后,將完成狀態和結果通知接收方,接收方再響應發送方。
繼續使用在超市排隊付賬的例子。客戶(發送方)向收款員(接收方)付款(發送請求)后在等待收款員找零的過程中,還可以做其他事情,比如打電話、聊天等。
而收款員在等待收款機產生結果后,收款員給客戶端結賬(響應請求)。在四種方式中,這種方式是發送方和接收方通信效率最高的一種。
Nginx服務器如何處理請求
Nginx服務器的一個顯著優勢是能夠同時處理大量并發請求。它結合多進程機制和異步機制對外提供服務。異步機制使用的是異步非阻塞方式。
Nginx服務器啟動后,可以產生一個主進程(master process)和多個工作進程(worker processes),其中可以在配置文件中指定產生的工作進程數量。Nginx服務器的所有工作進程都用于接收和處理客戶端的請求。
這類似于Apache使用的改進的多進程機制,預先生成多個工作進程,等待處理客戶端請求。
注意
實際上,Nginx服務器的進程模型有兩種:Single模型和Master-Worker模型。Single模型為單進程方式,性能較差,一般在實際工作中不使用。
Master-Worker模型實際上被更廣泛地稱為Master-Slave模型。在Nginx服務器中,充當Slave角色的是工作進程。
每個工作進程使用了異步非阻塞方式,可以處理多個客戶端請求。當某個工作進程接收到客戶端的請求以后,調用IO進行處理,如果不能立即得到結果,就去處理其他的請求。而客戶端在此期間也無需等待響應,可以去處理其他的事情。當IO調用返回結果時,就會通知此工作進程。
該進程得到通知,暫時掛起當前處理的事務,去響應客戶端請求。 客戶端請求數量增長、網絡負載繁重時,Nginx服務器使用多進程機制能夠保證不增長對系統資源的壓力。
同時使用異步非阻塞方式減少了工作進程在I/O調用上的阻塞延遲,保證了不降低對請求的處理能力。
Nginx服務器的事件處理機制
Nginx服務器的工作進程調用IO后,就去進行其他工作了。當IO調用返回后,會通知工作進程。這里有一個問題,IO調用時如何把自己的狀態通知給工作進程的呢?
一般解決這個問題的方案有兩種。一是,讓工作進程在進行其他工作的過程中間隔一段時間就去檢查一下IO的運行狀態,如果完成,就去響應客戶端,如果未完成就繼續正在進行的工作。
而是,IO調用在完成后能主動通知工作進程。對于前者,雖然工作進程在IO調用過程中沒有等待,但不斷的檢查仍然在時間和資源上導致了不小的開銷,最理想的解決方案是第二種。
具體來說,select/poll/epoll/kqueue等這樣的系統調用就是用來支持第二種解決方案的。
這些系統調用,也被稱為時間驅動模型,它們提供了一種機制,讓進程可以同時處理多個并發請求,不用關心IO調用的具體狀態。IO調用完全由事件驅動模型來管理,事件準備好之后就通知工作進程已經就緒。
3.nginx的安裝
//創建用戶 [root@localhost ~]# useradd -r -M -s /sbin/nologin nginx //安裝依賴包 [root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ [root@localhost ~]# yum -y groups mark install 'Development Tools' 創建日志存放目錄 [root@nginx ~]# mkdir -p /var/log/nginx [root@nginx ~]# chown -R nginx.nginx /var/log/nginx 下載nginx [root@nginx ~]# cd /usr/src [root@nginx src]# wget http://nginx.org/download/nginx-1.20.1.tar.gz [root@nginx src]# [root@nginx src]# ls debug zabbix-5.4.4 kernels zabbix-5.4.4.tar.gz nginx-1.20.1.tar.gz [root@nginx src]# //編譯安裝 [root@nginx src]# tar xf nginx-1.20.1.tar.gz [root@nginx src]# cd nginx-1.20.1 [root@nginx nginx-1.20.1]# ./configure \ > --prefix=/usr/local/nginx \ > --user=nginx \ > --group=nginx \ > --with-debug \ > --with-http_ssl_module \ > --with-http_realip_module \ > --with-http_image_filter_module \ > --with-http_gunzip_module \ > --with-http_gzip_static_module \ > --with-http_stub_status_module \ > --http-log-path=/var/log/nginx/access.log \ > --error-log-path=/var/log/nginx/error.log [root@nginx nginx-1.20.1]# make && make install4.nginx的配置
配置環境變量
[root@nginx ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh [root@nginx ~]# . /etc/profile.d/nginx.sh [root@nginx ~]# //服務控制方式,使用nginx命令-t //檢查配置文件語法-v //輸出nginx的版本-c //指定配置文件的路徑ginx.conf配置詳解
nginx.conf的內容分為以下幾段:
main配置段:全局配置段。其中main配置段中可能包含event配置段
event {}:定義event模型工作特性
http {}:定義http協議相關的配置
5.優化性能的配置參數
worker_processes n; 啟動n個worker進程,這里的n為了避免上下文切換,通常設置為cpu總核心數-1或等于總核心數
[root@nginx conf]# head /opt/nginx.conf #user nobody; worker_processes 4;#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;#pid logs/nginx.pid;[root@nginx conf]# [root@nginx conf]# head /usr/local/nginx/conf/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;6網絡連接相關的配置參數
keepalive_timeout number; //長連接的超時時長,默認為65s keepalive_requests number; //在一個長連接上所能夠允許請求的最大資源數 keepalive_disable [msie6|safari|none]; //為指定類型的UserAgent禁用長連接 tcp_nodelay on|off; //是否對長連接使用TCP_NODELAY選項,為了提升用戶體驗,通常設為on client_header_timeout number; //讀取http請求報文首部的超時時長 client_body_timeout number; //讀取http請求報文body部分的超時時長 send_timeout number; //發送響應報文的超時時長Nginx配置文件
[root@localhost ~]# vim /usr/local/nginx/conf全局塊user www-data; ##用戶worker_processes 2; ## 默認1,一般建議設成CPU核數1-2倍error_log logs/error.log; ## 錯誤日志路徑pid logs/nginx.pid; ## 進程id# Events塊events {# 使用epoll的I/O 模型處理輪詢事件。# 可以不設置,nginx會根據操作系統選擇合適的模型use epoll;# 工作進程的最大連接數量, 默認1024個worker_connections 2048;# http層面的keep-alive超時時間keepalive_timeout 60;# 客戶端請求頭部的緩沖區大小client_header_buffer_size 2k;}# http塊http { include mime.types; # 導入文件擴展名與文件類型映射表default_type application/octet-stream; # 默認文件類型# 日志格式及access日志路徑log_format main '$remote_addr - $remote_user [$time_local] $status ''"$request" $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log logs/access.log main; # 允許sendfile方式傳輸文件,默認為off。sendfile on;tcp_nopush on; # sendfile開啟時才開啟。# http server塊# 簡單反向代理server {listen 80;server_name domain2.com www.domain2.com;access_log logs/domain2.access.log main;# 轉發動態請求到web應用服務器location / {proxy_pass http://127.0.0.1:8000;deny 192.168.197.128; # 拒絕的ipallow 192.168.197.131; # 允許的ip }# 錯誤頁面error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}# 負載均衡upstream backend_server {server 192.168.0.1:8000 weight=5; # weight越高,權重越大server 192.168.0.2:8000 weight=1;server 192.168.0.3:8000;server 192.168.0.4:8001 backup; # 熱備}server {listen 80;server_name big.server.com;access_log logs/big.server.access.log main;charset utf-8;client_max_body_size 10M; # 限制用戶上傳文件大小,默認1Mlocation / {# 使用proxy_pass轉發請求到通過upstream定義的一組應用服務器proxy_pass http://backend_server;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_redirect off;proxy_set_header X-Real-IP $remote_addr;} }}正常運行必備的配置參數
user USERNAME [GROUPNAME]; 指定運行worker進程的用戶和組 Syntax: user user [group]; #語法 Default: user nobody nobody; #默認值 Context: main #可以配置在那個字段中 #user nobody; //取消掉注釋,手動更改用戶 worker_processes 1;pid /path/to/pid_file; 指定nginx守護進程的pid文件#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; //取消掉注釋 worker_rlimit_nofile number; 設置所有worker進程最大可以打開的文件數,默認為1024,最大值為655350 Syntax: worker_rlimit_nofile number; Default: 1024 Context: main worker_rlimit_core size; 指明所有worker進程所能夠使用的總體的最大核心文件大小,保持默認即可 Syntax: worker_rlimit_core size; Default: — Context: main 優化性能的配置參數 worker_processes n; 啟動n個worker進程,這里的n為了避免上下文切換,通常設置為cpu總核心數-1或等于總核心數,最大值為509 [root@centos8-1 ~]# vim /usr/local/nginx/conf/nginx.conf #user nobody; worker_processes 6; //這里的默認是1 [root@centos8-1 ~]# nginx -s reload [root@centos8-1 ~]# ps -ef | grep nginx root 19230 1 0 06:25 ? 00:00:00 nginx: master process nginx nginx 19373 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19374 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19375 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19376 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19377 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19378 19230 0 06:25 ? 00:00:00 nginx: worker process root 19741 1509 0 06:26 pts/0 00:00:00 grep --color=auto nginx 注意:worker_processes的數量*worker_connections的數量=nginx所能支持的最大并發連接數量,在實際情況最大并發數建議不超過30000 worker_cpu_affinity cpumask …; 將進程綁定到某cpu中,避免頻繁刷新緩存,似于專人專事,建議不要把所有的cpu都綁定,至少留一個cpu來讓系統正常運行 [root@centos8-1 ~]# nproc [root@centos8-1 ~]# vim /usr/local/nginx/conf/nginx.conf #user nobody; worker_processes 6; worker_cpu_affinity 0001 0010 0100; //添加此行 [root@centos8-1 ~]# ps -ef | grep nginx root 19230 1 0 06:25 ? 00:00:00 nginx: master process nginx nginx 19373 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19374 19230 0 06:25 ? 00:00:00 nginx: worker process nginx 19375 19230 0 06:25 ? 00:00:00 nginx: worker process [root@centos8-1 ~]# top Tasks: 189 total, 3 running, 186 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.3 us, 0.8 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.1 hi, 0.1 si, 0.0 st MiB Mem : 3708.8 total, 3202.8 free, 265.7 used, 240.3 buff/cache timer_resolution interval; 計時器解析度。降低此值,可減少gettimeofday()系統調用的次數 Syntax: timer_resolution interval; Default: — Context: main worker_priority number; 指明worker進程的nice值 [root@centos8-1 ~]# vim /usr/local/nginx/conf/nginx.conf #user nobody; worker_processes 6; worker_cpu_affinity 0001 0010 0100; worker_priority -20; [root@centos8-1 ~]# ps -elf | grep nginx 1 S root 42232 1 0 80 0 - 20408 - 06:38 ? 00:00:00 nginx: master process nginx 5 S nginx 42233 42232 0 60 -20 - 28556 do_epo 06:38 ? 00:00:00 nginx: worker process 5 S nginx 42234 42232 0 60 -20 - 28556 do_epo 06:38 ? 00:00:00 nginx: worker process 5 S nginx 42235 42232 0 60 -20 - 28556 do_epo 06:38 ? 00:00:00 nginx: worker process 5 S nginx 42236 42232 0 60 -20 - 28556 do_epo 06:38 ? 00:00:00 nginx: worker process 5 S nginx 42237 42232 0 60 -20 - 28556 do_epo 06:38 ? 00:00:00 nginx: worker process 5 S nginx 42238 42232 0 60 -20 - 28556 do_epo 06:38 ? 00:00:00 nginx: worker process 0 S root 45041 1509 0 80 0 - 3087 - 06:39 pts/0 00:00:00 grep --color=auto nginx [root@centos8-1 ~]# 事件相關的配置:event{}段中的配置參數 accept_mutex {off|on}; master調度用戶請求至各worker進程時使用的負載均衡鎖;on表示能讓多個worker輪流地、序列化地去響應新請求 Syntax: accept_mutex on | off; Default: accept_mutex off; Context: events lock_file file; accept_mutex用到的互斥鎖鎖文件路徑 Syntax: lock_file file; Default: lock_file logs/nginx.lock; Context: main use [epoll | rtsig | select | poll]; 指明使用的事件模型,建議讓nginx自行選擇 Syntax: use method; Default: — Context: eventsserver {}:定義一個虛擬主機
......server{listen 82;server_name www.shuaige.com;location / {root html/test;index index.html;}}......[root@Nginx ~]# cd /usr/local/nginx/html/ [root@Nginx html]# ls 50x.html index.html [root@Nginx html]# mkdir test [root@Nginx html]# ls 50x.html index.html test [root@Nginx html]# echo 'sb' test/index.html [root@centos8-1 html]# nginx -s stop;nginx [root@centos8-1 html]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:82 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* //listen:指定監聽的地址和端口 listen address[:port]; listen port;//server_name NAME [...]; 后面可跟多個主機,名稱可使用正則表達式或通配符,當存在多個server時,匹配順序如下:1. 先做精確匹配檢查 2. 左側通配符匹配檢查,如*.example.com 3. 右側通配符匹配檢查,如web.* 4. 正則表達式匹配檢查,如~ ^.*\.example\.com$ 5. default_serverhttp{}段的配置參數
http{…}段是配置http相關,由ngx_http_core_module模塊引入。nginx的HTTP配置主要包括四個區塊http { //協議級別include mime.types;default_type application/octet-stream;keepalive_timeout 65;gzip on;upstream { //負載均衡配置...}server { //服務器級別,每個server類似于httpd中的一個<VirtualHost>listen 80;server_name localhost;location / { //請求級別,類似于httpd中的<Location>,用于定義URL與本地文件系統的映射關系root html;index index.html index.htm;}} }keepalive_timeout number; 長連接的超時時長,默認為65s
[root@centos8-1 ~]# vim /usr/local/nginx/conf/nginx.confsendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;http{}段配置指令:
server {}:定義一個虛擬主機,示例如下:server{ ? listen 81;(端口) ? server_name www.lp.com;(域名可以給多個) ? location / { ? root html/test; (網站位置) or alias /var/www/html/;(別名,但是別名一定要寫絕對路徑,就是把資源放到另外一個位置,當有人訪問時,看見的路徑是/根下面,其實我們已經放在了另一個位置,防止被攻擊) ? index index.html;listen:指定監聽的地址和端口
listen address[:port];server_name NAME […]; 后面可跟多個主機,名稱可使用正則表達式或通配符
當有多個server時,匹配順序如下:
1.先做精確匹配檢查
2.左側通配符匹配檢查,如*.idfsoft.com
3.右側通配符匹配檢查,如mail.*
4.正則表達式匹配檢查,如~ ^.*.idfsoft.com$
5.default_server
root path; 設置資源路徑映射,用于指明請求的URL所對應的資源所在的文件系統上的起始路徑
alias path; 用于location配置段,定義路徑別名
//注意:此處可用變量為nginx各模塊內建變量
location區段,通過指定模式來與客戶端請求的URI相匹配
//功能:允許根據用戶請求的URI來匹配定義的各location,匹配到時,此請求將被相應的location配置塊中的配置所處理,例如做訪問控制等功能
//語法:location [ 修飾符 ] pattern {…}
error_page code […] [=code] URI | @name 根據http響應狀態碼來指明特用的錯誤頁面,例如 error_page 404 /404.html;[root@localhost nginx]# vim /usr/local/nginx/conf/nginx.conf error_page 404 /404.html; [root@localhost nginx]# vim html/404.html [root@localhost nginx]# cat html/404.html <html> <head> <title>test page</title> </head> <body> <a href="http://www.baidu.com">baidu</a> <html> [root@localhost nginx]# systemctl restart nginx.service訪問ip不會再報錯404,而是會出現一個鏈接
進去后便是百度官網
[=code]:以指定的響應碼進行響應,而不是默認的原來的響應,默認表示以新資源的響應碼為其響應碼,例如 error_page 404 =200 /404.html
[root@localhost nginx]# vim /usr/local/nginx/conf/nginx.conf error_page 404 =200 /404.html; [root@localhost nginx]# systemctl restart nginx.service 狀態會顯示為200log_format 定義日志格式log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"'; [root@localhost nginx]# tail -f logs/access.log 192.168.101.1 - - [27/Oct/2021:15:26:04 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.8031 SLBChan/25" "-" $remote_addr :遠程主機地址 $remote_user:遠程用戶 $time_local:本地時間 $request:請求資源 $status:狀態碼 $body_bytes_sent:發送主題的字節數 $http_referer:是否是跳轉過來的 $http_user_agent:用戶代理 $http_x_forwarded_for:從哪跳轉過來的location區段,通過指定模式來與客戶端請求的URI相匹配
//功能:允許根據用戶請求的URI來匹配定義的各location,匹配到時,此請求將被相應的location配置塊中的配置所處理,例如做訪問控制等功能
//語法:location [ 修飾符 ] pattern {…}
常用修飾符說明:
修飾符 功能
= 精確匹配
~ 正則表達式模式匹配,區分大小寫
~* 正則表達式模式匹配,不區分大小寫
^~ 前綴匹配,類似于無修飾符的行為,也是以指定模塊開始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正則表達式
@ 定義命名location區段,這些區段客戶端不能訪問,只可以由內部產生的請求來訪問,如try_files或error_page等
沒有修飾符
精確匹配
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation =/test {echo "test";}[root@localhost ~]# nginx -s reload##如下內容就可正確匹配 [root@localhost ~]# curl http://192.168.101.210/test test##如下內容則無法匹配
[root@localhost ~]# curl http://192.168.101.210/testdasdasd <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.20.1</center> </body> </html>正則表達式模式匹配(區分大小寫)
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf location ^~ /test {echo "test";} [root@localhost ~]# curl http://192.168.101.210/test test [root@localhost ~]# curl http://192.168.101.210/Test <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.20.1</center> </body> </html>正則表達式模式匹配(不區分大小寫)
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf location ~* /test {echo "test";} [root@localhost ~]# curl http://192.168.101.210/test test [root@localhost ~]# curl http://192.168.101.210/Test test~:類似于無修飾符的行為,也是以指定模式開始,不同的是,如果模式匹配,則停止搜索其他模式
優先級次序
( location = 路徑 ) --> ( location ^~ 路徑 ) --> ( location ~ 正則 ) --> ( location ~* 正則 ) --> ( location 路徑 )
查找順序和優先級:由高到底依次為
1.帶有=的精確匹配優先
2.正則表達式按照他們在配置文件中定義的順序
3.帶有^~修飾符的,開頭匹配
4.帶有或*修飾符的,如果正則表達式與URI匹配
5.沒有修飾符的精確匹配
示例:
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation / {root html;index index.html index.html;}location /test {echo "test1";}location ~ ^ /test {echo "test2";}location ~* /test {echo "test3";}[root@localhost ~]# nginx -s reload優先級測試
[root@localhost ~]# curl http://192.168.168.210/test test2 [root@localhost ~]# curl http://192.168.168.210/testid test1 [root@localhost ~]# curl http://192.168.168.210/TEST test3訪問控制
注:用于location段,可以用主機地址表示,也可用網段表示,必須一起用
allow:設定允許那臺或那些主機訪問,多個參數間用空格隔開
deny:設定禁止那臺或那些主機訪問,多個參數間用空格隔開
在matser主機上修改nginx配置文件,將192.168.50.0網段禁止訪問
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation / {root html;index index.html index.htm;allow 192.168.101.210/32;deny 192.168.101.110/32;} [root@localhost ~]# nginx -s reload主機為192.168.101.210訪問
[root@localhost ~]# curl http://192.168.101.210 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p><p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p> </body> </html>主機為192.168.101.110訪問
[root@localhost ~]# curl http://192.168.101.210 <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.20.1</center> </body> </html>將deny字段改為all,表示在拒絕所有主機訪問
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation / {root html;index index.html index.htm;allow 192.168.101.210/32;deny 192.168.101.110/32;deny allow;} [root@localhost ~]# nginx -s reload再次訪問
https配置
server {listen 443 ssl;server_name luojk.com;ssl_certificate ssl/nginx.crt;ssl_certificate_key ssl/nginx.key;ssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;ssl_ciphers HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers on;location / {root html;index index.html index.htm;}}開啟狀態界面
開啟status:
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf location / {root html;index index.html index.htm;}location /status {stub_status;} [root@localhost ~]# nginx -s reload狀態頁面信息詳解:
狀態碼 表示的意義
Active connections 2 當前所有處于打開狀態的連接數
accepts 總共處理了多少個連接
handled 成功創建多少握手
requests 總共處理了多少個請求
Reading nginx讀取到客戶端的Header信息數,表示正處于接收請求狀態的連接數
Writing nginx返回給客戶端的Header信息數,表示請求已經接收完成, 且正處于處理請求或發送響應的過程中的連接數
Waiting 開啟keep-alive的情況下,這個值等于active - (reading + writing), 意思就是Nginx已處理完正在等候下一次請求指令的駐留連接
rewrite
語法:rewrite regex replacement flag;,如:
常見的flag
flag 作用
last 基本上都用這個flag,表示當前的匹配結束,繼續下一個匹配,最多匹配10個到20個 一旦此rewrite規則重寫完成后,就不再被后面其它的rewrite規則進行處理 而是由UserAgent重新對重寫后的URL再一次發起請求,并從頭開始執行類似的過程
break 中止Rewrite,不再繼續匹配 一旦此rewrite規則重寫完成后,由UserAgent對新的URL重新發起請求, 且不再會被當前location內的任何rewrite規則所檢查
redirect 以臨時重定向的HTTP狀態302返回新的URL
permanent 以永久重定向的HTTP狀態301返回新的URL
last
瀏覽器訪問IP/luo/tian.html時結果為百度頁面
rewrite模塊的作用是用來執行URL重定向。這個機制有利于去掉惡意訪問的url,也有利于搜索引擎優化(SEO)
nginx使用的語法源于Perl兼容正則表達式(PCRE)庫,基本語法如下:
標識符 意義
^ 必須以^后的實體開頭
$ 必須以$前的實體結尾
. 匹配任意字符
[] 匹配指定字符集內的任意字符
[^] 匹配任何不包括在指定字符集內的任意字符串
| 匹配 之前或之后的實體
() 分組,組成一組用于匹配的實體,通常會有
if
語法:if (condition) {…}
應用場景:
server段
location段
常見的condition
變量名(變量值為空串,或者以“0”開始,則為false,其它的均為true)
以變量為操作數構成的比較表達式(可使用=,!=類似的比較操作符進行測試)
正則表達式的模式匹配操作
~:區分大小寫的模式匹配檢查
~:不區分大小寫的模式匹配檢查
!和!:對上面兩種測試取反
測試指定路徑為文件的可能性(-f,!-f)
測試指定路徑為目錄的可能性(-d,!-d)
測試文件的存在性(-e,!-e)
檢查文件是否有執行權限(-x,!-x)
基于瀏覽器實現分離案例
防盜鏈案例
location ~* \.(jpg|gif|jpeg|png)$ {valid_referers none blocked www.idfsoft.com;if ($invalid_referer) {rewrite ^/ http://www.idfsoft.com/403.html;} }zabbix監控nginx status
開啟狀態界面
開啟status:
編寫腳本:
[root@localhost conf]# cat status.sh #!/bin/bashif [ `curl -s http://192.168.197.128/status|awk 'NR==4 {print $2}' ` -ne 0 ];thenecho 1 elseecho 0配置zabbix配置文件
[root@localhost conf]# vim /usr/local/etc/zabbix_agentd.conf UserParameter=check_status[*],/usr/local/nginx/conf/status.sh服務端測試
[root@localhost ~]# zabbix_get -s 192.168.197.128 -k check_status 0瀏覽器配置監控
總結
- 上一篇: sqlite的数据导入 导出
- 下一篇: 在ubuntu上搭建LNMP服务器