NginX
回顧http協議:
1.URL格式
URL:shceme://username:password@host:port/path;params?query#fram
2.http事務:
request:請求報文格式 reponse:響應報文格式
<method> <URL> <VERSION> <VERSION> <STATUS Code> <REASON-PHRASE>
HEADERS HEADERS
空行 空行
<body> <body>
Method:GET/HEAD/POST, PUT/DELETE, TRACES, OPTIONS
Status Code:
1xx:信息類狀態碼
2xx:成功類響應碼,常見:200–OK
3xx:重定向類的響應碼,301, 302, 304
4xx:客戶端錯誤,常見:403:forbidden—-客戶端沒權限;404:not found-客戶端請求的資源不存在)
5xx:服務器端錯誤,常見:502(bad gate–通常是反向代理服務器向后端服務器請求超時導致,nginx中常見)
3.認證:http協議提供,有basic、digest兩種認證算法
基于ip認證
基于用戶認證
4.跨主機進程間通信之串行響應模型
客戶端的某個進行請求服務端的服務器端的某個進行進行通信時,此時服務器端的進行有可能是被客戶端獨占的,如果此時再有其他客戶端進行請求服務端進行響應是,那么客戶端只能處于等待狀態,這就叫串行模型。
5.跨主機進程間通信之并發響應模型
為解決串行響應模型帶來的性能瓶頸提出的解決方法,并發響應模型中,服務器啟動一個主控進程,監聽在某服務相對應的套接字上,此主控進程用于fock自身生成子進程來相應客戶端請求,但為避免主控進程生成過多子進程從而占用存儲空間,主控進程只能fock自身生成有限的子進程來對客戶端的請求進行響應。但是如果等到客戶端發起請求在fock自身生成子進程的話速度上會有所減慢,所以就提出比較常用的三種進程模型:prefork、worker、event。
6.httpd MPM:運行與并發響應模型中
prefork:進程模型,兩級結構,由主控進程master負責fock自身生成子進程,每個子進程負責響應一個請求;
主控進程預先生成指定的空閑子進程,使用的是select()機制,并發請求連接數上限最多1024個子進程
worker:線程模型,三級結構,由主控進程master負責fock生成子進程,每個子進程負責生成多個線程,每個線程響應一個請求;
對于linux系統來說,線程和進程對于內核本身沒有太多的區別,主控進程用于監聽在套接字中,生成子進程來響應客戶端請求,而子進程并不直接響應客戶請求,而是生成有限的線程對客戶端的請求進行響應,每個線程響應一個請求,每個子進程創建的線程是有限的,線程可以共享進程打開的所有資源,如果線程過多,性能會非常低。
線程模型:對于支持線程模型的服務器來說,線程模型在工作中就表現為一個子進程響應多個請求一樣
Event:由主控進程master負責fock自身生成子進程,每個子進程響應多個請求;
正真意義上的一個子進程響應N個請求,內部并沒有創建線程響應請求,而是在內部使用一個完整的處理邏輯機制來處理客戶端發給此子進程的請求,此子進程中基于事件驅動模型來實現,事件驅動模型的好處在于,每個子進程在響應客戶請求是不用再尋找一個內部的處理機制來處理請求,只需要在請求到達時,而當前的進程正在處理請求,此機制會找一段內存空間將此請求的狀態記錄下來,然后處理其他請求,當子進程工作完成此機制會通知其子進程根據其請求的狀態來繼續響應
基于cow(寫時復制)機制,使用select()機制完成并發,最多并發1024個
7.I/O模型:
異步、同步、阻塞型、非阻塞型、復用型、信號驅動型
同步:進程間通信就有同步異步的概念,同步(synchronous),異步(asynchronous)
如果一個任務依賴另一任務,這個任務向被依賴任務發起調用請求,這個調用請求不會立即返回,而是要等待對方處理完成才返回,但一旦返回了就一定是處理成功的結果;只要收到返回的結果就表示調用者也成功了,這叫做同步;
異步:
當調用發出以后,被調用方可以立即返回消息,但返回的并不是最終結果,于是被調用者可以通過狀態通知機制通知調用者;這種機制就叫異步;這種方式就要依賴于通知,回調函數等等;
所謂異步是指不需要等待被依賴的任務完成,只是通知被依賴的任務干什么事,依賴的一方可以繼續自己的其它任務,被依賴的任務把最終完成的結果通知依賴方即可
同步/異步: 關注消息通知機制;
同步:等待對方返回成功消息;
異步:被調用者通過狀態、通知或回調機制通知調用者被調用者的運行狀態;
阻塞:
是指調用結果返回之前,調用者被掛起(暫停)睡眠狀態;一直處于等待消息通知,不能執行其它任務,只有被調用者的結果返回,調用者才被喚醒并繼續后面的任務;
非阻塞:
當前線程就是調用者可能并沒有被改為睡眠狀態,還可以處理其它任務;調用者在等待被調用者返回時,仍然能執行其它消息的處理這種情況就叫非阻塞;
阻塞/非阻塞:
關注調用者在等待結果返回之前所處的狀態;
即A調用B,B不返回,A就完成不了,所以一定是同步的,只不過在B返回時,A能不能干其它事,如果能就是非阻塞,如果不能就是阻塞;
阻塞和非阻塞是用來描述同步模式下調用者的狀態的;阻塞、非阻塞和異步就沒有關系了,異步就不可能有阻塞;
阻塞:blocking,針對于同步I/O,調用結果返回之前,調用者被掛起;
非阻塞:nonblocking,針對于同步I/O,調用結果返回之前,調用者不會被掛起;
復用型IO調用:
select():1024
poll():
I/O模型:5種
一次IO請求,都會由兩階段組成:
第一步:等待數據,即數據從磁盤到內核內存;
第二步:復制數據,即數據內核內存到進程內存;
(1)同步阻塞:第一步和第二步都會阻塞
(2)同步非阻塞:第一步不會阻塞,第二步會阻塞
(3)IO multipexing:IO復用,select(并發上限最多1024),poll機制(可修改并發上限);
(4)Signal Driven IO:信號驅動(消息通知),同步非阻塞模型(異步阻塞模型),第一階段完全是非阻塞;
(5)Asynchronous IO:異步IO:都不阻塞
Nginx: 全名:engine X = Nginx
http協議:web服務器(類似于httpd)、http reverse proxy(類似于httpd)、imap/pop3 reverse proxy
架構:一個master進程有多個一個或多個worker子進程,每個worker子進程可以相應N個請求,每個worker有核心模塊core和外圍的模塊modules組成,有實現http功能的ht_core模塊,實現負載均衡的ht_upstream模塊,實現反代的ht_proxy模塊,實現fcgi的ht_fastcgi模塊
在需要用到某種功能是直接編譯或轉載指定模塊即可,基于每種模塊可以與后端的不同應用進行通信,例:基于ht_core模塊可以基于http協議與后端的web server通信,基于ht_fastcgi模塊可以與php通信,基于memcache模塊可以與mamcache通信,這些都是反代模型工作時的架構
Nginx架構功能:
Worker進程接收客戶端的請求,如果使用緩存功能,則把后端服務器的內容緩存到本地,如果客戶端再次請求相同數據則負責從緩存中加載數據,直接響應給客戶端;如果客戶端請求的內存沒有緩存,則通過代理客戶端到后端服務器上取資源,如果要取的資源所在的后端服務器是http就用http模塊進行,如果是php服務器就使用FastCgi模塊進行。Nginx能向客戶端提供服務、向后端服務器提供反代服務,又能將后端服務器內容緩存在本地以提高性能。
1.Nginx的程序架構:master/worker
一個master進程:負責加載配置文件、管理worker進程、平滑升級
一個或多個worker進程:分別是那種進程處理并響應用戶請求
2.緩存相關的進程:
cache loader:載入緩存對象
cache manager:管理緩存對象
3.特性:
(1)異步I/O、事件驅動、非阻塞
(2)并實現并發用戶請求響應處理時:可通過kevent/epoll/select機制
(3)基于在本地磁盤上與本地磁盤數據通行時,支持高級IO機制:高級IO sendfile,異步,mmap
Mmap:內存映射,如果文件要想被訪問,都必須先從磁盤載入內核內存中才能夠被訪問,而內存映射指在內存空間中找一段空間映射本地磁盤中的數據,但并沒有把數據復制到內存空間中,而是直接通過這段內存加載數據。
4.nginx高度模塊塊:高度模塊化,但其模塊早期不支持DSO機制;近期版本支持動態裝載和卸載;
核心模塊:core module
標準模塊:Standard HTTP modules 標準http模塊
Optional HTTP modules可選http模塊
Mail modules 郵件模塊
Stream modules 流模塊
3rd party modules 第三方模塊
每個模塊都引入兩個特性:
第一:指令,有某個模塊,就有相應的配置指令,沒有編譯的模塊就沒有這個配置指令
第二:內置變量,不用模塊有不同的變量
5.nginx的功用:
(1)靜態的web資源服務器;
(2)結合FastCGI/uwSGI/SCGI等協議反代動態資源請求;
(3)http/https協議的反向代理;
(4)imap4/pop3協議的反向代理;
(5)tcp/udp協議的反向代理;
6.nginx的安裝配置:
(1)官方的預制包:
http://nginx.org/packages/centos/7/x86_64/RPMS/
(2)編譯安裝:
~]#下載nginx程序源碼包
~]# yum install pcre-devel openssl-devel zlib-devel
Prce-devel:url重寫模塊用到的開發包
Openssl-devel:使用ssl模塊是使用的開發包
~]# useradd -r nginx
~]#./configure –prefix=/usr/local/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/nginx.pid –lock-path=/var/run/nginx.lock –user=nginx –group=nginx –with-http_ssl_module –with-http_v2_module –with-http_dav_module –with-http_stub_status_module –with-threads –with-file-aio
~]# make && make install
編譯安裝Nginx的選項含義:
–prefix=/usr/local/nginx 程序安裝路徑
–conf-path=/etc/nginx/nginx.conf 程序配置文件安裝路徑
–error-log-path=/var/log/nginx/error.log 錯誤日志安裝路徑
–http-log-path=/var/log/nginx/access.log 訪問日志安裝路徑
–pid-path=/var/run/nginx.pid 進程號存放文件路徑
–lock-path=/var/run/nginx.lock 鎖文件存放路徑
–user=nginx 指定那個用戶運行worker進程,主控進程一般與root用戶運行
–group=nginx
–http-client-body-temp-path=/var/cache/nginx/client_temp
客戶端body部分的臨時文件存放路徑,如果服務器允許客戶端使用put方法提交大數據時,臨時存放的磁盤路徑
–http-proxy-temp-path=/var/cache/nginx/proxy_temp
作為代理服務器,服務器響應報文的臨時文件存放路徑
–http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
作為fastcgi代理服務器,服務器響應報文的臨時文件存放路徑
–http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
作為uwsgi代理服務器,服務器響應報文的臨時文件存放路徑
–http-scgi-temp-path=/var/cache/nginx/scgi_temp 作為scgi反代服務器,服務器響應報文的臨時文件存放路徑
–with表示要編譯指定的某個模塊,要啟用指定的模塊
–without表示不編譯指定的某個模塊,禁用指定的模塊
–with-http_ssl_module
–with-http_v2_module
–with-http_dav_module
–with-http_stub_status_module
–with-threads
–with-file-aio
7.配置文件:
主配置文件:nginx.conf
include conf.d/*.conf
fastcgi, uwsgi,scgi等協議相關的配置文件
mime.types:支持的mime類型
fastcgi.conf 支持fastcgi的配置文件,與php結合要編輯此文件;
fastcgi_params 支持fastcgi的配置文件,與php結合要編輯此文件;
koi-utf 支持語言的配置文件
koi-win 支持語言的配置文件
mime.types 支持的MEMI類型的配置文件
scgi_params 支持scgi的配置文件
uwsgi_params 支持uwsgi的配置文件,與params結合要編輯此文件;
8.主配置文件的配置指令:
directive value [value2 …];
注意:(1) 指令必須以分號結尾;
(2) 支持使用配置變量;
內建變量:由Nginx模塊引入,可直接引用;
自定義變量:由用戶使用set命令定義;
set variable_name value;
引用變量:$variable_name
9.主配置文件結構:
main block:主配置段,也即全局配置段;
event {
…
}:事件驅動相關的配置;
http {
…
}:http/https 協議相關的配置段;
mail {
…
} 郵件相關的配置
stream {
…
}
~]#vim /etc/nginx/nginx.conf
worker_processes 1;
//定義啟動的worker進程數,設置為auto時為當前cpu核心數
worker_cpu_affinity 0010 0100;
//指定第1和第2顆cpu為worker運行
使用命令ps axo command,pid,psr 查看worker工作在哪顆cpu上,cpu編號是從0開始;
使用cpumask標識,有幾顆cpu就用幾位二進制數標識使用cpu的個數;
例如:有八顆cpu,用8個位二進制
0000 0000 – 1111 1111
0000 0001 表示第0號cpu
0000 0010 第1號cpu
0000 0100 第2號cpu
0000 1000 第3號cpu
0001 0000 第4號cpu
……
worker_priority -5;
//指定worker進程的優先級nice值為-5;
events {
worker_connections 1024;
//定義每個worker進程可以處理的請求數,每worker支持的最大并發數
}
10.main配置段常見的配置指令:
(1)正常運行必備的配置
(2)優化性能相關的配置
(3)用于調試及定位問題相關的配置
(4)事件驅動相關的配置
11.正常運行必備的配置:
1、user指定運行worker進程的用戶
Syntax: user user [group];
Default: user nobody nobody;
Context: main
user nobody;
2、pid /PATH/TO/PID_FILE;
指定存儲nginx主進程進程號碼的文件路徑;
pid logs/nginx.pid;
3、include file | mask;
指明包含進來的其它配置文件片斷;
http{
include mime.types;
}
4、load_module file;
指明要裝載的動態模塊;
12.性能優化相關的配置:
1、worker_processes number | auto;
worker進程的數量;通常應該為當前主機的cpu的物理核心數;
worker_processes 1;
2、worker_cpu_affinity auto [cpumask];
綁定worker進程運行在指定的cpu核心上,多個cpu核心用空格隔開
CPU MASK:cpu掩碼
00000001:0號CPU
00000010:1號CPU
… …
worker_cpu_affinity 00000001 00000010;
3、worker_priority number;
指定worker進程的nice值,設定worker進程優先級;[-20,20]
worker_priority -5;
4、worker_rlimit_nofile number;
單個worker進程所能夠打開的文件數量上限,默認為1024;
Work_rlimit_nofile 2048;
13、調試、定位問題:
1、daemon on|off;
是否以守護進程方式運行Nignx;如果設定為off,nginx會輸出信息到桌面
Daemon off;
2、master_process on|off;
是否以master/worker模型運行nginx;默認為on,如設定為off,則只有一個worker進程監聽,處理請求;
Master_process off;
3、error_log file [level];
錯誤日志文件的記錄方式及其日志級別;其中debug,依賴于編譯時–with-debug選項
error_log logs/error.log info;
14、事件驅動相關的配置:
定義在events端中的指令:
events {
…
}
1、worker_connections number;
每個worker進程所能夠打開的最大并發連接數數量;
總并發數=worker_processes * worker_connections
events {
worker_connections 1024;
}
每一個進程所能夠打開是數量是受限于(worker_rlimit_nofile設置)它所能夠打開的文件數量的
2、use method;
指明并發連接請求的處理方法;
支持的方法有:select、poll、kqueue、epoll、/dev/poll、eventport
events {
use epoll;
}
3、accept_mutex on | off;
是否打開負載均衡鎖,處理新的連接請求的方法;on意味著由各worker輪流處理新請求,Off意味著每個新請求的到達都會通知所有的worker進程;
events {
Accept_mutex on;
}
15.http協議相關的配置結構
http {
…:各server虛擬的公共配置
server {
…
}:每個server用于定義一個虛擬主機;
server {
…
server_name //定義當前虛擬主機的主機名
Root //定義文檔根目錄
Alias //別名
location [OPERATOR] URL { //定義類似于別名的映射
…
if CONDITION {
…
}
}
}
}
Nginx 配置:與套接字相關的配置
1.server {…}配置虛擬主機
配置一個虛擬主機;基于ip和主機名沒顯著區別;只能用于http上下文中;
server {
listen address[:PORT]|PORT;
server_name HOSTNAME;
root /PATH/TO/DOCUMENTROOT;
…
}
注意:(1)基于port的虛擬主機:
listen指令需要使用不同的端口;
(2)基于HOSTNAME的虛擬主機:
server_name指令指向不同的主機名;
(3)基于IP的虛擬主機;
listen IP:port
2.listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE
listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
default_server:設置默認虛擬主機;用戶訪問虛擬主機不存在時默認響應的虛擬主機
ssl:限制只能通過ssl連接提供服務;端口要為443;
backlog:后援隊列的長度;例如并發最大為100個,來了200請求,就要排隊,如果排隊也滿了就靠后援隊列,后援隊列也滿了就有可能超時了;
rcvbuf:接收緩沖區大??;
sndbuf:發送緩沖區大??;
3.server_name name …;
指明虛擬主機的主機名稱;后可跟多個由空白字符分隔的字符串;
支持*通配任意長度的任意字符;server_name *.magedu.com
支持~起始的字符做正則表達式模式匹配;server_name ~^www\d+\.magedu\.com$
匹配機制:
(1) 首先是字符串精確匹配;
(2) 左側*通配符;
(3) 右側*通配符;
(4) 正則表達式;
練習:定義四個虛擬主機,混合使用三種類型的虛擬主機;
僅開放給來自于本地網絡中的主機訪問;
1.編輯主配置文件,定義虛擬主機:
1和2定義基于主機名的虛擬主機
3和4定義基于ip的虛擬主機
2和4定義基于端口的虛擬主機
~]# vim /etc/nginx/nginx.conf
(1)server {
listen 88;
server_name www.li1.com;
root /var/li1/html;
}
(2)server {
listen 192.168.1.4:88;
server_name www.li2.com;
root /var/li2/html;
}
(3)server {
listen 10.1.25.11:8;
server_name www.li3.com;
root /var/li3/html;
}
(4)server {
listen 192.168.1.4:8; www.li4.com;
root /var/li4/html;
}
2.添加防火墻規則:
[root@Centos72 ~]#iptables -P INPUT DROP
[root@Centos72 ~]# iptables -A INPUT -s 10.1.0.0/16 -d 10.1.25.11 -p tcp -m multiport –dport 22,8,88,80 -j ACCEPT
[root@Centos72 ~]# iptables -A OUTPUT -s 10.1.25.11 -p tcp -m multiport –sport 22,8,88,80 -j ACCEPT
[root@Centos72 ~]# iptables -vnL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
347 28512 ACCEPT tcp — * 10.1.0.0/16 10.1.25.11 multiport dports 22,8,88,80
pkts bytes target prot opt in out source destination
18 1648 ACCEPT tcp — * * 10.1.25.11 0.0.0.0/0 multiport sports 22,8,88,80
4.tcp_nodelay on|off;
只對keepalived模式下才有意義,是否啟用TCP_NODELAY選項;
tcp特性每次都要3次握手,4次斷開,如果兩主機間通信時,每次在保持連接的通信上,服務器只發送很小的數據給客戶端,會浪費帶寬(開銷比數據大)
如果客戶端只請求了這個很小的數據,等待很長時間才能得到響應,此時tcp等待很小的報文增多時一起發送時,表示tcp_delay=off;
如果客戶端請求有小數據時,服務端也立即發送,表示tcp_nodelay=on
tcp_nodelay on 表示數據報文每請求一次發送一次,不允許延遲發送響應報文
Tcp_nodelay off 表示數據報文請求數據少的時候,聚合數據報文多的時候同意發送響應報文
5.sendfile on|off;
是否啟用sendfile功能,即在內核中直接封裝響應報文響應用戶的請求;默認是關閉的,需要手動啟用;
(把用戶所請求的數據直接在內核中封裝響應發送給客戶端)
tcp_nopush on | off;
只在sendfile啟用時才有效,默認是關閉的;
定義路徑相關配置:
6.root path;
設置web資源的路徑映射;用于指明用戶請求的url所對應的本地文件系統上的文檔所在目錄路徑;
可用的上下文:
http:表示對所有server都生效;
server:表示只對當前一個server生效;
location:表示只對server定義的location中的URL生效;
if:表示僅對條件判斷生效;
7、location 有2種方式:
location [ = | ~ | ~* | ^~ ] uri { … }
location @name {…}
根據用戶請求的URI來匹配定義的location,匹配到時,此請求將被相應的location塊中的配置指令所處理;有點類似于if的功能;
=:URI精確匹配;用戶給定的URI與location中的完成一樣;
~:做正則表達式模式匹配,區分字符大小寫;
~*:做正則表達式模式匹配,不區分字符大小寫;
^~:對URI左半部分做匹配檢查,不區分字符大小寫;
匹配優先級:=、^~、~/~*、不帶符號;
如果用戶請求的URI被server中的代碼塊中多個location都能匹配到,應用則按照優先級;
URi:訪問資源時路徑:http://www.magedu.com/images/1.jpg,其中:/images/1.jpg就被稱為uri;
location可以對某特定資源類型加以限制,例如用戶訪問的都是以.txt結尾,壓縮以后發送;此時就必須標識出那些資源
以txt結尾,來作出額外處理:
location ~* \.txt {
gzip on;
}
location引入了新的上下文,可有指令,但僅對location能匹配到的uri資源生效;所以在一個server中location可出現多次,分別用來實現對不同類型資源做特定處理功能;location中還可嵌套location;
8、alias path;
定義路徑別名,也是文檔映射的一種機制,只能用在location上下文;
root指令:給定的路徑對應于location中/uri/左側的/;
alias指令:給定的路徑對應于location中的/uri/右側的/(這個url),而不包含uri本身;
例如:在http中,定義別名 alias /bbs/ /forum/
請求資源:http://www.magedu.com/bbs/a.jpg
對應資源:http://www.magedu.com/forum/a.jpg
文件路徑:/web/forum/a.jpg
在nginx中,定義別名,例如:
location /bbs/ {
alias /web/forum/;
}
相當于訪問的是:/web/forum/a.jpg;
有時常用法,例如:
location /bbs/ {
root /web/forum/;
}
相當于訪問的是:/web/forum/bbs/a.jpg
例:定義虛擬主機,定義bbs別名
1 server {
2 root /var/li1/html;
3 server_name www.li1.com;
4 listen 80;
5 location /bbs {
6 root /var/li1/html;
7 }
8 location /bbs2 {
9 alias /var/li1/forum;
10 }
11 }
實驗結果:
(1)訪問www.li1.com時顯示/var/li1/html/index.html主頁信息
(2)訪問www.li1.com/bbs時顯示/var/li1/html/bbs/index.html主頁信息
(3)訪問www.li1.com/bbs2時顯示/var/li1/forum/index.html主頁信息
結論:
(1)定義root或alias指定的路徑時相對于文件系統的絕對路徑地址
(2)對于root,訪問location指定的目錄時會補全location到root指定的目錄后面
(3)對于alias,訪問location指定的目錄會直接跳轉到alias指定的目錄
(4)定義別名時,location指定的目錄和alias指定的
9.index file …;
可用位置:http,server,location;
設置默認主頁;在不同的location可指定不同的主頁;
10.error_page code…[=[response]] url;
自定義錯誤頁面,根據用戶請求的資源的http響應的狀態碼實現錯誤頁重定向;
可用于http、server、location、if in location
(1)自定義錯誤碼對應錯誤頁面
server {
root /var/li1/html;
server_name www.li1.com;
listen 80;
location /bbs {
root /var/li1/html;
error_page 404 =200 /error.html;
}
當用戶訪問錯誤碼是404,響應/var/li1/html/error.html錯誤頁面給用戶,并且客戶端的回應碼為200 ok;
(2)自定義多個響應碼響應一個頁面
例:服務器端錯誤頁面:可定義多個響應碼
server {
root /var/www/html;
server_name www.li1.com;
listen 808;
error_page 404 403 /error.html;
location = /error.html {
root /var/error;
}
}
用戶訪問頁面時代碼為403,404時,返回error.html頁面給用戶
注意:error.html頁面首先匹配location中定義的root目錄下是否存在error.html文件,如果location中的root指定的目錄中未定義error.html文件,則會從http、server自上而下匹配root下的error.html頁面返回給用戶
(3)錯誤解決方法
顯示:Error_Page
編譯時沒有自動創建:/var/run/nginx/nginx.pid
解決辦法:sudo nginx -c nginx.conf
sudo nginx -s reload
11、try_files
定義客戶端請求的相關配置:
12、keepalive_timeout timeout [header_timeout];
設定保持連接的超時時長,0表示禁止使用長連接,默認為75秒;
13、keepalive_requests number;
在一次長連接上所允許請求的資源的最大數量,默認100個;
14、keepalive_disable none|browser…;
對哪種瀏覽器禁用長連接;none表示不禁用;
15、send_timeout time;
向客戶端發送響應報文的超時時長,默認60秒;是指兩次寫操作之間的間隔時長;
16、client_body_buffer_size size;
用于接收客戶端請求報文的body部分的緩沖區大小,默認為8或16k(取決于32位64位系統),超出此大小時,其將被暫存到磁盤上;
客戶端請求資源時,緩存主體內容的緩沖區大小
17、client_body_tmp_path path[level1 [level2 [level3]]];
設定用于存儲客戶端請求報文的body部分的臨時存儲路徑及子目錄結構和數量;
每一個客戶端請求報文的body大小為16k,并發連接的請求量有很多;因此,如果每一個請求量都大于了16k,都應該緩存到磁盤上,如果請求數量有2萬個,就意味著在這個目錄下有2萬個文件,從這2萬個文件中找一個在某個時刻是特別慢,為了加速這個過程,就實現分級存儲;
例:
/var/tmp/body/{1,2,3}創建3個一級子目錄,還可在1下再創建{a,b,c}二級子目錄;
在文件存儲時,可以按級存儲,好處在于可以按級查找文件;把每個用戶請求的URL,把URL做md5編碼,編碼后首字母是0-15之間的數字,所以就看第一位是什么,第一位是0就放在0目錄下,是1就放在1目錄下…;然后再找第二位,是a就放在a目錄下,是b
就放在b目錄下…;
由于使用的是16個數字,就意味著可以把2萬個文件平均在16個子目錄下,第一次查找就可以縮減了15倍,在二級子目錄下查找又可以縮減15倍;
因此,這里分級的意義,就是用來指明,創建多少一級子目錄,創建多少二級子目錄,多少三級子目錄;
這里的[level1 [level2 [level3]的代表一個數字,表示十六進制數的個數;
例如:
/var/tmp/body 2 表示在body目錄下使用兩個十六進制字符創建一級子目錄,一個十六進制是4位二進制數,兩個十六進制數就是8位二進制數;因此,一共有256中變化,即:
00-ff 可創建256個一級子目錄;
/var/tmp/body 2 1 表示在每一個一級子目錄下,使用一個十六進制數創建二級子目錄,即可創建16個二級子目錄;00-ff 可創建256個一級子目錄;0-f 可創建1個二級子目錄;
/var/tmp/body 2 1 2 表示在每個二級子目錄下有兩個十六進制數創建三級子目錄,即可創建256了三級子目錄;00-ff 可創建256個一級子目錄;0-f 可創建1個二級子目錄;00-ff 可創建256個三級子目錄;
所以,這樣查找一個文件只需前5個字符,就可以第一次縮減256倍,第二次縮減16倍,第三次又縮減256倍;就是2^8+2^4+2^8,只需3次查找就基本可以定位到文件的位置了;
對客戶端請求進行限制的相關配置:
18、limiti_rate rate;
限制服務器端每秒鐘響應給客戶端的傳輸速率,單位是字節/秒,bytes/second,0表示無限制;只用于http,server,location,if;
例:定義limit_rate限制客戶端請求服務端資源速率
]# vim /etc/nginx/nginx.conf
location /download/ {
limit_rate 20480;
root /web/host1;
}
]# mkdir /web/host1/download
]# dd if=/dev/zero of=/web/host1/download/test.img bs=1M count=50
在本機測試:
]# wget http://192.168.255.2/test.img
瀏覽器測試:http://www1.stu11.com/download/test.img
顯示:下載對話框;速度非常慢;
實驗結果:
(1)設定limit_rate 為20480時,使用瀏覽器http://HOST/download/test.img時,會自動彈出下載框,此時下載速率為20k/s;當關閉limit_rate指令時,下載速率為20M/s。
19、limit_except method… {…};
限制對指定的請求方法之外的其它方法的使用客戶端;
僅限制用于location中;
例:限制GET方法可以所有人訪問,但除了GET方法以外的其他方法只允許10.1.1.25客戶端訪問;
limit_except GET {
allow 10.1.1.25/32;
deny all;
}
表示除了GET方法以外的其它方法僅允許192.168.1.0/32中的主機使用;
文件操作優化的配置:
20、aio on|off|threads[=pool];
是否啟用aio功能;默認關閉;指明使用多少個線程;不指定就是用多少啟用多少線程;建議開啟,可用在http, server, location;
21、directio size|off;
Context:http, server, location
是否啟用直接IO, 當請求的文件達到指定大小時啟用直接IO;
直接IO就是,寫請求的時候,數據不在內存中緩存而是直接刷到磁盤上去,這就是直接IO;對性能有影響,對數據可靠性比較高;
例:當I/O請求的文件大于4M以后啟用直接I/O #directio 4m
22、open_file_cache off;
open_file_cache max=N[inactive=time];
有助于提高性能;對打開的文件是否緩存下來,nginx緩存的是文件的元數據;
off:表示不緩存;
max=N:可緩存的緩存條目上限;達到上限后會使用LRU(最近最少使用)算法實現緩存管理;
inactive=TIME:緩存項的超時時長,在此處指定的時間內未被訪問命中的或命中的次數少于open_file_cache_min_users指令指定的次數的緩存項即為非活動項;
nginx可以緩存以下三種信息:
(1)文件的描述符、文件大小和最近一次的修改時間;
(2)打開的目錄結構;
(3)沒有找到的或沒有權限訪問的文件的相關信息;
23、open_file_cache_errors on|off;
是否緩存查找時發生錯誤的文件一類的信息;open_file_cache的功能是否有效,取決于此處指令;
24、open_file_cache_min_uses number;
緩存項在非活動期限內,最少應該被訪問的次數;
在open_file_cache指令的inactive參數指定的時長內,至少應該被命中多少次可以被歸類為活動項
哪些文件被認為是非活動項:在open_file_cache中指定的時長內沒有被訪問的項就叫非活動項;其實,非活動項是有最小門檻限制的;在指定的時長內,至少要訪問多少次,才認為是活動項,少于此處指定的次數才認為是非活動項,而不是0次;
在open_file_cache中指定的時長內沒有被訪問的項就叫指令的inactive參數指定的時長內,在至少命中此處指定的次數方可不被歸類到非活動項;
25、open_file_cache_valid time;
緩存項有效性的檢查頻率;默認為60秒;
能改善nginx的性能,nginx很多地方都能用到緩存,而緩存的管理方法都是近似的;理解了這一個,其它就很容易了;
一旦發現文件是非活動期限,超出非活動時長,或在指定時長內,訪問次數小于min_uses指定的次數,就應該把該文件刪除;此處就是設置,每隔多久檢查一次文件的非活動期限;
ngx_http_access_module模塊:訪問控制模塊
實現基于客戶端ip的訪問控制功能;跟http基于ip實現訪問控制是一類法則;
26、allow address|CIDR|unix:|all;
27、deny address|CIDR|unix:|all;
可用上下文:http,server,loaction,limit_except
例如:
location / {
deny 192.168.11.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8:/32;
deny all;
}
ngx_http_auth_basic_module模塊;基于用戶認證的模塊
例如:
location / {
auth_basic "closed site";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
}
28、auth_basic string|off;
使用basic機制進行用戶認證;
用戶為虛擬用戶,要指明賬號、密碼的位置;
auth_basic_user_file file;
認證用的賬號密碼文件;
文件格式:name:password:commet(注釋)
密碼格式:htpasswd命令(或使用crypt()函數進行加密)
例:創建賬號、密碼文件;
]# yum -y install httpd
]# htpasswd -c -m /etc/nginx/.nginxpasswd tom 給tom用戶設定密碼
]# htpasswd -m /etc/nginx/.nginxpasswd jerry 給jerry用戶設定密碼
]# vim /etc/nginx/nginx.conf
root /var/www/html;
location /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /var/www/.pass;
}
實驗結果:
密碼文件所在的位置只能使用文件系統上的絕對路徑
ngx_http_stub_status_module模塊;
能夠啟用nginx自帶的狀態頁面,
用于輸出nginx的基本狀態信息;
29、tub_status;
例:定義nginx狀態頁面
]# vim /etc/nginx/nginx.conf
location /status {
stub_status;
Access_log off //不記錄訪問狀態頁面的訪問記錄
}
顯示信息解釋:
Active connections: 2 當前活動狀態客戶端鏈接數
server accepts handled requests
19 19 44
Reading: 0 Writing: 1 Waiting: 1
解釋:
Active connecttions:處于活動狀態的客戶端連接的數量;(包括等待客戶端發來請求、開始建立連接的客戶端但已經處于等待客戶端發請求、或正在處理客戶端請求、正在給客戶端發響應報文)
accepts:服務器已經接受客戶端請求的總數;(包括已經處理完、正在處理)
handled:已經處理完成的客戶端請求的總數;(接收的大于處理完成的數量;)
requests:客戶端已經發來的請求總數;(包含拒絕的請求)
Reading:正處于讀取客戶端請求報文首部的連接數量;
Writing:正處于向客戶端發送響應報文過程中的連接數;
Waiting:正處于等待客戶端發出請求的空閑連接數;如果啟用保持連接功能,客戶端請求資源后沒再請求就處于空閑狀態;如果waiting狀態數量很多,表示大量客戶端處于空閑狀態,有可能是keep allive timeout設置時間太長所導致;
ngx_http_referer_module模塊:
基于引用做訪問控制;表示從哪個鏈接跳轉到當前頁面;
30、valid_referers none|blocked|server_names|string…;
定義合法的referers數據;可實現防盜鏈拒絕訪問,拒絕來自某鏈接到本網頁等功能; Context: server, location
one:請求報文首部沒有referer首部;
blocked:請求報文的referer首部沒有值;
server_names:其值是主機名;一般是自己的域名;
string:有2種
arbitrary string:直接字符串,可以使用*通配符;
regular expression:被指定的正則表達式模式匹配到的字符串,要使用~開頭;
例如:使用主機名;
valid_referers none blocked server_names *.magedu.com magedu.* ~\.magedu\.;
if($invalid_referer){
return 403; }
其中,$invalid_referer是內嵌變量,表示只有不能被valid_refers指令匹配到的頭被歸類到invalid_referer;直接調用$invalid_referer變量即可;
例:只允許baidu.com域名的主機跳轉,不允許baidu.com域名以外的跳轉
[root@Centos conf.d]# vim vhost.conf
location /status {
stub_status;
access_log off;
valid_referers none blocked server_names *.baidu.com;
if ($invalid_referer) {
return 403;
}
}
驗證:baidu.com域名的所有主機可以跳轉,其余都不能跳轉
[root@Centos72 ~]# curl -e http://www.baidu.com http://192.168.1.10/status
Active connections: 1
server accepts handled requests
37 37 37
Reading: 0 Writing: 1 Waiting: 0
[root@Centos72 ~]# curl -e http://www.google.com http://192.168.1.10/status
<h1>403 404 error.html
ngx_http_log_module模塊
用于實現以指定格式記錄用戶請求日志;
在httpd設置日志格式時,有4種:combined、common、referer、agent等;但日志記錄的信息越豐富,對并發較高的場景中,對磁盤IO壓力越大;
31、access_log path format gzip[=leve][buffer=size][flush=time][if=condition];
access_log off;關閉訪問日志;Context:stream server
path:可指明日志文件路徑;
gzip[=leve] :指明日志文件壓縮存放時的gzip壓縮比
format:日志格式;
buffer=size日志緩存大??;(磁盤刷寫頻率過高時應調大此值);
flush=time:多長時間從內存刷寫至磁盤上一次;
例:access_log /testdir/nginx_status/acc.log main gzip=7;
結論:日志格式必須定義在http段, 日志文件路徑及格式定義在server段
32、access_log syslog:server=address[,parameter=value] [format[if=condition]];
向指定的日志服務器發送日志;
33、log_format name string…;
Context:http
定義日志格式,指明名稱和字符串;與httpd定義略有區別,在httpd中使用%u等宏定義,而對nginx則使用內建的變量來定義格式;
string可以使用nginx核心模塊及其它模塊內嵌的變量;
例:日志格式定義及含義
log_format main '$remote_addr – $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /spool/logs/nginx-access.log compression buffer=32k;
含義:
main:日志格式名稱;
$remote_addr:表示遠程地址;
$remote_user:遠端用戶名;
$request:客戶端發出的請求;
$http_referer:上一級跳轉的頁面;
$http_user_agent:瀏覽器類型;
$gzip_ratio:壓縮比;
使用access_log調用格式名(main)即可;
課外作業:為nginx定義使用類似于httpd的combined格式的訪問日志;
http格式:
log_format sts '$remote_addr'
' – – ["$time_local"]'
' "$request"'
' $status'
' \"-\" "$http_user_agent"';
34、open_log_file_cache max=N[inactive=time][min_uses=N][valid=time];
open_log_file_cace off; 關閉此功能
定義緩存空間,用來存儲文件描述符,對Linux系統,任何文件在內核中都能基于某個數字來追蹤這個文件,這個數字就是引用這個文件的唯一標識;稱為fd(file descriptors)叫做文件描述符;可理解為內核打開文件引用的臨時映射的數字標識;
多個server虛擬主機打開的文件不止一個,日志的每一次寫操作都要臨時通知內核,打開一個文件,寫完之后就關閉了,再寫時還得再找,這樣太慢了;可以把打開的文件緩存下來,每個文件打開后用一個描述符映射,隨時用隨時找這個描述符就可以;
max=N:緩存的最大文件描述符數量,默認10個;能緩存多少條打開的文件,在一個緩存中能緩存多少個打開的文件條目;如果超過設置條目,使用基于LRU算法最近最少使用算法,進行換進換出做緩存管理;
min_users:在inactive指定的時長內訪問大于等于此值方可被當作活動項;
inactive:非活動時長;
valid:驗正緩存中各緩存項是否為活動項的時間間隔;
nginx的內置變量:
$bytes_sent:發送的字節數;the number of bytes sent to a client
$connection:連接的序列號;
$connection_requests:連接請求;
$msec:毫秒;
$pipe:p表示基于管道,.表示otherwise;
$request_length:請求報文的長度;
$request_time:請求時間;
$status:響應碼;
$time_iso8601:時間格式;
$time_local:本地時間;
ngx_http_rewrite_module模塊:
用于實現將用戶請求的URI基于正則式轉換為其它URl機制;并且以重定向方式默認返回給客戶端,讓客戶端對新的URI重新再次發起請求;
處理步驟:
在server當中,使用rewrite指令定義的重寫機制是自上而下逐條進行處理的,類似于iptables的規則都是自上而下應用設置的;如果被第一條處理,下面不會再檢查;因為處理過了已經返回給客戶端,客戶端已經再次請求新URI了;
執行過程會重復如下操作:
(1)基于用戶請求的URI去搜索location;
(2)在一個location內部的指令,是從上而下逐條檢查;
(3)如果URI被重寫循環重復,最多10次,就會提示錯誤頁面
(4)用戶請求到達nginx服務器端時,服務端有多個server虛擬主機,映射到哪個server,取決于用戶請求的server name,根據用戶請求的server name最終被判斷到底請求的是哪個server,從而判斷屬于哪個server,每個srever內部還有多個location,每個location用來定義URL到本地文件系統路徑的映射方式以及內部處理機制;因此,還有根據用戶請求的URL去匹配location;所以,這里有2步操作:
第一步,根據server name匹配是哪個server,
第二步,根據用戶請求的URL去匹配server內部的location;在一個location內部可能存在多個rewrite指令,rewrite指令作用就是把用戶請求的URL換成其它的URL;
例如:用戶請求的是http://server2/hello.htm,被匹配到第二個srever上,其中location中如果第一條rewrite指令,指明了把hello.html指向了hi.html;則返回給客戶端去請求http://server2/hi.html,而后客戶端要重新再次發請求,依然自上而下去匹配屬于哪個server、哪個location;如果hi.html被第三location匹配則被location中的指令處理;
例:循環重寫示例:
rewrite (.*)\.jpg$ –> $1.html;
rewrite (.*)\.html$ –> $1.jpg;
寫的規則次序很重要:根據用戶請求的主機名來判斷是哪個server;確定server后,根據location完成搜索,根據location中的重寫規則完成重寫,重寫后,返回客戶端一個新的URL,客戶端再次發請求;如果中間出現循環最大循環10此;URL重寫可實現跨server,例如請求http://server2/images/1.jpg,改寫為http://images/$1.html,這個images可能是其它虛擬主機,甚至還可能是另一臺物理服務器;
所有URL重寫,可在一個主機上的一個server內只把URL部分重寫,但有時可以把server重寫,實現鏡像服務器;把里面的服務器地址改了,但是URL沒改;
URL重寫可把對應動態資源的請求轉換為靜態的URL地址;因此,這個結果可被搜索引擎收錄,還可被緩存服務器緩存;可理解為把動態資源靜態化的效果;
如果用戶訪問的php動態資源,很多時候緩存服務器是不緩存這個結果的,但是如果動態資源生成的結果不會再變化可以緩存服務器緩存下來時(靜態的存下來),可以給靜態URL;這種機制可在nginx的rewrite功能來實現;但用到正則式就要啟動正則表達式引擎,這樣會消耗更多資源;因此,盡量不使用;
1、rewrit regex replacement[flag];
用于實現重寫操作;
把用戶請求的URI基于regex做檢查,匹配到時,這個URI將替換為replacement指定的字符串;
[flag]:
last:重寫完成后停止對當前URI在當前location中后續的其它重寫操作,而后對新的URI啟動新一輪重寫檢查;提前重啟新一輪循環;
break:重寫完成后停止對當前URI在當前location中后續的其它重寫操作,而后直接跳轉至重寫規則配置塊之后的其它配置;結束循環;
redirect:重寫完成后以臨時重定向方式直接返回重寫后生成的新URI給客戶端,由客戶端對新URL進行請求;(重定向響應碼302),不能以http://或https://開頭;
permanent: 重寫完成后以永久重定向方式直接返回重寫后生成的新URI給客戶端,由客戶端對新URL進行請求;(重定向響應碼301)
如果第一條規則被last匹配了,意味著新的URI會重新做一次請求,nginx會在內部自動重新檢查,如果又被這個location匹配,還會再檢查一遍;最終將資源加載后返回給客戶端;
如果第一條規則被break匹配,rewrite停止在第一條中的新URI上,意味著不再被執行重寫指令即跳出循環,nginx會在內部而繼續執行此location內的其它指令;最終將資源加載后返回給客戶端;
如果第一條規則被redirect匹配,直接將新URL返回給客戶端,瀏覽器自動對新URL發請求,這個新URL有可能還是本機中location,再解析匹配檢查,所以,redirect直接返回的不是資源,而是一個新的URL;
但redirect和permanent,表示當用戶請求的URL被重定向時,直接返回用戶新的URL,讓用戶自己重新請求,只不過這兩者的區別為,redirect是臨時重定向,permanent是永久重定向;
注意:last和break都是nginx自動的在內部進行后續處理;
redirect和permanent是nginx返回URL給客戶端瀏覽器自動重新請求的
注意:
(1)在同一location中存在多個rewrite規則會自上而下逐個被檢查(隱含循環);可使用flag控制此循環功能;
(2)如果replacement是以http://或https://開頭,則替換結果會直接以重定向方式返回給客戶端;
(3)如果replacement不是以http://或https://開頭,將會按次序,依次讀取規則,所有規則都處理完成后,把最終結果返回客戶端,而不是被某條規則重寫后立即返回客戶端;
(4)查找時可使用模式,替換為的內容不能使用模式,但可使用后向引用,在nginx中不使用\1,是使用$1來表示引用;
(5) 如果在同一級配置塊中存在多個rewrite規則,那么會自下而下逐個檢查;被某條件規則替換完成后,會重新一輪的替換檢查,因此,隱含有循環機制;[flag]所表示的標志位用于控制此循環機制;
(6)rewrite指令的執行次序,就是寫在配置文件中的次序,如果重寫時一個規則依次向下循環匹配很多規則時,可使用flag中的break在指定的規則上停止循環,完成最終重寫。
例:(1)無錯誤頁面重寫
]# vim /etc/nginx/nginx.conf
20 location / {
21 index index.html;
22 rewrite (.*)\/.*\.?.* $1/index.html break;
23 }
結論:無論用戶輸入什么資源,都會重寫到index.html頁面
(2)定義死循環
]# vim /etc/nginx/nginx.conf
20 location / {
21 index index.html;
22 rewrite (.*)\.txt $1.html;
23 rewrite (.*)\.html $1.txt;
24 }
結論:瀏覽器輸入http://10.1.1.25/index.txt時,服務器響應碼為500(服務器內部錯誤),此時在兩條重寫規則任意一條中添加break即可終止循環。
2、rewrite_log on | off;
是否啟用重寫日志;啟用時,日志信息被發往錯誤日志;
if(condition){…} 條件判斷機制,在條件滿足時,執行配置塊中的配置;引入了一個新的配置上下文;通常對nginx的變量做判斷;
可在ngx_http_core_module模塊中,查看定義的變量;$remote_addr、$remote_port、$remote_user、$request_uri、$uri等等;
Condition:表達式
(1)條件比較表達式:
等值比較和不等值比較: ==,!=
~:模式匹配,左側字符串是否能被右側模式匹配,區分字母大小寫;
~*:模式匹配,左側字符串是否能被右側模式匹配,不區分字符大小寫;
!~:模式不匹配,左側字符串是否不能被右側模式匹配,區分字符大小寫;
!~*:模式不匹配,左側字符串是否不能被右側模式匹配,不區分字符大小寫;
(2)文件及目錄存在性判斷:
-f|!-f:存在且類型為文件,嘆號表示取反;
-d|!d:判斷為目錄;
-e|!-e:判斷存在;
-x|!-x:判斷執行權限;
例:(1)定義只允許瀏覽器類型為Chrome和Firefox時,才能將.txt重寫為.html
]#vim /etc/nginx/conf.d/vhost.conf
if ($http_user_agent ~* Chrome|Firefox ) {
rewrite (.*)\.txt $1.html break;
}
表示:判斷用戶的瀏覽器是否能被Chrome或Firefox匹配,$http_user_agent是其它模塊引入的變量;
(2)定義如果用戶請求方法為post時,返回錯誤代碼及提示給用戶
if ($request_method = POST) {
return 405 “Sorry”;
}
(3)定義用戶訪問的uri中帶有admin字樣就返回錯誤代碼及提示給用戶
]# vim /etc/nginx/nginx.conf
if ($uri ~* .*admin,*) {
return 403 "go away";
}
結論:(1)瀏覽器輸入:www1.stu11.com/admin.html,顯示:go away,響應碼還是403;
(2)返回指定的錯誤代碼不受自定義的錯誤代碼響應頁面影響
set $variable value;
用戶自定義變量;在nginx中變量無論在定義還是引用都要使用$符號;
ngx_http_gzip_module模塊
過濾器,對指定類型的資源壓縮傳輸以節約帶寬;但消耗了cpu資源;
一下所有指令都可用與http, server, location
1、gzip on|off;
是否啟用gzip壓縮響應報文;不是所有瀏覽器都支持壓縮機制;
2、gzip_comp_level level;
指定壓縮比,1-9,默認為1;數越大壓縮比越大;
3、gzip_disable regex …;
regex是匹配客戶端瀏覽器類型的模式,表示對所有匹配到的瀏覽器不執行壓縮響應;因為有些瀏覽器類型不支持壓縮;
4、gzip_min_length length;
觸發啟用壓縮功能的響應報文的最小長度;
5、gzip_http_version 1.0|1.1;
設定啟用壓縮響應功能時,協議的最小版本;向下兼容原則;
6、gzip_types mime-type …;
壓縮過濾器,僅對此處設定的MIME類型的內容啟用壓縮功能;默認為text/html;
7、gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …;
nginx作為代理服務器接收到從被代理服務器發送的響應報文后,在何種條件下啟用壓縮功能的;
off:對代理的請求不啟用
expired:如果響應報文首部包含expired字段并有值,其值即是有效的但過期了,因為禁用了緩存機制,則啟用壓縮;
no-cache, no-store,private:表示從被代理服務器收到的響應報文首部的Cache-Control的值為此三者中任何一個,則啟用壓縮功能;
示例:定義壓縮機制
]#vim /etc/nginx/conf.d/vhost.conf
gzip on;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_disables msle6;
gzip_min_length 2;
gzip_type text/plain text/css text/xml applicatin/x-javascript application/xml application/json application/javascript;
ngx_http_fastcgi_module模塊:
LNMP():
nginx+php(fpm):只有1種
nginx編譯時只支持fastcgi模塊,php也只能使用php-fpm機制;fpm就是fastcig processor manager進程管理器; php在編譯時使用–enable-fpm選項支持fpm
當有大量數據進行保存時,要放在專用的存儲中,需要專用的協議客戶端,php程序代碼,要與后端mysql通信,就要php鏈接mysql的驅動,叫php鏈接器;不同程序員使用不同的鏈接器,存儲mysql數據庫;
當用戶請求有動態資源時,就交由后臺的php服務器進行處理,如果還要有數據存儲,就由php再與myslq通信,從而,將結果返回給客戶端;
后端存儲會存在多個客戶端與數據庫服務器通信,此時會遇到資源征用,可能會導致資源響應較慢;
安裝php-fpm與nginx結合;安裝php鏈接mysql的驅動;
nginx和php-fpm在同一臺主機:
]# yum -y install php-fpm php-mysql php-mbstring php-gd php-xml
]# rpm -ql php-fpm
/etc/php-fpm.d/www.conf 配置文件
/etc/sysconfig/php-fpm 環境配置文件
/usr/share/fpm/status.html 狀態頁面
]# vim /etc/php-fpm.d/www.conf
[www]
listen = 127.0.0.1:9000 監聽php本機的ip地址
;listen.backlog = -1 后援隊列
listen.allowed_clients = 127.0.0.1 前端web服務器的ip地址;
user = nginx
group = apache
pm = dynamic 動態方式
pm.max_children = 50 最大并發進程數,根據業務,資源設置;
pm.start_servers = 5 啟動時的進程數
pm.min_spare_servers = 5 最小空閑進程數
pm.max_spare_servers = 35 最大空閑進程數
;pm.max_requests = 500 單個pm進程最多響應請求數量
pm.status_path = /pm_status 可能被nginx所占用,改名為pm_status;
]# systemctl start php-fpm
]# vim /etc/php-fpm.d/www.conf
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; 把fastcgi請求傳遞給后端php服務器
fastcgi_index index.php; 匹配此location中的php
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html/$fastcgi_script_name; 其中/scripts應為后端php主機資源所在的文件路徑;
include fastcgi_params; 在文件中定義參數;
}
]# ls /etc/nginx/
fastcgi.conf
fastcgi.conf.default
fastcgi_params
fastcgi_params.default
使用哪個文件,就在配置文件中include包含哪個文件即可;
]# vim /etc/nginx/fastcgi_params
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
參數有很多,在URL請求中包含很多信息,參數、查詢字符串、請求方法等都要讓后端服務器知道;在代理時,前端服務器是根據客戶端請求的報文首部分析;
就是把前端的各種信息保存在變量中,參數可認為就是變量,把變量的值保存在對應的參數中,后端服務器可通過參數獲取值,這個參數相當于中間變量,由前端的fastcgi模塊,把變量傳遞給后端php服務器;
]# vim /usr/local/nginx/html/info.php
<?php
phpinfo();
?>
]# nginx -s reload
瀏覽器輸入:https://www1.stu11.com/info.php
fastcgi模塊指令:
1、fastcgi_pass address;
指明后端php-fpm服務器的address;是fpm服務器監聽的地址和端口;
示例:fastcgi 127.0.0.1:9000;
2、fastcgi_index name;
定義fastcgi應用的主頁名稱;可以是多個;
3、fastcgi_param parameter value [if_not_empty];
指明向后端傳遞的參數,傳遞給fpm服務器的參數及其值;有可能調用的nginx變量的值;
(1)fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time]
(2)[max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off]
(3)[purger_files=number] [purger_sleep=time] [purger_threshold=time];
定義緩存空間的名稱;
path:文件系統路徑,用于存放緩存的文件數據;在此目錄下分多級目錄
max_size=size:定義此路徑下多大空間用于存儲緩存數據;其它使用默認設置即可;
levels=#[:#[:#]]:緩存目錄的層級定義;一般為1或2;
例如:levels=1:2;
keys_zone=name:size
定義內存中用于緩存k/v映射關系的空間名稱及大??;
inactive=time 非活動時間
注意:只能用于http上下文;
nginx緩存實現加速,php執行代碼的結果保存在nginx的緩存空間中,用戶再請求時就不會交給后端的php在執行了,而是直接從緩存返回給客戶端,這就相當于靜態資源了;httpd基于模塊也能緩存;
注意:
第一:緩存結果內容,有可能剛存下來,資源被刪了,客戶端請求時發現資源仍然可以響應,這樣就不真實了,所以,緩存要及時清理;
第二:緩存下來的內容,得有命中率,要有客戶端經常訪問,否則沒有意義;同一資源被多次請求的經歷;
nginx把緩存分為兩段:
首先在內存空間中保存緩存文件的元數據;然后在磁盤中保存元數據所指向的文件內容;所以,對于nginx緩存保存的是鍵值數據,把文件系統上的層級文件數據,轉換成Key-Value數據,key在內存中,value在磁盤中是一個個的文件對象;而文件的名字等信息是在內存中的;key也是分層級的但不同于文件系統的層級;k是文件的名字或是訪問的URL,而v是真正的數據;數據文件的名字是這個文件內容的校驗碼;
緩存下來的文件的文件名是文件內容做md5校驗計算后的校驗碼,md5校驗碼是128位二進制定長輸出;每四位二進制對應一個十六位進制數,以md5為例,128/4=32,即32個十六進制數;文件內容不同校驗碼就不同;把這些十六進制數字組成的文件名進行層級劃分;可把前兩個字符當作一級子目錄的名字,再兩字符當二級子目錄的名字,再一個字符當三級子目錄的名字;這樣意味著,一級子目錄有(兩個十六進制數字表示的個數)即256個,二級子目錄有256個。三級子目錄有16個;想要分幾級,就用多少個十六進制數所能劃分的個數來表示;
4、fastcgi_cache zone|off;
是否啟用cache功能,如果啟用,要提前定義緩存空間的名字;默認為off不緩存;
5、fastcgi_cache_key string;
定義要使用的緩存鍵;
例如:fastcgi_cache_key $request_uri
6、fastcgi_cache_methods GET | HEAD | POST …;
緩存哪些類型的請求的相關數據;是請求方法;
7、fastcgi_cache_min_uses number;
緩存最少使用次數;在指定時長內,如果小于此值就為非活動;
8、fastcgi_cache_valid [code …] time;
緩存數據時,對不同響應碼設定其可緩存的時長;
注意:調用緩存時,至少應該制定3個參數
fastcgi_cache
fastcgi_cache_key
fastcgi_cache_valid
例如:定義緩存,使用ab命令壓測試
]# ab -c 10 -n 100 https://172.18.11.114/info.php
平均響應請求為300個左右;
開啟nginx緩存功能:
]# vim /etc/nginx/nginx.conf
在http配置段:
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fcgicache:10m;
調用緩存:
location ~ \.php$ {
root html;
fastcgi_cache fcgicache;
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 1m;
fastcgi_cache_key $request_uri;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html/$fastcgi_script_name;
include fastcgi_params;
}
]# mkdir /var/cache/nginx/fastcgi -pv
]# nginx -s reload
在瀏覽器:https://www1.stu11.com/info.php 多次刷新頁面后,查看生成的緩存文件:
]# tree /var/cache/nginx/fastcgi/
]# ab -c 10 -n 100 https://172.18.11.114/info.php
有顯著提升,平均響應為400左右
ngx_http_ssl_module模塊:
ssl協議位于傳輸層和應用層之間的半層;應用層協議在開發時調用ssl功能,就能支持ssl,有些應用層協議在調用ssl時,可把ssl當做一個模塊,用到時就可以調用;就像httpd,可提供http服務,也可提供https服務;只不過,如果是基于rpm安裝方式時,需要
安裝mod_ssl模塊;
ssl協議是基于tcp通信的,經過tcp3次握手后,才能進行sslhandshake;
服務器發證書給客戶端,包括支持哪些加密算法,與客戶端協商;客戶端接收后證書后,要驗證證書持有者與訪問主機站點地址是否一致,證書的頒發機構是否是信任的機構,驗證證書的有效期,用CA公鑰解密數字簽名,用同樣的算法加密特征碼,對比是否一致,驗證CA的合法性;還要檢查證書吊銷列表;驗證通過后,才通信;但通信時,還要有密鑰交換的過程,用對方的公鑰加密選擇的一次性對稱密鑰,然后傳遞給對方,對方用私鑰解密后,就得出了密碼,然后就用這個密碼來加密客戶端請求的資源之后,將資源發送給客戶端,隨后就是ssl雙方之間的通信;
這個通信是基于ssl會話進行的,所有http報文在發送給tcp層之前,先交給ssl層,ssl層會把文本形式的報文,轉換為ssl報文,ssl報文是為二進制格式的;隨后才交給tcp層;因此基于ssl層的會話,可認為是在整個報文多了一層,即數據之外是應用層,應用層之外是ssl會話層,然后才是tcp層,最后經過封裝MAC發送;
運營商能截獲客戶端的訪問頁面,插入相關的鏈接或廣告,站點有可能都不知道;在cdn層次上分析客戶的訪問;因此,站點現在都做全站https,這樣,再運營商插入廣告,客戶就打不開網頁,從而,運營商為了滿足客戶端打開網頁的需求,就不能插入廣告了;
ssl會話是基于tcp隧道承載的一種協議,是在tcp建立連接之后,才建立的;而在拆除會話時,是先拆除ssl會話,再拆除tcp連接;
ssl加解密會給cpu帶來很大壓力;將來做服務器時,要做選型;軟硬件模型多服務器做壓測,要滿足業務需要;客戶端使用域名訪問服務器站點,通過DNS服務器解析返回一個請求的要訪問服務器ip地址,之后,客戶端就封裝http請求報文,http報文基于get方法,body部分一般是空的,再外面封裝的是http請求報文首部,當中有大多請求報文的header,其中有一個header叫做host,這個host給的就是在瀏覽器中鍵入的主機名;再封裝tcp等等;域名只在http請求報文首部才用到,而首部是在ssl會話內部的;所以兩臺主機間通信tcp會話是基于ip地址進行,ssl會話也是基于ip地址進行的;雙方身份識別是基于ip地址,而沒有用到主機名;所以,任何一臺服務器只有一個IP地址的主機,只能提供一個https的虛擬主機;但現在有個開源項目,能夠實現單臺主機使用多個https的虛擬主機;
灰度模型:服務器上線、下線一批一批來打補??;
1、ssl on|off;
是否啟用當前虛擬主機的ssl
手動測試時,可臨時關閉;
基于ip地址的ssl會話,在一個ip上進行只能一個虛擬主機ssl會話;
2、ssl_certificate file;
當前虛擬主機使用的PEM格式的證書文件;
3、ssl_certificate_key file;
指明私鑰文件;當前虛擬主機使用的證書文件中的公鑰配對兒的私鑰文件路徑,PEM格式;
4、ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
指明使用的ssl協議版本;最好使用TLSv1以上的版本;
5、ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
ssl會話創建非常消耗資源,能緩存下來對同一主機的多次請求,在有效時間內可不用建立ssl會話,基于緩存來實現;指明ssl會話的緩存機制;
off:禁止使用會話;堅決禁止;
none:禁止使用會話;溫和禁止;告訴客戶端會話有可能被重用,但并不保證;
builtin:使用openssl(加密的庫)內建的緩存機制,此為各worker獨占;
為每個worker進程在自己的空間中加載ssl相關庫,各worker是不共享的;每個worker自己獨立管理自己的ssl會話緩存;
缺陷:同一個用戶請求,第一個請求調度在第一個worker響應,第二個請求有可能被調度到第二個worker響應,這樣緩存有可能無法被命中;
shared:相對于builtin而言,ssl緩存是由各worker共享的緩存;緩存空間需要定義name,size等,每個共享必須有名字;共享的緩存由nginx進程所管理的一段內存空間,對于nginx,共享內存空間非常多,所以共享內存空間要有名字和空間大??;
name:緩存空間的名稱;每一段空間間必須有一個名字;
size:字節為單位的緩存空間的大小,每1MB內存空間可緩存4000個會話;10M空間就可緩存4萬個會話;一般只使用共享,效率會高些;多個虛擬主機可使用同一段緩存空間來緩存自己的ssl會話;
6、ssl_verify_client
是否驗證客戶端證書;一般不會驗證客戶端證書;
7、ssl_ciphers
加密算法,必須是Openssl所支持的加密算法才可以;
!(嘆號)表取反,+表示包含的算法;
使用openssl ciphers命令,可查看openssl支持哪些加密算法;
8、ssl_session_timeout;
ssl會話超時時長,指ssl會話緩存中緩存條目的有效時長(即非活動期限的有效時長);默認是5分鐘;
9、ssl_prefer_server_ciphers
當使用SSLv3和TLS協議時,優先使用服務器端的加密算法;傾向于使用服務器端的加密算法;
server {
listen 443 ssl; ————————-強制ssl會話
server_name localhost; ——————虛擬主機名
ssl_certificate cert.pem; —————–證書
ssl_certificate_key cert.key;————-私鑰
ssl_session_cache shared:SSL:1m; —-共享ssh緩存大小
ssl_session_timeout 5m; —————–會話ssl的超時時長
ssl_ciphers HIGH:!aNULL:!MD5; ——–ssl的加密算法
ssl_prefer_server_ciphers on; ———–傾向于使用服務器端的加密算法
location / {
root html;
index index.html index.htm;
}
nginx配置虛擬主機使用https示例:centos7系統:
創建私鑰,創建簽署證書請求:
]# mkdir ssl
]# (umask 077;openssl genrsa -out ssl/nginx.key 1024)
]# openssl req -new -key nginx.key -out nginx.csr -days 365
創建私有CA:
]# cd /etc/pki/CA/
創建CA私鑰,創建CA自簽證書:
]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
創建CA必要文件:
]# touch index.txt
]# echo 01 > serial
CA簽署證書請求:
]# openssl ca -in /etc/nginx/ssl/nginx.csr -out /etc/nginx/ssl/nginx.crt -days 365
配置nginx配置文件
]# vim /etc/nginx/nginx.conf
server {
listen 443 ssl;
server_name www1.stu11.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;
}
}
在瀏覽器輸入:https://www1.stu11.com
原創文章,作者:Lii,如若轉載,請注明出處:http://www.www58058.com/54476