Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。由俄羅斯的程序設計師Igor Sysoev所開發,供俄國大型的入口網站及搜索引擎Rambler(俄文:Рамблер)使用。其特點是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:京東、新浪、網易、騰訊、淘寶等。
一、event模型
傳統的基於進程和線程的模型在處理併發連接的時候針對每個連接會調用一個獨立的進程或線程,並且阻塞在網絡或I/O操作上面。根據應用程序的不同,它們對內存和CPU的使用效率非常低。產生一個新的進程或線程需要一個新的運行時環境,包括堆和棧的分配,以及運行時的上下文。因此需要額外的CPU開銷來創建這些環境,過多的線程以及上下文切換最終會導致性能的下降。所有這些狀況在Apache上都可以見到。因此,這是一個在提供豐富普遍適用的功能特性以及服務器資源優化之間的權衡。
event模型處理時內部不啓動線程爲每個連接創建獨立的處理邏輯,而是內部一個完整的處理邏輯來處理所有或大多數發給它的請求,進程內部基於事件等機制完成請求的處理。好處就是,不用單獨找一個獨立的處理邏輯,當一個請求如果處理時間需要等待的話比如IO時,僅僅把這個請求在內存空間地方把狀態記下來就行了,一旦完成了,通知進程,進程繼續暫存的任務就可以了。
二、Nginx軟件架構
Nginx的架構如下所示:
Nginx分爲Master/Worker兩級結構,Master進程負責加載配置文件,創建,綁定並關閉套接字啓動子進程,開始、終止保持配置中的worker進程數目;在線升級更新配置,日誌文件更替;Worker進程負責處理客戶端的請求,提供核心功能,反代,負載均衡等絕大多數功能;緩存加載進程負責檢測磁盤上的緩存項並填充Nginx內存數據庫。本質上緩存加載進程替Nginx提供一個存儲在磁盤上的目錄結構中的文件實例。需要使用時,它遍歷目錄,檢查緩存元數據,更新共享內存中的相關條目,準備好一切。退出是一切全部清理。
緩存管理器主要負載緩存過期和失效,Nginx操作的時候駐留在內存中,失敗了由Master啓動。
Nginx 架構中分爲核心模塊和第三方模塊,核心模塊負責維持運行環和在每個請求處理階段執行執行適當模塊代碼,第三方模塊提供如負載均衡,地址重寫的功能,應用功能。Nginx的模塊架構允許開發者在無需要改動Nginx核心的情況下擴展web服務器的特性。
Nginx使用量了event模型和異步IO機制,多請求進程處理和對於專門硬件的加速IO過程,加速了相應處理過程,能夠輕鬆處理數以萬計的請求。
三、nginx安裝
Nginx位於epel源中,也可以使用官方的YUM 源安裝它,目前還有很多它的二次開發版,比較有名的有tengine, OpenResty。
編譯安裝時,可以依據以下選項:
yum -y groupinstall "Development Tools" "Server Platform Development"
yum -y install openssl-devel zlib-devel pcre-devel
tar xf nginx.tar.gz
./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-debug
useradd -r nginx
export PATH=/usr/local/nginx/sbin/:$PATH
nginx -t # 測試nginx 配置,
nginx # 啓動nginx
nginx -s stop|reload
cp /root/nginx-1.8.1/man/nginx.8 /usr/share/man/man8 #
這樣日常使用基本就可以了。
主配置文件:/etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf
配置文件結構:
main block:設置全局配置,對其他部分完全有效;
event:事件驅動配置,存在於main block上下文;
http:http協議配置段;
mail:mail協議配置段;
配置命令規範;
directive value1 [value2 ...];
一個簡化的配置:
...
# main block
event{
...
}# 事件配置段
http {
... ;http公用配置
server {
...
server_name
root
alias
location /uri/ {
}
...
}
server {
...
}
}
四、詳細配置
全局參數
1.worker_rlimit_nofile #;
指定worker進程能都打開的最大文件描述符數量,影響單個worker進程所能處理的請求數;修改方法見後面的博文
2.worker_processes #;
指定worker進程的個數,應該根據CPU的核心數確定:每個CPU一個worker,爲了阻止了線程競爭和鎖死應該綁定worker進程到指定CPU上
3.worker_cpu_affinity CPUMASK CPUMASK
綁定worker進程到CPU核心,CPUMASK可以爲二進制掩碼,
示例:
[root@centos6_143 ~]# lscpu
...
CPU(s): 2
On-line CPU(s) list: 0,1
這裏設置woker進程數爲2,綁定兩個worker到兩個CPU上,可以用如下方式:
worker_processes 2;
worker_cpu_affinity 10 01
此時查看進程可以看到:
# ps axo user,comm,pid,psr|grep nginx
root nginx 1607 1
nginx nginx 1867 1
nginx nginx 1868 0
4.worker_priority NICE; 調整進程的nice值;
NICE=[-20,19], 用戶空間有限級範圍100-139,默認20,可以通過該參宿調整worker進程的優先級;
worker_prority 20
# ps axo user,comm,pid,psr|grep nginx
root nginx 1607 1
nginx nginx 1867 1
nginx nginx 1868 0
event 事件參數
5.woker_connections #;
指定單個worker進程所能夠相應的最大併發請求數;實際影響了進程的併發量,必須調整。默認1024。
6.accept_mutex [on|off] ;
設置worker進程之間的負載均衡鎖;表示用於讓多個worker輪流地、序列化地響應新請求;應該打開。
7.lock_file PATH
指定互斥鎖的位置。
http 配置
8.server{}
定義新的server上下文,定義於http上下文中,其上下文結構如下:
server {
listen PORT;
server_name NAME;
root /PATH/TO/DOCUMENTROOT;
}
多個server可以根據端口,域名,或IP的虛擬主機:
9.listen
listen address[:port] [default_server] [ssl] [backlog=number][rcvbuf=size][sndbuf=size];
listen port [default_server] [ssl] [ssl];
listen unix:path [default_server] [ssl] [ssl];
server參數:
default_server:設置該虛擬主機爲默認虛擬主機,默認虛擬主機主要用於基於IP或匹配不到的虛擬主機名訪問時,default_server負責響應。
backlog:後援隊列長度,等待響應的隊列長度。
10.server_name NAME ...;
設定web服務器主機名;名稱支持通配符和“~”起始的正則表達式;多個匹配的優先級;
(1) 首先做精確匹配;例如:www.magedu.com
(2) 左側通配符;例如:*.magedu.com
(3) 右側通配符,例如:www.magedu.*
(4) 正則表達式,例如:~^.*\.magedu\.com$
(5) default_server
worker_processes 2;
worker_cpu_affinity 0010 0001;
worker_priority 19;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 172.18.29.142:80;
server_name www.magedu.com;
root /data/webs/v1;
location / {
index index.html;
}
}
server {
listen 172.18.29.142:80;
server_name *.magedu.com;
root /data/webs/v2;
location / {
index index.html;
}
}
server {
listen 172.18.29.142:80;
server_name www.magedu.*;
root /data/webs/v3;
location / {
index index.html;
}
}
server {
listen 172.18.29.142:80;
server_name ~^.*w.magedu.*;
root /data/webs/v4;
location / {
index index.html;
}
}
server {
listen 172.18.29.142:80 default_server ;
server_name bbs.magedu.com;
root /data/webs/v5;
location / {
index index.html;
}
}
}
創建root網頁資源映射位置:
mkdir /data/webs/v{1..4}
# for i in {1..4};do echo "index.html @ server$i" > /data/webs/v$i/index.html ;done ;
修改域名解析:
172.18.29.142 www.magedu.com
172.18.29.142 www.godean.com
此時一次注掉虛擬主機server 1-3,訪問http://www.magedu.com/index.html,可以看到各個虛擬主機依次被匹配到;當訪問http://www.godean.conf/index.html或用http://172.18.29.142/index.html可以看到"index.html@server5",因爲該虛擬主機爲默認虛擬主機。
11.sendfile on|off;
在內核中直接將報文封裝發送給用戶,是Nginx的重要特性,這裏要開啓。
12.tcp_nodelay on|off;
對keepalive模式下的連接是否使用TCP_NODELAY選項;啓用該選項時,在keepalive連接中會將小段數據攢到一塊在發送,可能會造成小請求的延遲,視情況而定。
路徑相關命令
13.root PATH;
可應用於http,server,location上下文中,指定映射到文件系統資源路徑;多次指定以最近一次指定爲準。
14.location
可用於上下文:server/localtion
允許根據用戶請求的URI來匹配定義的各location,匹配到時,此請求將被相應的location塊中的配置所處理(如爲.txt結尾文件做壓縮);簡言之,即用於爲需要用到專用配置的uri提供特定配置;
server {
listen 172.18.29.142:80;
server_name www.magedu.com;
root /data/webs/v1;
index index.html;
location / {
index index.html;
}
location /admin {
root /data/webs/v1;
gzip on;
}
}
建立對應的資源,就可看到如下圖的gzip壓縮的顯示:
15.alias
用於上下文:localtion,只能用於location配置段,定義路徑別名;可以和root比較:
對於兩個相似配置:
location /bbs/ {
root /web/;
}
location /bbs/ {
alias /web/;
}
前者的真實資源文件位置爲:/web/bbs/,後者的真實資源文件位置爲:/web/
root指令:給定的路徑右側“/”對應於locationURL右側斜線;
/p_w_picpaths/test.jpg --> /data/imgs/p_w_picpaths/test.jpg
alias指令:給定的路徑右側“/”對應於locationURL左側斜線;
/p_w_picpaths/test.jpg --> /data/imgs/test.jpg
16.error_page
可用上下文:http,server,location,指定error page 的位置;
error_page 404 /404.html; # 可以定義
... ....
location =/404.html{
root /use/share/nginx/html;
}
17.open_file_cache 對打開的文件緩存
open_file_cache off;
open_file_cache max=N [inactive=time];
nginx可以緩存以下三種信息:都是元數據
(1) 文件描述符、文件大小和最近一次的修改時間;
(2) 打開的目錄的結構;
(3) 沒有找到的或者沒有權限操作的文件的相關信息;
max=N表示可緩存的最大條目上限;一旦達到上限,則會使用LRU算法從緩存中刪除最近最少使用的緩存項
inactive=time:在此處指定的時長內沒有被訪問過的緩存項是爲非活動緩存項,因此直接刪除;
18.open_file_cache_errors on | off;
是否緩存找不到其路徑的文件,或沒有權限訪問的文件相關信息;
19.open_file_cache_valid
open_file_cache_valid time;
每隔多久檢查一次緩存中緩存項的有效性;默認爲60s;
20.open_file_cache_min_uses
open_file_cache_min_uses number;
在open_file_cache指令inactive參數指定時長內至少命中指定次數,方可歸類爲非活動項目。
21.allow address
ngx_http_access_module模塊的配置(基於IP的訪問控制)
實現客戶端IP的訪問控制
allow address | CIDR | unix: | all;
addrss;IPv4地址
CIDR: 172.18.0.0/16
all:表示所有地址
22、deny address
應用上下文:http, server, location, limit_except
deny address | CIDR | unix: |
23.stub_status
通過指定的uri輸出nginx的基本信息(stub status);
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
Active connections:當前活動的客戶端連接數;
accepts:已經接受的客戶端連接總數量;
handled:已經處理過後客戶端連接總數量;
requests:客戶端的總的請求數量;
Reading:正在讀取的客戶端請求的數量;
Writing:正向其發送響應報文的連接數量;
Waiting:等待其發出請求的空閒連接數量;
location /status {
stub_status on;
}
# curl http://172.18.29.142/status
Active connections: 1
server accepts handled requests
73 73 146
Reading: 0 Writing: 1 Waiting: 0
24.valid_referers
可應用於上下文:server、location,指定合法的引用,合法引用就是跳轉之前的頁面,該設定可以用來防盜鏈。
valid_referers none | blocked | server_names | string ...;
none:請求報文不存在referer首部;
blocked:請求報文中存在referer首部,但其沒有有效值,或其值非以http://或https://開頭;
server_names:其值爲一個主機名;
arbitrary string:直接字符串,可以使用*通配符的字符串;
regular expression:以~起始的正則表達式匹配的字符串;
內置變量:$invalid_referer(所有不能符合valid_referer指定定義的引用請求均爲不合法引用)
示例:這隻除了blocked example.* www.example.org/galleries/ ~\.google\. 以外都是非法引用,不允許其訪問。
valid_referers blocked example.* www.example.org/galleries/ ~\.google\.;
if ($invalid_referer) {
return 403;
}
location / {
root /data/webs/vhost1;
index index.html;
valid_referers blocked server_names *.example.com;
if ($invalid_referer){
return 403;
}
}
# curl http://172.18.29.142/
<html>
<head><title>403 Forbidden</title><head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.0.15</center>
</body>
</html>
報文的引用者引用變量 $invalid_referer,此時的請求是referer爲none,那麼返回403。
ngx_http_ssl_module 模塊配置
25.ssl [on|off];
應用上下文:http, server
是否啓用當前虛擬主機的ssl功能;
26.ssl_certificate file;
應用上下文:http, server
當前虛擬主機使用的PEM格式的證書文件;
ssl_certificate_key file;
應用上下文:http, server
當前虛擬主機使用的PEM格式的私鑰文件;
# 自建CA
cd /etc/pki/CA
openssl genrsa -out private/ca.pem 2048
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/certs/cacert.pem -days 365
touch {serial,index.txt}
echo 01 > serial
# 生成認證請求
mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
openssl genrsa -out ./nginx.priv 2048
openssl req -new -key nginx.privat -out /opt/nginx.csr -days 365
# CA簽署證書,併發放證書
openssl ca -in /opt/nginx.csr -out certs/nginx.crt -days 365
# 配置nginx.cinf文件,建立https虛擬主機
server {
listen 172.18.29.142:443 ssl ;
server_name www.magedu.com;
root /data/webs/v2;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.priv;
location / {
}
}
The ngx_http_log_module 模塊將請求日誌按照格式寫入日誌中
27.access_log path [format [buffer=size [flush=time]] [if=condition]];
access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
access_log syslog:server=address[,parameter=value] [format [if=condition]];
access_log off;
設定對http,server,location設置各自的日誌位置,如果需要緩存(buffer)那麼需要設定刷新到文件的時間。
默認日誌格式:access_log logs/access.log combined;
可應用於上下文:http, server, location, if in location, limit_except
access_log /var/log/nginx/access.log combined buffer=5m flush=1h ;
28.log_format name string ...;
log_format name string ...;
默認值:log_format combined "...";
可應用於上下文:http
29.open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
默認:open_log_file_cache off;
可應用於上下文:http, server, location
max:最大緩存條目;
inactive=time:非活動時長;
min_uses:最少使用次數;
valid:驗正緩存條目有效性的頻率;
open_log_file_cache max=10 inactive=20s min_uses=1 valid=1m;
說明:max爲緩存最大條目數,如果達到max數值,那麼從中根據LRU算法踢出;inactive爲緩存條目多長時間沒有達到min_uses的值,那麼就踢出;min_uses緩存最少訪問次數;valid爲文件緩存後查詢文件的有效性間隔時長。
ngx_http_rewrite_module模塊配置
用戶訪問通過服務器名稱,指定到某個servername,再根據localtion定位映射文件位置,設定location的屬性,其中配置rewrite指令。
30.rewrite regex replacement [flag];
可用於上下文:server, location, if
1.把用戶請求的URI基於regex做檢查,匹配到時將替換爲replacement指定的字符串;
2.在同一個location中存在的多個rewrite規則會自上而下逐個被檢查(內生的循環機制);可以使用flag控制此循環功能,循環最多10次,否則返回500服務器端錯誤;
3.如果replacement是以http://或https://開頭,則替換結果會直接以重定向方式返回給客戶端;
http --> https, domain1.tld --> domain2.tld, uri1 --> uri2, ...
regex:正則表達式,用於匹配用戶請求的url;
replacement:重寫爲的結果;
[flag]:
last:重寫完成後停止對當前uri在當前location中的後續其它重寫操作,改爲對新uri的新一輪處理;
break:重寫完成後停止對當前uri在當前location中的後續其它重寫操作;
redirect:重寫完成後以臨時重定向方式直接返回重寫後生成的新URL給客戶端,由客戶對新URL進行請求;(302)
permanent:重寫完成後以永久重定向方式直接返回重寫後生成的新URL給客戶端,由客戶對新URL進行請求;(301)
關於flag的示例:
訪問:http://www.magedu.com/index.txt
存在文件:
# cat /data/webs/vhost1/index.html
index.html
# cat /data/webs/vhost1/admin/index.html
admin index.html
# cat /data/webs/vhost1/admin/index.txt
admin index.txt
location / {
root /data/webs/vhost1;
index index.html;
rewrite /(.*)\.txt /admin/$1.txt break;
rewrite /admin/(.*)\.txt /admin/$1.html;
}
location /admin {
root /data/webs/vhost1;
rewrite /admin/(.*)\.txt /$1.html;
}
如果break所在位置替換爲空,那麼請求響應爲:admin index.html;如果break所在位置替換爲last,那麼請求響應爲:index.html;如果break所在位置替換爲break,那麼請求響應爲:admin index.txt;
ngx_http_gzip_module模塊配置
過濾器,對指定類型的資源壓縮傳輸以節約帶寬,但是可能增加CPU負載;
zip on | off;
啓用或禁用gzip壓縮響應報文;
gzip_comp_level level;
壓縮比,1-9,默認爲1;
gzip_disable regex ...;
regex是匹配客戶端瀏覽器類型的模式,表示對所有匹配到的瀏覽器不執行壓縮響應;
gzip_min_length length;
觸發壓縮功能的響應報文的最小長度;
gzip_http_version 1.0 | 1.1;
設定啓用壓縮功能時,協議的最小版本;
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
定義對客戶端請求的具有何種請求屬性的資源啓用壓縮功能;如expired則表示對由於使用了expired首部而無法緩存的對象啓用壓縮功能;
gzip_types mime-type ...;
指明僅對哪些類型的資源執行壓縮操作;即壓縮過濾器;
示例:
gzip on;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_disable msie6;
gzip_min_length 2;
gzip_types text/plain text/css text/xml application/x-javascript application/xml application/json application/java-script;
基礎配置就到這裏,下篇博文介紹Nginx的反向代理。如有不到的地方,請各位指教。