nginx

nginx(web server,web reverse proxy)

http事務:request <----> response
request:
<method> <URL> <version>
<HEADERS>
...
<body>

response:
<version> <status> <reason phrase>
<HEADERS>
...
<body>

web資源:URL (scheme://server:port/path/to/source)

方法:GET, HEAD, POST, (WEBDAV) PUT, DELETE, TRACE, OPTIONS

status:
1xx: 信息類
2xx: 成功類,200
3xx: 重定向,301, 302, 304
4xx: 客戶端類錯誤,403, 401, 404
5xx: 服務端類錯誤,502

I/O類型:
同步和異步:synchronous, asyncrhonous
關注的是消息通知機制

同步:調用發出不會立即返回,但一旦返回就可以返回最終結果;
異步:調用發出之後,被調用方立即返回消息,但返回的非最終結果;被調用者通過狀態、通知機制來通知調用者,或通過回調函數來處理結果;

阻塞和非阻塞:block, nonblock
關注的是調用者等待調用結果(消息、返回值)時的狀態

阻塞:調用結果返回之前,調用者(調用線程)會被掛起;調用者只有在得到結果之後纔會返回;
非阻塞:調用結果返回之前,調用不會阻塞當前線程;

5種I/O模型:
同步阻塞   blocking IO
同步非阻塞    nonblocking IO
IO複用    IO multiplexing            select(),poll()
信號驅動IO   signal driven IO    通知:1、水平觸發:多次通知;2、邊緣觸發:只通知一次;
異步IO     asyncrhonous IO

nginx:讀音engine x
二次研發:tengine、registry

libevent:高性能的網絡庫
1、epool()

Nginx的特性:
模塊化設計、較好擴展性;
高可靠性:master/worker
支持熱部署:不停機更新配置文件、更換日誌、更新服務器程序版本;
低內存消耗 :10000個keep-alive連接模式下的非活動連接僅消耗2.5M內存;
事件驅動機制(mmap), 異步IO(aio), 內存映射機制(mmap);

基本功能:
靜態資源的web服務器,能緩存打開的文件描述符;
http、smtp、pop3、imap4等協議的反向代理服務器;
緩存加速、負載均衡;
支持FastCGI(php-fpm), uWSGI(Python Web Framwork)等協議
模塊化(非DSO機制),過濾器zip、SSI及圖像的大小調整;
支持SSL;

擴展功能:
基於名稱和IP的虛擬主機;
支持keepalive
支持平滑升級
定製訪問日誌,支持使用日誌緩存區提供日誌存儲性能;
支持url rewrite;
支持路徑別名;
支持基於IP及用戶的訪問控制;
支持速率限制,支持併發數限制;

Nginx的程序架構:
master/worker
一個master進程,可生成一個或多個worker進程;
事件驅動模型:epoll(Linux默認邊緣觸發), kqueue(FreeBSD), /dev/poll(Solaris)
消息通知(複用器):select, poll, rt signals
支持sendfile,  sendfile64
支持AIO,mmap

master: 加載配置文件、管理worker進程、平滑升級,...
worker:http服務,http代理,fastcgi代理,...

模塊類型:
1、核心模塊:core module
2、標準模塊:
a、標準http模塊:Standard HTTP modules
b、可選http模塊:Optional HTTP modules
c、郵件相關模塊:Mail modules
3、第三方模塊:3rd party modules

安裝方法:
1、源碼:編譯安裝

yum groupinstall "development tools" "server plantform development"

yum -y install pcre-devel openssl-devel zlib-devel

wget http://101.110.118.22/nginx.org/download/nginx-1.14.0.tar.gz

tar xvf nginx-1.14.0.tar.gz -C /usr/local/

cd /usr/local/nginx-1.14.0/

./configure --help | less

useradd -r nginx

./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

make && make install

2、製作好的程序包:rpm包

配置文件組織結構
main block:全局配置;對http及mail模塊均有效;
events {}:定義event模型(事件驅動)的相關配置;對http及mail模塊均有效
http {}:http協議的相關配置;
mail {}:mail協議的相關配置;

 配置指令:要以分號結尾,語法格式:directive    value1 [value2...]
支持使用變量:1、內置變量:模塊會提供內建變量;2、自定義變量:set var_name value;

main配置段:
類別:
正常運行必備的配置;
優化性能相關的配置;
用於調試、定位問題的配置;

正常運行必備的配置:
1、user USERNAME  [GROUPNAME];
指定用於運行worker進程的用戶和組;
user  nginx  nginx;

2、pid  /PATH/TO/PID_FILE;
指定nginx進程的pid文件路徑;
 pid  /var/run/nginx.pid;

3、worker_rlimit_nofile #;
指定單個worker進程所能夠打開的最大文件描述符數量;

性能優化相關的配置:
1、worker_processes #;
worker進程的個數;通常應該爲物理CPU核心數量減1;
可以爲"auto",實現自動設定;

2、worker_cpu_affinity  CPUMASK(cpu掩碼) CPUMASK ...;
  worker_cpu_affinity auto [CPUMASK]
   實現nginx綁定cpu;
優點:提升緩存的命中率;
CPUMASK:多少顆cpu就用多少個二進制來表示;如下例如4顆cpu;
0001
0010
0100
1000

worker_cpu_affinity 00000001 00000010 00000100;

3、worker_priority  nice;
定義worker進程的優先級;
[-20, 19],默認nice值爲0
100-139,默認優先級爲120

4、timer_resolution interval;
計時器解析度,降低此值,可減少gettimeofday()系統調用的次數;

調試、定位問題的配置:
1、daemon  off|on;
是否以守護進程方式啓動nignx;默認爲on;調試時應該設置爲off;

2、master_process  on|off;
是否以master/worker模型運行nginx;默認是on;調試時應該設置爲off;

3、error_log     /PATH/TO/ERROR_LOG     level;
錯誤日誌文件的記錄方式,及其級別;出於調試的需要,可以設爲debug;但debug僅在編譯時使用了“--with-debug”選項時纔有效;
方式:
file /PATH/TO/SOME_LOG_FILE;
stderr:發送到錯誤輸出;
syslog:server=address[,parameter=value]:發送給syslog服務器;
memory:size

日誌級別:
debug:依賴於configure時的--with-debug選項;
info、notice、warn、error、crit、alert、emerg

事件驅動相關的配置:
1、accept_mutex on | off;
master調度用戶請求至各worker進程時使用的負載均衡鎖;on表示能讓多個worker輪流地、序列化的響應新請求;

2、lock_file file;
accept_mutex用到的鎖文件路徑;

3、use method;
指明併發連接請求處理時使用的方法;即指明使用的事件模型;建議讓nginx自行選擇;
use epool;linux只有epool可選

 4、worker_connections number;
每個worker進程所能夠響應的最大併發請求數量;

總結:常需要進行調整的參數:
worker_processes,worker_connetctions,worker_cpu_affinity,worker_priority

新改動配置生效的方式:nginx -s reload | stop | quit | reopen

nginx作爲web服務器時使用的配置:
定義套接字相關功能
1、server {}:定義一個虛擬主機;
server {
listen PORT;
server_name HOSTNAME;
root /PATH/TO/DOCUMENTROOT;
}
...

注意:
(1) 基於port的虛擬主機;
listen指令監聽在不同的端口;
(2) 基於hostname的虛擬主機;
server_name指令指向不同的主機名;
(3)基於ip的虛擬主機:
   listen IP:PORT;

2、listen
listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
listen port [default_server] [ssl] [http2 | spdy]
listen unix:path [default_server] [ssl] [http2 | spdy]

default_server:設置默認虛擬主機;用於基於IP地址,或使用了任意不能對應於任何一個server的name時所返回站點;
ssl:用於限制只能通過ssl連接提供服務;
backlog:後援隊列的長度;
rcvbuf:接收緩衝區大小;
sndbuf:發送緩衝區大小;
spdy:SPDY protocol(speedy),在編譯了spdy模塊的情況下,用於支持SPDY協議;
http2:http version 2;

3、server_name NAME [...];
指明當前server的主機名;後可跟一個或多個用空白字符分隔的主機;
支持使用*任意長度的任意字符;
支持~起始的正則表達式模式字符串;

優先級:
(1) 首先做精確匹配;例如:www.magedu.com
(2) 左側通配符;例如:.magedu.com
(3) 右側通配符,例如:www.magedu.

(4) 正則表達式,例如:~^.*.magedu.com$
(5) default_server

4、root path;

設置web資源的路徑映射;用於指明請求的URL所對應的文檔的目錄路徑;
可用上下文:http,server,location,if

5、location [ = | ^~ | ~ | ~*  ] uri { ... };
   location @name { ... }
功能:允許根據用戶請求的URI來匹配定義的各location;匹配到時,此請求將被相應的location塊中的配置所處理,例如做訪問控制等功能;

=:URI的精確匹配;
^~:URI的前半部分匹配,不支持正則表達式;
~:做正則表達式匹配,區分字符大小寫;
~*:做正則表達式匹配,不區分字符大小寫;

匹配優先級:精確匹配=、^~、~或~*、不帶符號的URL;

6、alias path;
只能用於location配置段,定義路徑別名;
location  /images/ {
root /data/imgs/;
}
http://www.magedu.com/images/a.jpg      <---    /data/imgs/images/a.jpg

location  /images/  {
alias /data/imgs/;
}
http://www.magedu.com/images/a.jpg      <---    /data/imgs/a.jpg

注意:root表示指明路徑爲對應的location "/" URL;alias表示路徑映射,即location指令後定義的URL是相對於alias所指明的路徑而言;

7、index  file;
默認主頁面;
例如:   index    index.php    index.html;

8、error_page    code   [...]    [=code]   URI   |   @name;

根據http的響應狀態碼來指明特用的錯誤頁面;
error_page   404   /404_customed.html

 [=code]:以指定的響應碼進行響應,而不是默認的原來的響應碼;默認表示以新資源的響應碼爲其響應碼;
error_page  404  =200  /404.html

9、基於IP的訪問控制
allow    IP |  NETWORK | unix: | all;
deny    IP  | NETWORK | unix: | all;
可用上下文:http, server, location, limit_except

10、基於用戶的訪問控制(basic,digest)

auth_basic   "";
auth_basic_user_file   "/PATH/TO/PASSWD_FILE";
賬號密碼建議使用htpasswd來創建
htpasswd命令;

htpasswd -c -m  /etc/nginx/.ngxhtpasswd tom

htpasswd -m  /etc/nginx/.ngxhtpasswd jerry

11、https服務
前提:生成私鑰,生成證書籤署請求,並獲得證書;

server {
listen 443 ssl;
server_name www.magedu.com;

ssl_certificate      cert.pem;          指明證書文件位置
ssl_certificate_key      cert.key;    指明私鑰文件位置

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {
root    /vhosts/web1;
index    index.html index.htm;
}
}

12、stub_status {on|off};
通過指定的uri輸出stub status;僅能用於location上下文;

location  /status    {
stub_status on;
allow    172.20.120.0/23
deny   all;
}

結果示例:
Active connections: 5
server               accepts               handled             requests
                             234                       234                    462
Reading: 1               Writing: 5                Waiting: 12

Active connections:當前所有處於打開狀態的連接數;
accepts:已經接受過的連接數;
handled:已經處理過的連接數;
requests:已經處理過的請求數;在“保持連接”模式下,請求數量可能會多於連接數量;
Readking:正處於接收請求狀態的連接數;
Writing:請求已經接收完成,正處於處理請求或發送響應的過程中的連接數;
Waiting:保持連接模式,且處於活動狀態的連接數;

13、rewrite     regex      replacement     [flag];
把用戶請求的URI基於regex做檢查,匹配到時將替換爲replacement指定的字符串;
在同一個location中存在的多個rewrite規則會自上而下逐個被檢查(循環);可以使用flag控制此循環功能;
regex:正則表達式,用於匹配用戶請求的url;
replacement:重寫爲的結果;
[flag]:
last:一旦此rewrite規則重寫完成後,就不再被後面其他的rewrite規則進行處理;而是由user agent重新對重寫後的URL再一次發起請求,並從頭開始執行類似的過程;
break:一旦此rewrite規則重寫完成後,由user agent對新的URL重新發起請求,且不再會被當前location內的任何rewrite規則所檢查;
redirect:以302響應碼(臨時重定向)返回新的URL;
permanent:以301響應碼(永久重定向)返回新的URL;
 例如:
rewrite    ^/images/(.*.jpg)$     /imgs/$1    break;
http://www.magedu.com/images/a/1.jpg      --->    http://www.magedu.com/imgs/a/1.jpg

14、if
語法 if (condition)  {...}
應用環境:server,location
condition:
(1)變量名:
變量值爲空串,或者以“0”開始,則爲fault,其他均爲true;
(2)以變量爲操作數構成的比較表達式
可使用=,!=類似的比較操作符進行測試;
(3)正則表達式的模式匹配操作;
~:區分大小寫的模式匹配檢查;
~:不區分大小寫的模式匹配檢查;
!~和!~
:對上面兩種測試取反;
(4)測試路徑爲文件的可能性:-f,!-f
(5)測試路徑爲目錄的可能性:-d,!-d
(6)測試文件的存在性:-e,!-e
(7)檢查文件是否有執行權限:-x,!-x
例如:
      if    ($http_user_agent ~ MSIE) {
             rewrite   ^(.
)$  /msie/$1 break;
 }

15、防盜鏈
location   ~*   .(jpg|gif|jpeg|png)$   {
          valid_referer   none  blocked   www.lewis.com;
          if     ($invalid_referer)   {
                            rewrite     ^/    http://www.lewis.com/403.html;
            }
}

16、定製訪問日誌
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各模塊內建變量;

網絡連接相關配置:

1、keepalive_timeout  #;          長連接的超時時長,默認爲75s;

2、keepalive_requests  #;   在一個長連接上所能夠允許請求的最大資源數;

3、keepalive_disable [msie|safari|none];    爲指定類型的user agent禁用長連接;

4、tcp_nodelay   on|offf;     是否對長連接使用TCP_NODELAY選項;

5、client_header_timeout  #;    讀取http請求報文首部的超時時長;

6、client_body_timeout   #;      讀取http請求報文body部分的超時時長;

7、send_timeout   #;      發送響應報文的超時時長;

LNMP:php啓用fpm模型;

例如:

location / {

root           /vhosts/web1;
index           index.php     index.html         index.htm;
}

location ~ .php$ {
root              /vhosts/web1;
fastcgi_pass              127.0.0.1:9000;
fastcgi_index        index.php;
fastcgi_param           SCRIPT_FILENAME         /vhosts/web1/$fastcgi_script_name;
include                fastcgi_params;
}

nginx反向代理:proxy、fastcgi、upstream

ngx_http_proxy_module:實現反向代理及緩存功能;

(1) proxy_pass URL;
應用上下文:location, if in location, limit_except

proxy_pass後面的路徑不帶uri時,其會將location的uri傳遞給後端的主機;下面的示例會將/uri/傳遞給backend服務器;
location  /uri/ {
proxy_pass http://hostname;
}

proxy_pass後面的路徑是一個uri時,其會將location的uri替換爲後端主機自己的uri;
location  /uri/ {
proxy_pass http://hostname/new_uri/;
}

如果location定義其uri時使用的正則表達式模式匹配,則proxy_pass後的路徑不能夠使用uri;
location  ~*  .(jpg|gif|jpeg)$  {
proxy_pass  http://HOSTNAME;
}
 此處的http://HOSTNAME後面不能有任何uri,哪怕只有/也不可以;

(2) proxy_set_header field value;
用於proxy server向backend server發請求報文時,將某請求首部重新賦值,或在原有值後面添加一個新的值; 也可以添加自定義首部;
 示例:
proxy_set_header  X-Real-IP  $remote_addr;
proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
原有請求報文中如果存在X-Forwared-For首部,則將remote_addr以逗號分隔補原有值後,否則則直接添加此首部;

實踐作業:
假如nginx有兩個server(虛擬主機),且均反代至後端某一個主機,此主機亦有兩個虛擬主機,虛擬主機名與nginx的相同;
要求:用戶請求nginx的哪一個虛擬主機,就將其代理後後端主機的對應的虛擬主機;

緩存相關的選項(緩存要先定義,後調用):
(3) proxy_cache_path    path    [levels=levels]   [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size]
定義緩存;可用上下文爲http;

(4) proxy_cache zone | off;
調用緩存;可用上下文 爲http, server和location;

(5) proxy_cache_key string;
定義緩存鍵;
proxy_cache_key $scheme$proxy_host$request_uri;

(6) proxy_cache_valid [code ...] time;
對不同響應碼的響應設定其可緩存時長;
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
處於什麼狀態下,以舊的緩存響應;

proxy_cache_bypass  string:設置在何種情況下nginx將不從cache取數據;
$cookie_nocache  $arg_nocache  $httpd_authorization

跟連接相關的選項
(7) proxy_connect_timeout time;
定義與後端服務器建立連接的超時時長;默認爲60s,不建議超出75s;

(8) proxy_send_timeout time;
把請求發送給後端服務器的超時時長;默認爲60s;

(9) proxy_read_timeout time;
等待後端服務器發送響應報文的超時時長;

ngx_http_upstream_module:定義服務器組
用於將多個服務器定義成服務器組,而由proxy_pass, fastcgi_pass等指令進行引用;

(1) upstream name { ... }
定義一個後端服務器組,name爲組名稱;僅能用於http上下文 ;

(2) server address [parameters];
在upstream中定義一個服務器及其相關參數;僅能用於upstream上下文;

常用參數:
weight=number:定義服務器權重,默認爲1;
max_fails=number:最大失敗連接嘗試次數,失敗連接超時時長由fail_timeout參數指定;
fail_timeout=number:等待目標服務器發送響應的時長;
backup:備用服務器,所有主服務器均故障時才啓用此主機;
down:手動標記其不再處理任何用戶請求;

使用方法:
(a) 定義upstream服務器組
upstream websrvs {
server 172.16.100.68 weight=2 max_fails=2 fail_timeout=6s;
server 172.16.100.6  weight=1 max_fails=2 fail_timeout=6s;
}

(b) 在反代場景中(proxy_pass, fastcgi_pass, ...)進行調用;
location / {
proxy_pass http://websrvs/;
}

(3) ip_hash;
源地址hash,把來自同一個ip地址的請求始終發往同一個backend server,除非此backend server不可用;

(4) least_conn;
最少連接;當各server權重不同時,即爲加權最少連接;

(5) health_check [parameters];
健康狀態檢測機制;只能用於location上下文;建議關閉訪問日誌;

常用參數:
interval=time檢測的頻率,默認爲5秒;
fails=number:判定服務器不可用的失敗檢測次數;默認爲1次;
passes=number:判定服務器可用的失敗檢測次數;默認爲1次;
uri=uri:做健康狀態檢測測試的目標uri;默認爲/;
match=NAME:健康狀態檢測的結果評估調用此處指定的match配置塊;

(6) match name { ... }
對backend server做健康狀態檢測時,定義其結果判斷機制;只能用於http上下文;

常用的參數:
status  code[  code ...]: 期望的響應狀態碼;
header  HEADER[operator  value]:期望存在響應首部,也可對期望的響應首部的值基於比較操作符和值進行比較;
body:期望響應報文的主體部分應該有的內容;

(7) hash key [consistent];
指明基於hash方式進行調度時,其hash key;
hash  $remote_addr相當於ip_hash;

常用的hash key:
$cookie_name:將一個用戶的請求始終發往同一個backend server,能實現會話綁定的功能;此處的name爲cookie某些參數的名稱,此處常用的有cookie_username;
$request_uri: 將對同一個uri的請求始終發往同一個backend server,後端爲cache server時特別有用;

session會話保持:
session sticky:基於ip, ngix還可基於請求報文首部中的多種信息,例如cookie, uri;
session cluster:每個server均把創建和維護session同步集羣中的其它主機;僅適用於較小規模的環境;
session server:使用一個共享的存儲服務存儲session信息;

ngx_http_headers_module模塊配置
 (1) add_header name value [always];
向響應報文添加自定義首部,併爲其賦值;
示例:
add_header realserver $server_addr;                     添加真實服務器地址的自定義首部
add_header cache_status $upstream_cache_status;                 添加nginx緩存狀態的自定義首部

(2) expires [modified] time;
     expires epoch | max | off;
允許或禁止向響應報文的Cache-Control或Expires首部添加新值或修改其值;

fastcgi模塊指令:
 (1) fastcgi_pass address;
address爲fastcgi server監聽的地址和端口;

示例:fastcgi_pass   127.0.0.1:9000;

(2) fastcgi_index name;
定義fastcgi應用的默認主頁;

示例:fastcgi_index  index.php;

(3) fastcgi_param parameter value [if_not_empty];
設定傳遞給後端fastcgi server參數及其值;

示例:fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

/index.php --> /scripts/index.php
http://www.magedu.com/users.php?username=tom

(4) fastcgi_cache_path path  [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size];
定義緩存:緩存空間等;

可應用的上下文 :http
緩存機制:
元數據:內存,即爲keys_zone;
數據:磁盤,即爲path;
path:文件系統路徑,用於儲存緩存的文件數據;

levels=#[:#[:#]]:緩存目錄層級定義;
levels=2:1

keys_zone=name:size
內存中用於緩存k/v映射關係的空間名稱及大小;
name: cache的標識符;
size:元數據cache大小;

max_size:緩存空間上限;

注意:只能用於http上下文;

(5) fastcgi_cache zone | off;
調用定義過的緩存;

zone即爲通過fastcgi_cache_path定義緩存時其keys_zone參數中的name;

(6) fastcgi_cache_key string;
定義如何使用緩存鍵;

使用示例:fastcgi_cache_key   $request_uri;

(7) fastcgi_cache_methods GET | HEAD | POST ...;
爲何請求方法對應的請求進行緩存,默認爲GET和HEAD;

(8) fastcgi_cache_min_uses number;
緩存項的最少使用次數;

(9) fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | off ...;
是否可使用stale緩存項響應用戶請求;

(10) fastcgi_cache_valid [code ...] time;
對不同響應碼的響應設定其可緩存時長;

示例:
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid 404      1m;

注意:調用緩存時,至少應該指定三個參數
fastcgi_cache
fastcgi_cache_key
fastcgi_cache_valid

LNMP:php啓用fpm模型;

php-fpm的工作方式:
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
pm = dynamic|static
pm.start_servers:啓動fpm進程時啓動的工作進程數量;
pm.min_spare_servers:最少空閒進程數;
pm.max_spare_servers:最大空閒進程數;
pm.max_children:最大工作進程數;
user = USERNAME
group = GROUPNAME

示例:location / {

root           /vhosts/web1;
index           index.php     index.html         index.htm;
}

location ~ .php$ {
root              /vhosts/web1;
fastcgi_pass              127.0.0.1:9000;
fastcgi_index        index.php;
fastcgi_param           SCRIPT_FILENAME         /vhosts/web1/$fastcgi_script_name;
include                fastcgi_params;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章