When you realize you want to spend the rest of your life with somebody,you want the rest of your life to start as soon as possible.
當你意識到想和某人共度餘生時,便會恨不得下半場人生馬上開始。——《當哈利遇到莎莉》1989
基本概述
或許當提前80端口和443端口的時候,我們就能想起對應的Http訪問[基於HTTP協議]和Https訪問[基於HTTP協議+SSL證書]。記憶中比較深刻的,就是開發微信小程序時,對應域名配置述求,必須是備案認證通過的Https的服務。因此,在配置之前,我們需要了解Nginx包含着那些模塊以及配置規則,工作原理才能更好地使用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由內核和模塊組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用於URL匹配),而在這個location中所配置的每個指令將會啓動不同的模塊去完成相應的工作。
Nginx結構分析
以nginx-1.19.8版本爲例:
Nginx的源碼主要分佈在src/目錄下,而src/目錄下主要包含三部分比較重要的模塊:
-
core:基礎核心庫和框架
Nginx的核心源代碼,包括常用數據結構的以及Nginx 內核實現的核心代碼。 -
event:事件驅動模型
Nginx事件驅動模型,以及定時器的實現相關代碼。 -
http:HTTP的模塊
Nginx 實現http 服務器相關的代碼。 -
mail:郵件服務模塊
Nginx 實現郵件代理服務器相關的代碼。 -
misc:整合模塊
輔助代碼,測試C++頭 的兼容性,以及對Google_PerfTools 的支持。 -
os:系統模塊
不同體系統結構所提供的系統函數的封裝,提供對外統一的系統調用接口。 -
stream:流處理模塊
Nginx(tcp/udp)反向代理及與上游通信的基礎模塊。
Nginx 事件驅動模型
Nginx提供支持的模型主要有Select庫,Eventport庫,Poll庫,Epoll庫,Kqueue庫,Devpoll庫以及Eventport庫等。
- Select庫:在linux和windows平臺都基本支持的 事件驅動模型庫,並且在接口的定義也基本相同,只是部分參數的含義略有差異,最大併發限制1024,只最早期的事件驅動模型。
- Poll庫: 在Linux 的基本驅動模型,windows不支持此驅動模型,是select的升級版,取消了最大的併發限制,在編譯nginx的時候可以使用--with-poll_module和--without-poll_module這兩個指定是否編譯select庫。
- Epoll庫:Nginx服務器支持的最高性能的事件驅動庫之一,是公認的非常優秀的事件驅動模型,它和select和poll有很大的區別,epoll是poll的升級版,但是與poll的效率有很大的區別.epoll的處理方式是創建一個待處理的事件列表,然後把這個列表發給內核,返回的時候在去輪訓檢查這個表,以判斷事件是否發生,epoll支持一個進程打開的最大事件描述符的上限是系統可以打開的文件的最大數,同時epoll庫的IO效率不隨描述符數目增加而線性下降,因爲它只會對內核上報的“活躍”的描述符進行操作。
- Kqueue庫:用於支持BSD系列平臺的高校事件驅動模型,主要用在FreeBSD 4.1及以上版本、OpenBSD 2.0級以上版本,NetBSD級以上版本及Mac OS X 平臺上,該模型也是poll庫的變種,因此和epoll沒有本質上的區別,都是通過避免輪訓操作提供效率。
- Devpoll庫:用於支持unix衍生平臺的高效事件驅動模型,主要在Solaris 平臺、HP/UX,該模型是sun公司在開發Solaris系列平臺的時候提出的用於完成事件驅動機制的方案,它使用了虛擬的/dev/poll設備,開發人員將要見識的文件描述符加入這個設備,然後通過ioctl()調用來獲取事件通知,因此運行在以上系列平臺的時候請使用/dev/poll事件驅動機制。
- Eventport庫:是sun公司在開發Solaris的時候提出的事件驅動庫,只是Solaris 10以上的版本,該驅動庫看防止內核崩潰等情況的發生。
Nginx工作原理
Nginx的模塊從功能上分爲三類,分別是:
- Handlers(處理器模塊): 直接處理請求,並進行輸出內容和修改headers信息等操作。handlers處理器模塊一般只能有一個。
- Filters ->過濾器模塊: 主要對其他處理器模塊輸出的內容進行修改操作,最後由Nginx輸出。
- Proxies->代理類模塊: Nginx的HTTP Upstream之類的模塊,這些模塊主要與後端一些服務比如fastcgi等操作交互,實現服務代理和負載均衡等功能。
在Nginx的模塊下,一次常規的HTTP請求和響應的過程:
在工作方式上,Nginx分爲單工作進程和多工作進程兩種模式:
- 在單工作進程模式下,除主進程外,還有一個工作進程,工作進程是單線程的
- 在多工作進程模式下,每個工作進程包含多個線程
Nginx默認爲單工作進程模式。Nginx的模塊直接被編譯進Nginx,因此屬於靜態編譯方式。啓動Nginx後,Nginx的模塊被自動加載,不像在Apache一樣,首先將模塊編譯爲一個so文件,然後在配置文件中指定是否進行加載。在解析配置文件時,Nginx的每個模塊都有可能去處理某個請求,但是同一個處理請求只能由一個模塊來完成
Nginx的Http模塊
Nginx常用的模塊:
- ngx_http_access_module模塊:只有allow[允許訪問]和deny[拒絕訪問]2個值,一般用於設置和控制IP的請求,類似於網絡黑名單的功能。
location / {
root html;
index index.html index.htm;
allow 127.0.0.1; ##允許127.0.0.1訪問
deny 127.0.0.1; ##拒絕127.0.0.1訪問
}
- ngx_http_auth_basic_module模塊:實現基於用戶的訪問控制,使用basic機制進行用戶認證
location / {
root html;
index index.html index.htm;
auth_basic "Admin"; ##認證對話框的提示字符串顯示的內容
auth_basic_user_file /etc/nginx/conf/htpasswd; ##存放認證用的用戶名和文件,需要用htpasswd命令生成
}
對於htpasswd的應用需要安裝httpd-tools:
yum install httpd-tools
使用命令生成:htpasswd -c /etc/nginx/conf/htpasswd nginx
[root@cotos-pivotal nginx]# htpasswd -c /etc/nginx/conf/htpasswd nginx
New password:
Re-type new password:
Adding password for user nginx
- ngx_http_stub_status_module模塊:用來查看http的狀態信息的,使用方式直接在location裏面加stub_status
location / {
root html;
index index.html index.htm;
auth_basic "Admin"; ##認證對話框的提示字符串顯示的內容
auth_basic_user_file /etc/nginx/conf/htpasswd; ##存放認證用的用戶名和文件,需要用htpasswd命令生成
stub_status;
}
狀態參數解析:
-
Active connections: 活動狀態的連接數;
-
accepts:已經接受的客戶端請求的總數;
-
handled:已經處理完成的客戶端請求的總數;
-
requests:客戶端發來的總的請求數;
-
Reading:處於讀取客戶端請求報文首部的連接的連接數;
-
Writing:處於向客戶端發送響應報文過程中的連接數;
-
Waiting:處於等待客戶端發出請求的空閒連接數;
-
ngx_http_log_module模塊:日誌模塊
-
ngx_http_gzip_module模塊:壓縮模塊,有利於傳輸數據的大小減少,但是cpu使用會變高。因爲要對傳輸的數據進行壓縮
gzip on;
gzip_comp_level 6;
gzip_min_length 64;
gzip_proxied any;
gzip_types text/xml text/css application/javascript;
- ngx_http_ssl_module模塊: 設置https連接的模塊
server {
listen 443 ssl;
server_name www.ice.com;
root /var/www/html;
ssl on;
ssl_certificate /usr/local/nginx/ssl/ssl.crt;
ssl_certificate_key /usr/local/nginx/ssl/ssl.key;
ssl_session_cache shared:sslcache:20m;
location / {
index index.html index.htm;
}
}
- ngx_http_rewrite_module模塊:重寫指令
rewrite regex replacement [flag]:將用戶請求的URI基於regex所描述的模式進行檢查,匹配到時將其替換爲replacement指定的新的URI;
在同一級配置塊中存在多個rewrite規則,那麼會自下而下逐個檢查;被某條件規則替換完成後,會重新一輪的替換檢查,因此,隱含有循環機制;[flag]所表示的標誌位用於控制此循環機制;
其中:
-
last:如果規則有很多條。這裏重寫完成一次之後就會重新開始匹配規則,直至最後一條。也就是說。如果規則寫的不好很容易造成死循環,不停的重寫規則。
-
break:重寫完成之後不再從頭再次匹配規則。直接跳出循環
-
redirect:重寫完成後以臨時重定向方式直接返回重寫後生成的新URI給客戶端,由客戶端重新發起請求;不能以http://或https://開頭;
-
permanent:重寫完成後以永久重定向方式直接返回重寫後生成的新URI給客戶端,由客戶端重新發起請求;
-
ngx_http_referer_module模塊:防盜鏈
定義referer首部的合法可用值: -
none:請求報文首部沒有referer首部
-
blocked:請求報文的referer首部沒有值
-
server_names:參數,其可以有值作爲主機名或主機名模式
-
arbitrary_string:直接字符串,但可使用*作通配符
-
regular expression:被指定的正則表達式模式匹配到的字符串;要使用~打頭
valid_referers none block server_names *.pivotal.com ;
if($invalid_referer) {return 403; }
- ngx_http_headers_module模塊 :向由代理服務器響應給客戶端的響應報文添加自定義配置部
完整的 Nginx配置文件:
#Setting Nginx User Group
user root;
#Setting Nginx Processes
worker_processes 1;
#Setting Nginx Max Nofile
worker_rlimit_nofile 51200;
#Setting Nginx Events
events {
worker_connections 51200;
}
#Setting Nginx Http
http {
include mime.types;
default_type application/octet-stream;
#Setting Nginx FastCGI[避免504 502等]
fastcgi_connect_timeout 600s;
fastcgi_send_timeout 600s;
fastcgi_read_timeout 600s;
fastcgi_buffer_size 256k;
fastcgi_buffers 16 256k;
fastcgi_busy_buffers_size 512k;
fastcgi_temp_file_write_size 512k;
send_timeout 60000;
client_header_buffer_size 64k;
large_client_header_buffers 4 64k;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
#keepalive_timeout 0;
keepalive_timeout 120;
#文件上傳最大限制50M 默認是1m
client_max_body_size 100m;
#gzip on;
#Setting Nginx Gzip
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#Setting Nginx Reverse Proxy [反向代理配置 負載均衡]
#後臺系統web層tomcat端口 monitor-8090
upstream monitor.com{
ip_hash;
server localhost:8090 ;
}
#前臺接口web層tomcat端口proscenium-8091
upstream proscenium.com{
ip_hash;
server localhost:8091;
}
#移動接口web層tomcat端口mobile-8092
upstream mobile.com{
ip_hash;
server localhost:8092;
}
#後臺系統web層tomcat端口 schedule-8093
upstream schedule.com{
ip_hash;
server localhost:8093;
}
server {
listen 80;
server_name localhost;
#處理websocket請求
location /monitor {
#請求轉向定義的服務器列表
proxy_pass http://monitor.com/zhimeng;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超時設置 默認300s
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /proscenium {
#請求轉向定義的服務器列表
proxy_pass http://proscenium.com;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超時設置 默認300s
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /mobile {
#請求轉向定義的服務器列表
proxy_pass http://mobile.com;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超時設置 默認300s
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /schedule {
#請求轉向定義的服務器列表
proxy_pass http://schedule.com/;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超時設置 默認300s
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /staticFile {
alias /root/repository/staticFile;
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
}
}
}