文章目錄
一、安裝Nginx
本文環境是CentOS Linux release 7.3.1611 (Core)
cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
1: 添加 yum 源
Nginx 不在默認的 yum 源中,可以使用 epel 或者官網的 yum 源,本例使用官網的 yum 源。
sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
安裝完 yum 源之後,可以查看一下
yum repolist
2. 安裝
yum 安裝 Nginx,非常簡單,一條命令。
sudo yum install nginx
3. 配置 Nginx 服務
## 設置開機啓動
sudo systemctl enable nginx
## 啓動服務
sudo systemctl start nginx
## 停止服務
sudo systemctl restart nginx
## 重新加載,因爲一般重新配置之後,不希望重啓服務,這時可以使用重新加載。
sudo systemctl reload nginx
4. 打開防火牆端口
默認 CentOS7 使用的防火牆 firewalld 是關閉 http 服務的(打開 80 端口)。
$ sudo firewall-cmd --zone=public --permanent --add-service=http
success
$ sudo firewall-cmd --reload
success
打開之後,可以查看一下防火牆打開的所有的服務
sudo firewall-cmd --list-service
ssh dhcpv6-client http
可以看到,系統已經打開了 http 服務
5. 查看和修改nginx文件
ls /etc/nginx
conf.d fastcgi_params koi-utf koi-win mime.types modules
nginx.conf scgi_params uwsgi_params win-utf
二、配置Nginx
1. Nginx常用功能
- 反向代理
- 負載均衡
- web緩存
2. 使用Nginx的必備工具
2.1 GCC & G++編譯器
sudo yum install -y gcc
sudo yum install -y g++
2. 2 PCRE庫
兼容正則表達式(PCRE)。在配置nginx時如果使用了正則表達式,就需要將PCRE庫編譯進nginx。pcre-devel是使用PCRE做二次開發時所需要的開發庫,包括頭文件等,這也是編譯Nginx所必須使用的。PCRE庫安裝方法如下:
sudo yum install -y pcre pcre-devel
2.3 zlib
zlib庫用於對HTTP包的內容做gzip格式的壓縮
,如果我們在nginx.conf裏配置了gzip on,並指定對於某些類型(content-type
)的HTTP響應使用gzip來進行壓縮以減少網絡傳輸量,那麼,在編譯時就必須把zlib編譯進Nginx。其安裝方式如下:
sudo yum install -y zlib zlib-devel
2.4 OpenSSL開發庫
如果我們的服務器不只是要支持HTTP,還需要在更安全的SSL協議上傳輸HTTP,那麼
就需要擁有OpenSSL了。另外,如果我們想使用MD5、SHA1等散列函數,那麼也需要安裝它。其yum安裝方式如下:
sudo yum install -y openssl openssl-devel
2.5 磁盤目錄
要使用Nginx,還需要在Linux文件系統上準備以下目錄。
a. Nginx源代碼存放目錄
該目錄用於放置從官網上下載的Nginx源碼文件,以及第三方或我們自己所寫的模塊源代碼文件。
b. Nginx編譯階段產生的中間文件存放目錄
該目錄用於放置在configure命令執行後所生成的源文件及目錄,以及make命令執行後生成的目標文件和最終連接成功的二進制文件。默認情況下,configure命令會將該目錄命名爲objs,並放在Nginx源代碼目錄下。
c. 部署目錄
該目錄存放實際Nginx服務運行期間所需要的二進制文件、配置文件等。默認情況下,該目錄爲 /usr/local/nginx
。
d. 日誌文件存放目錄
日誌文件通常會比較大,當研究Nginx的底層架構時,需要打開debug級別的日誌,這個級別的日誌非常詳細,會導致日誌文件的大小增長得極快,需要預先分配一個擁有更大磁盤空間的目錄。
小結
Nginx是高度自由化的Web服務器,它的功能是由許多模塊來支持的。而這些模塊可根據
我們的使用需求來定製,如果某些模塊不需要使用則完全不必理會它。同樣,如果使用了某個模塊,而這個模塊使用了一些類似zlib或OpenSSL等的第三方庫,那麼就必須先安裝這些軟件。
3. Linux內核優化
由於默認的Linux內核參數考慮的是最通用的場景,這明顯不符合用於支持高併發訪問的Web服務器的定義,所以需要修改Linux內核參數,使得Nginx可以擁有更高的性能。
在優化內核時,可以做的事情很多,不過,我們通常會根據業務特點來進行調整,當Nginx作爲靜態Web內容服務器、反向代理服務器或是提供圖片縮略圖功能(實時壓縮圖片的服務器時,其內核參數的調整都是不同的。這裏只針對最通用的、使Nginx支持更多併發請求的TCP網絡參數做簡單說明
。
首先,需要修改/etc/sysctl.conf來更改內核參數。例如,最常用的配置:
# 這個參數表示進程(比如一個worker進程)可以同時打開的最大句柄數
# 這個參數直接限制最大併發連接數,需根據實際情況配置
fs.file-max = 999999
# 這個參數設置爲1,表示允許將TIME-WAIT狀態的socket重新用於新的
# TCP連接,這對於服務器來說很有意義,因爲服務器上總會有大量TIME-WAIT狀態的連接
net.ipv4.tcp_tw_reuse = 1
#這個參數表示當keepalive啓用時,TCP發送keepalive消息的頻度。
# 默認是2小時,若將其設置得小一些,可以更快地清理無效的連接
net.ipv4.tcp_keepalive_time = 600
# 這個參數表示當服務器主動關閉連接時,socket保持在FIN-WAIT-2狀
# 態的最大時間。
net.ipv4.tcp_fin_timeout = 30
#v這個參數表示操作系統允許TIME_WAIT套接字數量的最大值,
# 如果超過這個數字,TIME_WAIT套接字將立刻被清除並打印警告信息。該參數默認爲
# 180000,過多的TIME_WAIT套接字會使Web服務器變慢
net.ipv4.tcp_max_tw_buckets = 5000
# 定義了在UDP和TCP連接中本地(不包括連接的遠端)端口的取值範圍。
net.ipv4.ip_local_port_range = 1024 61000
# 定義了TCP接收緩存(用於TCP接收滑動窗口)的
# 最小值、默認值、最大值。
net.ipv4.tcp_rmem = 4096 32768 262142
# 定義了TCP發送緩存(用於TCP發送滑動窗口)的
# 最小值、默認值、最大值。
net.ipv4.tcp_wmem = 4096 32768 262142
# 當網卡接收數據包的速度大於內核處理的速度時,會有一個隊列
# 保存這些數據包。這個參數表示該隊列的最大值。
net.core.netdev_max_backlog = 8096
# 表示內核套接字接收緩存區默認的大小。
net.core.rmem_default = 262144
# 表示內核套接字發送緩存區默認的大小。
net.core.wmem_default = 262144
# 表示內核套接字接收緩存區的最大大小
net.core.rmem_max = 2097152
# 表示內核套接字發送緩存區的最大大小
net.core.wmem_max = 2097152
# tcp_syncookies性能無關,用於解決TCP的SYN攻擊
net.ipv4.tcp_syncookies = 1
# 表示TCP三次握手建立階段接收SYN請求隊列的最大
# 長度,默認爲1024,將其設置得大一些可以使出現Nginx繁忙來不及accept新連接的情況時,
# Linux不至於丟失客戶端發起的連接請求
net.ipv4.tcp_max_syn.backlog=1024
使上述修改生效,需要執行以下命令:
sysctl-p
3. Nginx配置
Nginx擁有大量官方發佈的模塊和第三方模塊,這些已有的模塊可以幫助我們實現Web服務器上很多的功能。使用這些模塊時,僅僅需要增加、修改一些配置項即可。
3.1 運行中的Nginx進程間的關係
在正式提供服務的產品環境下,部署Nginx時都是使用一個master進程
來管理多個worker進程
,一般情況下,worker進程的數量與服務器上的CPU核心數相等
。每一個worker進程都是繁忙的,它們在真正地提供互聯網服務,master進程
則很“清閒”,只負責監控管理worker進程
。worker進程之間通過共享內存、原子操作等一些進程間通信機制來實現負載均衡等功能。
Nginx是支持單進程(master進程)提供服務而,那麼爲什麼要按照worker方式配置同時啓動多個進程呢?原因如下:
- 由於
master進程不會對用戶請求提供服務,只用於管理真正提供服務的worker進程
,所以master進程可以是唯一的,它僅專注於自己的純管理工作,爲管理員提供命令行服務,包括諸如啓動服務、停止服務、重載配置文件、平滑升級程序等 master進程需要擁有較大的權限
,例如,通常會利用root用戶啓動master進程。worker進程的權限要小於或等於master進程
,這樣master進程纔可以完全地管理worker進程。當任意一個worker進程出現錯誤從而導致coredump時,master進程會立刻啓動新的worker進程繼續服務。·- 多個worker進程處理互聯網請求不但可以提高服務的
健壯性
(一個worker進程出錯後,其他worker進程仍然可以正常提供服務),最重要的是,這樣可以充分利用現在常見的SMP多核架構,從而實現微觀上真正的多核併發處理。因此,用一個進程(master進程)來處理互聯網請求肯定是不合適的。
另外,爲什麼要把worker進程數量設置得與CPU核心數量一致呢?
- 這正是Nginx與Apache服務器的不同之處。在Apache上每個進程在一個時刻只處理一個請求,因此,如果希望Web服務器擁有併發處理的請求數更多,就要把Apache的進程或線程數設置得更多,通常會達到一臺服務器擁有幾百個工作進程,這樣大量的進程間切換將帶來無謂的系統資源消耗。
- Nginx則不然,
一個worker進程可以同時處理的請求數只受限於內存大小
,而且在架構設計上,不同的worker進程之間處理併發請求時幾乎沒有同步鎖的限制,worker進程通常不會進入睡眠狀態,因此,當Nginx上的進程數與CPU核心數相等時(最好每一個worker進程都綁定特定的CPU核心),進程間切換的代價是最小的。
nginx進程間的關係如下圖所示:
3.2 Nginx配置的通用語法
Nginx的配置文件其實是一個普通的文本文件。下面是nginx默認的配置文件:
[root]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
3.2.1 認識nginx配置項
塊配置項
上面代碼段中的events
、http
都是塊配置項
。所有的事件類配置都要在events塊中,http、server等配置也遵循這個規定。
單位
當指定空間大小時,可以使用的單位包括:
- K或者k千字節(KiloByte,KB)
- M或者m兆字節(MegaByte,MB)
當指定時間時,可以使用的單位包括:
·ms(毫秒),s(秒),m(分鐘),h(小時),d(天),w(周,包含7天),
M(月,包含30天),y(年,包含365天)。
在配置中使用變量
有些模塊允許在配置項中使用變量,如在日誌記錄部分,具體示例如下
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
其中,remote_addr是一個變量
,使用它的時候前面要加上$
符號。需要注意的是,這種變量只有少數模塊支持,並不是通用的
。
3.2.2 常用配置項
(1)優化性能的配置項
#Nginx worker進程個數. 默認爲1
worker_processes number
# 綁定Nginx worker進程到指定的CPU內核
# 如果每一個worker進程都獨享一個CPU,就在內核的調度策略上實現了完全的併發。
# worker_cpu_affinity cpumask[cpumask...]
worker_cpu_affinity 1000 0100 0010 0001 # 4核CPU
# SSL硬件加速
# 如果服務器上有SSL硬件加速設備,那麼就可以進行配置以加快SSL協議的處理速度。
ssl_engine device
# 內核的事件調用(epoll、select等)返回時,都會執行一次gettimeofday
# timer_resolution可以改變gettimeofday的執行頻率.
# 至少每t ms才調用一次gettimeofday
timer_resolution t
# Nginx worker進程優先級設置
worker_priority nice # 默認爲0
# 使用OpenSSL提供的命令來查看是否有SSL硬件加速設備
[root@calm-boot-3 ~]# openssl engine -t
(rdrand) Intel RDRAND engine
[ available ]
(dynamic) Dynamic engine loading support
[ unavailable ]
(2) event事件類配置項
# 是否打開accept鎖.accept_mutex是Nginx的負載均衡鎖
accept_mutex [on|off] # 默認 accept_mutext on;
# lock文件的路徑
# accept鎖可能需要這個lock文件,如果accept鎖關閉,lock_file配置完全不生效。
lock_file path/file # 默認lock_file logs/nginx.lock;
# 用accept鎖後到真正建立連接之間的延遲時間
accept_mutex_delay Nms; # 默認500ms
# 每個worker的最大連接數
worker_connections number
# 批量建立新連接。當事件模型通知有新連接時,
# 儘可能地對本次調度中客戶端發起的所有TCP請求都建立連接。
multi_accept[on|off] # 默認off
4. 用HTTP核心模塊配置一個靜態Web服務器
靜態Web服務器的主要功能由ngx_http_core_module模塊
(HTTP框架的主要成員)實現,當然,一個完整的靜態Web服務器還有許多功能是由其他的HTTP模塊實現的。
除了上文提到的基本配置項外,一個典型的靜態Web服務器還會包含多個server
塊和
location
塊。
Nginx爲配置一個完整的靜態Web服務器提供了非常多的功能,下面會把這些配置項分爲以下8類進行詳述:虛擬主機與請求的分發、文件路徑的定義、內存及磁盤資源的分配、網絡連接的設置、MIME類型的設置、對客戶端請求的限制、文件操作的優化、對客戶端請求的特殊處理。這種劃分只是爲了幫助大家從功能上理解這些配置項。
4.1 虛擬主機與請求的分發
由於IP地址的數量有限,因此經常存在多個主機域名對應着同一個IP地址
的情況,這時在nginx.conf中就可以按照server_name(對應用戶請求中的主機域名)並通過server塊來定義虛擬主機,每個server塊就是一個虛擬主機
,它只處理與之相對應的主機域名請求。這樣,一臺服務器上的Nginx就能以不同的方式處理訪問不同主機域名的HTTP請求
了。
(1)監聽端口
- 語法: listen address:port[default_server| backlog=num| rcvbuf=size|sndbuf=size| accept_filter=filter|deferred|bind|ipv6only=[on|off]|ssl]];
- 默認: listen 80;
- 配置塊:server
listen參數決定Nginx服務如何監聽端口。在listen後可以只加IP地址、端口或主機名,非
常靈活,例如:
server {
listen 127.0.0.1:8000; #注意:不加端口時,默認監聽80
# 在地址和端口後,還可以加上其他參數,例如:
listen 443 default_server ssl;
listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;
}
下面說明listen可用參數的意義。
-
default_server:將所在的server塊作爲整個Web服務的默認server塊。如果沒有設置這個參數,那麼將會以在nginx.conf中找到的第一個server塊作爲默認server塊。爲什麼需要默認虛擬主機呢?當一個請求無法匹配配置文件中的所有主機域名時,就會選用默認的虛擬主機
-
backlog=num:表示TCP中backlog隊列的大小。默認爲–1,表示不予設置。在TCP建立三次握手過程中,進程還沒有開始處理監聽句柄,這時backlog隊列將會放置這些新連接。可如果backlog隊列已滿,還有新的客戶端試圖通過三次握手建立TCP連接,這時客戶端將會建立連接失敗。
-
rcvbuf=size:設置監聽句柄的SO_RCVBUF參數。
-
sndbuf=size:設置監聽句柄的SO_SNDBUF參數。
-
accept_filter:設置accept過濾器,只對FreeBSD操作系統有用。
-
deferred:在設置該參數後,若用戶發起建立連接請求,並且完成了TCP的三次握手,內核也不會爲了這次的連接調度worker進程來處理,只有用戶真的發送請求數據時(內核已經在網卡中收到請求數據包),內核纔會喚醒worker進程處理這個連接。這個參數適用於大併發的情況下,它
減輕了worker進程的負擔
。當請求數據來臨時,worker進程纔會開始處理這個連接
。只有確認上面所說的應用場景符合自己的業務需求時,纔可以使用deferred配置。 -
bind:綁定當前端口/地址對,如127.0.0.1:8000。只有
同時對一個端口監聽多個地址時 纔會生效
。 -
ssl:在當前監聽的端口上建立的連接必須基於SSL協議。
(2)主機名稱
- 語法: server_name name[…];
- 默認: server_name " ";
- 配置塊: server
server_name後可以跟多個主機名稱,如:
server_name www.testweb.com 、www.testweb.com;
在開始處理一個HTTP請求時,Nginx會取出header頭中的Host,與每個server中的server_name進行匹配,以此決定到底由哪一個server塊來處理這個請求
。有可能一個Host與多個server塊中的server_name都匹配,這時就會根據匹配優先級
來選擇實際處理的server塊。server_name與Host的匹配優先級如下:
1)首先選擇所有字符串完全匹配的server_name,如www.testweb.com 。
2)其次選擇通配符在前面的server_name,如*.testweb.com。
3)再次選擇通配符在後面的server_name,如www.testweb.* 。
4)最後選擇使用正則表達式才匹配的server_name,如~^.testweb.com$。
Nginx正是使用server_name配置項針對特定Host域名的請求提供不同的服務,
以此實現虛擬主機功能。
(3) server_names_hash_bucket_size
- 語法: server_names_hash_bucket_size size;
- 默認: server_names_hash_bucket_size 32|64|128;
- 配置塊: http、server、location
爲了提高快速尋找到相應server name的能力,Nginx使用散列表來存儲server name
。
server_names_hash_bucket_size設置了每個散列桶佔用的內存大小。
(4) server_names_hash_max_size
- 語法: server_names_hash_max_size size;
- 默認: server_names_hash_max_size 512;
- 配置塊: http、server、location
server_names_hash_max_size會影響散列表的衝突率。server_names_hash_max_size越大,消耗的內存就越多,但散列key的衝突率則會降低,檢索速度也更快。server_names_hash_max_size越小,消耗的內存就越小,但散列key的衝突率可能增高。
(5)重定向主機名稱的處理
語法: server_name_in_redirect on|off;
默認: server_name_in_redirect on;
配置塊: http、server或者location
該配置需要配合server_name使用。在使用on打開時,表示在重定向請求時會使用server_name裏配置的第一個主機名代替原先請求中的Host頭部,而使用off關閉時,表示在重定向請求時使用請求本身的Host頭部。
(6)location
- 語法: location[=||*|^~|@]/uri/{…}
- 配置塊: server
location會嘗試根據用戶請求中的URI來匹配上面的/uri表達式,如果可以匹配,就選擇location{}塊中的配置來處理用戶請求。
~
表示匹配URI時是字母大小寫敏感的。~*
表示匹配URI時忽略字母大小寫問題。^~
表示匹配URI時只需要其前半部分與uri參數匹配即可。例如:location ^~ images { # 以images開始的請求都會匹配上 }
@
表示僅用於Nginx服務內部請求之間的重定向,帶有@的location不直接處理用戶請求- 在uri參數裏是可以用正則表達式的。當一個請求有可能匹配多個location時,實際上這個請求會被第一個location處理。
在以上各種匹配方式中,都只能表達爲“如果匹配…則…”。如果需要表達“如果不匹配…則…”,就很難直接做到。有一種解決方法是在最後一個location中使用/作爲參數,它會匹配所有的HTTP請求
,這樣就可以表示如果不能匹配前面的所有location,則由“/”這個location處理。
4.2 文件路徑的定義
先看個常用的配置。這裏配置完後如果訪問返回404, 則需要修改配置文件(/etc/nginx/nginx.conf
)。這是因爲nginx是由root用戶安裝創建,但是配置文件默認是user nginx;改爲user root即可正常訪問靜態圖片資源。
server {
location / {
proxy_pass http://localhost:8080/;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
(1)以root方式設置資源路徑
- 語法: root path;
- 默認: root html;
- 配置塊: http、server、location、if
例如,定義資源文件相對於HTTP請求的根目錄。
location /download/ {
root optwebhtml;
}
在上面的配置中,如果有一個請求的URI是/download/index/test.html,那麼Web服務器將會返回服務器上optwebhtmldownload/index/test.html文件的內容。
(2)以alias方式設置資源路徑
- 語法: alias path;
- 配置塊: location
alias也是用來設置文件資源路徑的,它與root的不同點主要在於如何解讀緊跟location後面的uri參數
,這將會致使alias與root以不同的方式將用戶請求映射到真正的磁盤文件上。例如,如果有一個請求的URI是/conf/nginx.conf,而用戶實際想訪問的文件在usrlocal/nginx/conf/nginx.conf
,那麼想要使用alias來進行設置的話,可以採用如下方式:
location conf {
alias usr/local/nginx/conf/;
}
如果用root設置,那麼語句如下所示:
location conf {
root usr/local/nginx/;
}
(3)訪問首頁
- 語法: index file…;
- 默認: index index.html;
- 配置塊: http、server、location
有時,訪問站點時的URI是/,這時一般是返回網站的首頁,而這與root和alias都不同。這裏用ngx_http_index_module
模塊提供的index配置實現。index後可以跟多個文件參數,Nginx將會按照順序來訪問這些文件。
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
上面配置nginx收到請求後,先去找index.html文件,如果有,則停止向後查找。如果沒有,則向後查找直到找到一個存在的文件。
(4)根據HTTP返回碼重定向頁面
- 語法: error_page code[code…][=|=answer-code]uri|@named_location
- 配置塊: http、server、location、if
當對於某個請求返回錯誤碼時,如果匹配上了error_page中設置的code,則重定向到新的URI中
。
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
4.3 內存及磁盤資源的分配
下面介紹處理請求時內存、磁盤資源分配的配置項。
(1)HTTP包體只存儲到磁盤文件中
- 語法:
client_body_in_file_only
on|clean|off; - 默認: client_body_in_file_only
off
; - 配置塊: http、server、location
當值爲非off時,用戶請求中的HTTP包體一律存儲到磁盤文件中
,即使只有0字節也會存儲爲文件。當請求結束時,如果配置爲on,則這個文件不會被刪除(該配置一般用於調試、定位問題
),但如果配置爲clean,則會刪除該文件。
(2)HTTP包體儘量寫入到一個內存buffer中
- 語法:
client_body_in_single_buffer
on|off; - 默認: client_body_in_single_buffer
off
; - 配置塊: http、server、location
用戶請求中的HTTP包體一律存儲到內存buffer中。當然,如果HTTP包體的大小超過了下面client_body_buffer_size設置的值,包體還是會寫入到磁盤文件中。
(3)存儲HTTP頭部的內存buffer大小
- 語法:
client_header_buffer_size
size; - 默認: client_header_buffer_size
1k
; - 配置塊: http、server
上面配置項定義了正常情況下Nginx接收用戶請求中HTTP header部分(包括HTTP行和HTTP頭部)時分配的內存buffer大小。有時,請求中的HTTP header部分可能會超過這個大小,這時large_client_header_buffers定義的buffer將會生效。
(4)存儲超大HTTP頭部的內存buffer大小
- 語法:
large_client_header_buffers number
size; - 默認: large_client_header_buffers
48k
; - 配置塊: http、server
large_client_header_buffers定義了Nginx接收一個超大HTTP頭部請求的buffer個數和每個buffer的大小。如果HTTP請求行(如GET/index HTTP/1.1)的大小超過上面的單個buffer,則返回"Request URI too large"(414)。請求中一般會有許多header,每一個header的大小也不能超過單個buffer的大小,否則會返回"Bad request"(400)。當然,請求行和請求頭部的總和也不可以超過buffer個數*buffer大小。
(5)connection_pool_size
- 語法:
connection_pool_size
size; - 默認: connection_pool_size
256
; - 配置塊: http、server
Nginx對於每個建立成功的TCP連接會預先分配一個內存池
,上面的size配置項將指定這個內存池的初始大小
(即ngx_connection_t結構體中的pool內存池初始大小),用於減少內核對於小塊內存的分配次數。需慎重設置,因爲更大的size會使服務器消耗的內存增多,而更小的size則會引發更多的內存分配次數。
(6)request_pool_size
- 語法: request_pool_size size;
- 默認: request_pool_size
4k
; - 配置塊: http、server
Nginx開始處理HTTP請求時,將會爲每個請求都分配一個內存池
,size配置項將指定這
個內存池的初始大小。
三、Nginx反向代理
1. 什麼是反向代理
當我們在外網訪問百度的時候,其實會進行一個轉發,代理到內網去,這就是所謂的反向代理,即反向代理“代理”的是服務器端,而且這一個過程對於客戶端而言是透明的。
2. 反向代理部署
Nginx的核心功能——反向代理是基於upstream模塊
(該模塊屬於HTTP框架的一部分)實現的。在弄清楚upstream的用法後,完全可以根據自己的需求重寫Nginx的反向代理功能。
例如,反向代理模塊是在先接收完客戶請求的HTTP包體後,才向上遊服務器建立連接並轉發請求的。假設用戶要上傳大小爲1GB的文件,由於網速限制,文件完整地到達Nginx需要10小時,恰巧Nginx與上游服務器間的網絡也很差(當然這種情況很少見),反向代理這個請求到上游服務也需要10小時,因此,根據用戶的網速也許本來只要10個小時的上傳過程,最終可能需要20個小時才能完成。
在瞭解了upstream功能後,可以試着改變反向代理模塊的這種特性,比如模仿squid反向代理模式,在接收完整HTTP請求的頭部後就與上游服務器建立連接,並開始將請求向上遊服務器透傳。upstream的使用方式並不複雜,它提供了8個回調方法,用戶只需要視自己的需要實現其中幾個回調方法就可以了。在瞭解這8個回調方法之前,首先要了解upstream是如何嵌入到一個請求中的。
啓動upstream的流程如下所示:
upstream執行的一般流程:
3. 修改配置文件實現反向代理
其實就是在location這一段配置中的root替換成proxy_pass即可。root說明是靜態資源,可以由Nginx進行返回;而proxy_pass說明是動態請求,需要進行轉發,比如代理到Tomcat上。
server {
location / {
proxy_pass http://localhost:8080/;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
反向代理,上面已經說了,過程是透明的,比如說request -> Nginx -> Tomcat,那麼對於Tomcat而言,請求的IP地址就是Nginx的地址,而非真實的request地址,這一點需要注意。不過好在Nginx不僅僅可以反向代理請求,還可以由用戶自定義設置HTTP HEADER。
四、Nginx負載均衡
上面的反向代理中,我們通過proxy_pass來指定Tomcat的地址,很顯然我們只能指定一臺Tomcat地址,那麼我們如果想指定多臺來達到負載均衡呢?
第一,通過upstream來定義一組Tomcat,並指定負載策略(IPHASH、加權論調、最少連接),健康檢查策略(Nginx可以監控這一組Tomcat的狀態)等。
第二,將proxy_pass替換成upstream指定的值即可。
負載均衡可能帶來的問題
負載均衡所帶來的明顯的問題是,一個請求,可以到A server,也可以到B server,這完全不受我們的控制,當然這也不是什麼問題,只是我們得注意的是:用戶狀態的保存問題,如Session會話信息,不能在保存到服務器上
。