您好,登錄后才能下訂單哦!
14.1 nginx簡介
Nginx(發音同engine x)是一款輕量級的Web服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,并在一個BSD-like協議下發行。
Nginx由俄羅斯的程序設計師Igor Sysoev所開發,最初供俄國大型的入口網站及搜尋引擎Rambler使用。
第一個公開版本0.1.0發布于2004年10月4日。其將源代碼以類BSD許可證的形式發布,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。2011年6月1日,nginx 1.0.4發布。
nginx的特點是占有內存少,并發能力強,事實上nginx的并發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。
14.2 nginx的特性與優點
14.2.1 nginx的特性
Nginx是一個很牛的高性能Web和反向代理服務器,它具有很多非常優越的特性:
在高連接并發的情況下,Nginx是Apache服務器不錯的替代品,能夠支持高達50000個并發連接數的響應
使用epoll and kqueue作為開發模型
Nginx作為負載均衡服務器:Nginx既可在內部直接支持和PHP程序對外進行服務,也可支持作為HTTP代理服務器對外進行服務
Nginx采用C進行編寫,不論系統資源開銷還是CPU使用效率都比Perlbal要好很多
14.2.2 nginx的優點
Nginx的優點:
高并發連接:官方測試能夠支撐5萬并發連接,在實際生產環境中跑到2-3萬并發連接數
內存消耗少:在3萬并發連接下,開啟的10個Nginx進程才消耗150M內存(15M*10=150M)
配置文件非常簡單:風格跟程序一樣通俗易懂
成本低廉:Nginx為開源軟件,可以免費使用。而購買F5 BIG-IP、NetScaler等硬件負載均衡交換機則需要十多萬至幾十萬人民幣
支持Rewrite重寫規則:能夠根據域名、URL的不同,將HTTP請求分到不同的后端服務器群組
內置的健康檢查功能:如果Nginx Proxy后端的某臺Web服務器宕機了,不會影響前端訪問
節省帶寬:支持GZIP壓縮,可以添加瀏覽器本地緩存的Header頭
穩定性高:用于反向代理,宕機的概率微乎其微
模塊化設計:模塊可以動態編譯
外圍支持好:文檔全,二次開發和模塊較多
支持熱部署:可以不停機重載配置文件
支持事件驅動、AIO(AsyncIO,異步IO)、mmap(Memory Map,內存映射)等性能優化
14.3 nginx的功能及應用類別
14.3.1 nginx的基本功能
Nginx基本功能:
靜態資源的web服務器,能緩存打開的文件描述符
http、smtp、pop3協議的反向代理服務器
緩存加速、負載均衡
支持FastCGI(fpm,LNMP),uWSGI(Python)等
模塊化(非DSO機制),過濾器zip、SSI及圖像的大小調整
支持SSL
14.3.2 nginx的擴展功能
Nginx擴展功能:
基于名稱和IP的虛擬主機
支持keepalive
支持平滑升級
定制訪問日志、支持使用日志緩沖區提高日志存儲性能
支持URL重寫
支持路徑別名
支持基于IP及用戶的訪問控制
支持速率限制,支持并發數限制
14.3.3 nginx的應用類別
Nginx的主要應用類別:
使用Nginx結合FastCGI運行PHP、JSP、Perl等程序
使用Nginx作反向代理、負載均衡、規則過濾
使用Nginx運行靜態HTML網頁、圖片
Nginx與其他新技術的結合應用
14.4 nginx的模塊與工作原理
Nginx由內核和模塊組成。其中,內核的設計非常微小和簡潔,完成的工作 也非常簡單,僅僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令,用于URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應的工作。
14.4.1 nginx的模塊分類
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等操作交互,實現服務代理和負載均衡等功能
Nginx模塊分為:核心模塊、事件模塊、標準Http模塊、可選Http模塊、郵件模塊、第三方模塊和補丁等
Nginx基本模塊:所謂基本模塊,指的是Nginx默認的功能模塊,它們提供的指令,允許你使用定義Nginx基本功能的變量,在編譯時不能被禁用,包括:
核心模塊:基本功能和指令,如進程管理和安全。常見的核心模塊指令,大部分是放置在配置文件的頂部
事件模塊:在Nginx內配置網絡使用的能力。常見的events(事件)模塊指令,大部分是放置在配置文件的頂部
配置模塊:提供包含機制
具體的指令,請參考nginx的官方文檔,詳見http://nginx.org/en/docs/ngx_core_module.html
14.4.2 nginx的工作原理
Nginx的模塊直接被編譯進Nginx,因此屬于靜態編譯方式。
啟動Nginx后,Nginx的模塊被自動加載,不像在Apache一樣,首先將模塊編譯為一個so文件,然后在配置文件中指定是否進行加載。
在解析配置文件時,Nginx的每個模塊都有可能去處理某個請求,但是同一個處理請求只能由一個模塊來完成。
Nginx的基本架構:
一個master進程,生成一個或多個worker進程
事件驅動:epoll(邊緣觸發)、kqueue,/dev/poll
復用器:select,poll,rt signal
支持sendfile,sendfile64
支持AIO
支持mmap
Nginx的進程結構:
啟動Nginx時,會啟動一個Master進程,這個進程不處理任何客戶端的請求,主要用來產生worker線程,一個worker線程用來處理n個request
下圖展示了Nginx模塊下一次常規的HTTP請求和響應的過程:
下圖展示了HTTP基于套接字通信:
下圖展示了基本的WEB服務請求步驟:
14.5 nginx的安裝與配置
14.5.1 nginx的安裝
useradd nginx -M -s /sbin/nologin yum -y install pcre-devel openssl openssl-devel gd-devel yum -y groupinstall "Development Tools" mkdir -pv /data/logs/nginx cd /usr/src wget http://nginx.org/download/nginx-1.12.0.tar.gz tar xf nginx-1.12.0.tar.gz cd nginx-1.12.0 ./configure \ --prefix=/usr/local/nginx \ --user=nginx \ --group=nginx \ --with-debug \ --with-http_ssl_module \ --with-http_realip_module \ --with-http_p_w_picpath_filter_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_stub_status_module \ --http-log-path=/data/logs/nginx/access.log \ --error-log-path=/data/logs/nginx/error.log make && make install
14.5.2 nginx的配置文件
配置文件:/usr/local/nginx/conf/nginx.conf
默認啟動Nginx時,使用的配置文件是:安裝路徑/conf/nginx.conf文件
可以在啟動nginx時通過-c選項來指定要讀取的配置文件
nginx常見的配置文件有如下幾個:
nginx.conf應用程序的基本配置文件
mime.typesMIME類型關聯的擴展文件
fastcgi.conf 與fastcgi相關的配置
proxy.conf與proxy相關的配置
sites.conf配置Nginx提供的網站,包括虛擬主機
nginx.conf配置詳解:
nginx.conf的內容分為以下幾段:
main配置段:全局配置段。其中main配置段中可能包含event配置段
event {}:定義event模型工作特性
http {}:定義http協議相關的配置
配置指令:要以分號結尾,語法格式如下:
derective value1 [value2 ...]
支持使用變量:
內置變量:模塊會提供內建變量定義
自定義變量:
set var_name value
14.5.3 nginx.conf常用配置詳解
nginx.conf配置段的指令有以下幾類:
用于調試、定位問題:
daemon {on|off}; #是否以守護進程方式運行nginx,調試時應設置為off master_process {on|off}; #是否以master/worker模型來運行nginx,調試時可以設置為off error_log 位置 級別; #配置錯誤日志
位置有以下幾種:
file
stderr
syslog:server=address[,parameter=value]
memory:size
級別可選值有:
debug:若要使用debug級別,需要在編譯nginx時使用--with-debug選項
info
notice
warn
error
crit
alert
emerg
正常運行必備的配置:
user USERNAME [GROUPNAME]; #指定運行worker進程的用戶和組 pid /path/to/pid_file; #指定nginx守護進程的pid文件 worker_rlimit_nofile number; #設置所有worker進程最大可以打開的文件數,默認為1024 worker_rlimit_core size; #指明所有worker進程所能夠使用的總體的最大核心文件大小,保持默認即可
優化性能的配置:
worker_processes n; #啟動n個worker進程,這里的n為了避免上下文切換,通常設置為cpu總核心數-1或等于總核心數 worker_cpu_affinity cpumask ...; #將進程綁定到某cpu中,避免頻繁刷新緩存 # cpumask:使用8位二進制表示cpu核心,如: # 0000 0001:第一顆cpu核心 # 0000 0010:第二顆cpu核心 # 0000 0100:第三顆cpu核心 # 0000 1000:第四顆cpu核心 timer_resolution interval; #計時器解析度。降低此值,可減少gettimeofday()系統調用的次數 worker_priority number; #指明worker進程的nice值
事件相關的配置:event{}段中的配置
accept_mutex {off|on}; #master調度用戶請求至各worker進程時使用的負載均衡鎖;on表示能讓多個worker輪流地、序列化地去響應新請求 lock_file file; #accept_mutex用到的互斥鎖鎖文件路徑 use [epoll | rtsig | select | poll]; #指明使用的事件模型,建議讓Nginx自行選擇 worker_connections #; #每個進程能夠接受的最大連接數
網絡連接相關的配置:
keepalive_timeout number; #長連接的超時時長,默認為75s keepalive_requests number; #在一個長連接上所能夠允許請求的最大資源數 keepalive_disable [msie6|safari|none]; #為指定類型的UserAgeng禁用長連接 tcp_nodelay on|off; #是否對長連接使用TCP_NODELAY選項,為了提升用戶體驗,通常設為on client_header_timeout number; #讀取http請求報文首部的超時時長 client_body_timeout number; #讀取http請求報文body部分的超時時長 send_timeout number; #發送響應報文的超時時長
fastcgi的相關配置:
LNMP:php要啟用fpm模型
配置示例:
location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000;定義反向代理 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }
常需要進行調整的參數:
worker_processes worker_connections worker_cpu_affinity worker_priority
nginx作為web服務器時使用的配置:
http{...}:配置http相關,由ngx_http_core_module模塊引入。Nginx的HTTP配置主要包括四個區塊,結構如下:
http {//協議級別 include mime.types; default_type application/octet-stream; keepalive_timeout 65; gzipon; upstream {//負載均衡配置 ... } server {//服務器級別,每個server類似于httpd中的一個<VirtualHost> listen80; server_name localhost; location / {//請求級別,類似于httpd中的<Location>,用于定義URL與本地文件系統的映射關系 root html; index index.html index.htm; } } }
配置指令:
server {}:定義一個虛擬主機,示例如下:
server { listen 80; server_name www.idfsoft.com; root "/vhosts/web"; }
listen:指定監聽的地址和端口
listen address[:port]; listen port;
server_name NAME [...]; 后面可跟多個主機,名稱可使用正則表達式或通配符
當有多個server時,匹配順序如下:
(1)先做精確匹配檢查
(2)左側通配符匹配檢查,如*.idfsoft.com
(3)右側通配符匹配檢查,如mail.*
(4)正則表達式匹配檢查,如~^.*\.idfsoft\.com$
(5)default_server
root path; 設置資源路徑映射,用于指明請求的URL所對應的資源所在的文件系統上的起始路徑
alias path; 用于location配置段,定義路徑別名
index file;默認主頁面
index index.php index.html;
error_page code [...] [=code] URI | @name 根據http響應狀態碼來指明特用的錯誤頁面,例如 error_page 404 /404_customed.html
[=code]:以指定的響應碼進行響應,而不是默認的原來的響應,默認表示以新資源的響應碼為其響應碼,例如 error_page 404 =200 /404_customed.html
log_format:定義日志格式
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; 注意:此處可用變量為nginx各模塊內建變量
location區段,通過指定模式來與客戶端請求的URI相匹配
功能:允許根據用戶請求的URI來匹配定義的各location,匹配到時,此請求將被相應的location配置塊中的配置所處理,例如做訪問控制等功能
語法:
location [ 修飾符 ] pattern {......}
修飾符:
=:精確匹配
~:正則表達式模式匹配,區分大小寫
~*:正則表達式模式匹配,不區分大小寫
^~:前綴匹配,類似于無修飾符的行為,也是以指定模塊開始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正則表達式
@:定義命名location區段,這些區段客戶端不能訪問,只可以由內部產生的請求來訪問,如try_files或error_page等
沒有修飾符表示必須以指定模式開始,如:
server { server_name www.idfsoft.com; location /abc { ...... } }
那么如下內容就可正確匹配:
http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22
http://www.idfsoft.com/abc/
=:表示必須與指定的模式精確匹配,如:
server { server_name www.idfsoft.com; location = /abc { ...... } }
那么如下內容就可正確匹配:
http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22
如下內容則無法匹配:
http://www.idfsoft.com/abc/
http://www.idfsoft.com/abc/abcde
~:表示指定的正則表達式要區分大小寫,如:
server { server_name www.idfsoft.com; location ~ ^/abc$ { ...... } }
那么如下內容就可正確匹配:
http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22
如下內容則無法匹配:
http://www.idfsoft.com/abc/
http://www.idfsoft.com/ABC
http://www.idfsoft.com/abcde
~*:表示指定的正則表達式不區分大小寫,如:
server { server_name www.idfsoft.com; location ~* ^/abc$ { ...... } }
那么如下內容就可正確匹配:
http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22
http://www.idfsoft.com/ABC
如下內容則無法匹配:
http://www.idfsoft.com/abc/
http://www.idfsoft.com/abcde
^~:類似于無修飾符的行為,也是以指定模式開始,不同的是,如果模式匹配,則停止搜索其他模式
查找順序和優先級:由高到底依次為
帶有“=”的精確匹配優先
正則表達式按照他們在配置文件中定義的順序
帶有“^~”修飾符的,開頭匹配
帶有“~”或“~*”修飾符的,如果正則表達式與URI匹配
沒有修飾符的精確匹配
優先級次序如下:
( location = 路徑 ) > ( location ^~ 路徑 ) > ( location ~ 正則 ) > ( location ~* 正則 ) > ( location 路徑 )
訪問控制:
allow:設定允許哪臺或哪些主機訪問,多個參數間用空格隔開
deny:設定禁止哪臺或哪些主機訪問,多個參數間用空格隔開
示例:
allow 192.168.1.1/32 172.16.0.0/16; deny all;
基于用戶認證:
auth_basic "歡迎信息"; auth_basic_user_file "/path/to/user_auth_file"
user_auth_file內容格式為:
username:password
這里的密碼為加密后的密碼串,建議用htpasswd來創建此文件:
htpasswd -c -m /path/to/.user_auth_file USERNAME
https服務:
生成私鑰,生成證書簽署請求并獲得證書,然后在nginx.conf中配置如下內容:
server { listen 443 ssl; server_name www.idfsoft.com; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/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:
location /status { stub_status {on | off}; allow 172.16.0.0/16; deny all; }
訪問狀態頁面的方式:
http://server_ip/status
狀態頁面信息詳解:
狀態頁面示例如下圖:
Active connections 2:當前所有處于打開狀態的連接數
accepts:總共處理了多少個連接
handled:成功創建多少握手
requests:總共處理了多少個請求
Reading:Nginx讀取到客戶端的Header信息數,表示正處于接收請求狀態的連接數
Writing:Nginx返回給客戶端的Header信息數,表示請求已經接收完成,正處于處理請求或發送響應的過程中的連接數
Waiting:開啟keep-alive的情況下,這個值等于active - (reading + writing),意思就是Nginx已處理完正在等候下一次請求指令的駐留連接
ReWrite:
語法:
rewrite regex replacement flag;
如:
rewrite ^/p_w_picpaths/(.*\.jpg)$ /imgs/$1 break;
$1用于引用(.*\.jpg)匹配到的內容
又如:
rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirect
如上例所示,replacement可以是某個路徑,也可以是某個URL
常見的flag:
last:基本上都用這個flag,表示當前的匹配結束,繼續下一個匹配,最多匹配10個到20個
一旦此rewrite規則重寫完成后,就不再被后面其它的rewrite規則進行處理
而是由UserAgent重新對重寫后的URL再一次發起請求,并從頭開始執行類似的過程
break:中止Rewrite,不再繼續匹配
一旦此rewrite規則重寫完成后,由UserAgent對新的URL重新發起請求,且不再會被當前location內的任何rewrite規則所檢查
redirect:以臨時重定向的HTTP狀態302返回新的URL
permanent:以永久重定向的HTTP狀態301返回新的URL
Rewrite模塊:用來執行URL重定向。這個機制有利于去掉惡意訪問的url,也有利于搜索引擎優化(SEO)
Nginx使用的語法源于Perl兼容正則表達式(PCRE)庫,基本語法如下:
^:必須以^后的實體開頭
$:必須以$前的實體結尾
.:匹配任意字符
[ ]:匹配指定字符集內的任意字符
[^ ]:匹配任何不包括在指定字符集內的任意字符串
|:匹配 | 之前或之后的實體
():分組,組成一組用于匹配的實體,通常會有 | 來協助
捕獲子表達式,可以捕獲放在()之間的任何文本,比如:
^(hello|sir)$字符串為“hi sir”捕獲的結果:$1=hi$2=sir
這些被捕獲的數據,在后面就可以當變量一樣使用了
if:
語法:
if (condition) {...}
應用環境:
server
location
常見的condition:
a) 變量名(變量值為空串,或者以“0”開始,則為false,其它的均為true)
b) 以變量為操作數構成的比較表達式(可使用=,!=類似的比較操作符進行測試)
c) 正則表達式的模式匹配操作
~:區分大小寫的模式匹配檢查
~*:不區分大小寫的模式匹配檢查
!~和!~*:對上面兩種測試取反
d) 測試指定路徑為文件的可能性(-f,!-f)
e) 測試指定路徑為目錄的可能性(-d,!-d)
f) 測試文件的存在性(-e,!-e)
g) 檢查文件是否有執行權限(-x,!-x)
基于瀏覽器實現分離案例:
if ($http_user_agent ~ Firefox) { rewrite ^(.*)$ /firefox/$1 break; } if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } if ($http_user_agent ~ Chrome) { rewrite ^(.*)$ /chrome/$1 break; }
防盜鏈:
location ~* \.(jpg|gif|jpeg|png)$ { valid_referer none clocked www.idfsoft.com; if ($invalid_referer) { rewrite ^/ http://www.idfsoft.com/403.html; } }
14.5.4 nginx反向代理
Nginx通常被用作后端服務器的反向代理,這樣就可以很方便的實現動靜分離以及負載均衡,從而大大提高服務器的處理能力。
Nginx實現動靜分離,其實就是在反向代理的時候,如果是靜態資源,就直接從Nginx發布的路徑去讀取,而不需要從后臺服務器獲取了。
但是要注意,這種情況下需要保證后端跟前端的程序保持一致,可以使用Rsync做服務端自動同步或者使用NFS、MFS分布式共享存儲。
Http Proxy模塊,功能很多,最常用的是proxy_pass和proxy_cache
如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模塊,用來清除指定的URL緩存。這個集成需要在安裝nginx的時候去做,如:
./configure --add-module=../ngx_cache_purge-1.0 ......
14.5.5 nginx負載均衡
Nginx通過upstream模塊來實現簡單的負載均衡,upstream需要定義在http段內
在upstream段內,定義一個服務器列表,默認的方式是輪詢,如果要確定同一個訪問者發出的請求總是由同一個后端服務器來處理,可以設置ip_hash,如:
upstream idfsoft.com { ip_hash; server 127.0.0.1:9080 weight=5; server 127.0.0.1:8080 weight=5; server 127.0.0.1:1111; }
注意:這個方法本質還是輪詢,而且由于客戶端的ip可能是不斷變化的,比如動態ip,代理,×××等,因此ip_hash并不能完全保證同一個客戶端總是由同一個服務器來處理。
定義好upstream后,需要在server段內添加如下內容:
server { location / { proxy_pass http://idfsoft.com; } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。