安裝和配置 Nginx

一、安裝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配置項

塊配置項

上面代碼段中的eventshttp都是塊配置項。所有的事件類配置都要在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會話信息,不能在保存到服務器上

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