天天看點

Nginx反向代理+Nginx性能優化配置詳解

前言:

代理服務可簡單的分為正向代理和反向代理:

正向代理: 用于代理内部網絡對Internet的連接配接請求(如VPN/NAT),用戶端指定代理伺服器,并将本來要直接發送給目标Web伺服器的HTTP請求先發送到代理伺服器上,然後由代理伺服器去通路Web伺服器, 并将Web伺服器的Response回傳給用戶端:

反向代理: 與正向代理相反,如果區域網路向Internet提供資源,并讓Internet上的其他使用者可以通路區域網路内資源, 也可以設定一個代理伺服器, 它提供的服務就是反向代理. 反向代理伺服器接受來自Internet的連接配接,然後将請求轉發給内部網絡上的伺服器,并将Response回傳給Internet上請求連接配接的用戶端:

(1.)反向代理(Reverse Proxy)方式是指以代理伺服器來接受用戶端的連接配接請求,然後将請求轉發給網絡上的web伺服器(可能是apache、nginx、tomcat、iis等),并将從web伺服器上得到的結果傳回給請求連接配接的用戶端,此時代理伺服器對外就表現為一個伺服器。

從上圖可以看出:反向代理伺服器代理網站Web伺服器接收Http請求,對請求進行轉發。而且nginx作為反向代理伺服器可以根據使用者請求的内容把請求轉發給後端不同的web伺服器,例如靜動分離,再例如在nginx上建立多個虛拟主機,這樣就成功的做到了在浏覽器中輸入不同域名(url)的時候通路後端的不同web伺服器或web群集。

(2.)反向代理的作用

保護網站安全:任何來自Internet的請求都必須先經過代理伺服器;

通過配置緩存功能加速Web請求:可以緩存真實Web伺服器上的某些靜态資源,減輕真實Web伺服器的負載壓力;

實作負載均衡:充當負載均衡伺服器均衡地分發請求,平衡叢集中各個伺服器的負載壓力;

Nginx是一款輕量級的網頁伺服器、反向代理器以及電子郵件代理伺服器。因它的穩定性、豐富的功能集、示例配置檔案和低系統資源的消耗而聞名。Nginx(發音同engine x),它是由俄羅斯程式員Igor Sysoev所開發的。起初是供俄國大型的門戶網站及搜尋引擎Rambler(俄語:Рамблер)使用。此軟體BSD-like協定下發行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及Microsoft Windows等作業系統中運作。

Nginx的應用現狀:

Nginx 已經在俄羅斯最大的門戶網站── Rambler Media(www.rambler.ru)上運作,同時俄羅斯超過20%的虛拟主機平台采用Nginx作為反向代理伺服器。

在國内,已經有淘寶、新浪部落格、新浪播客、網易新聞、六間房、56.com、Discuz!、水木社群、豆瓣、YUPOO、海内、迅雷線上等多家網站使用 Nginx 作為Web伺服器或反向代理伺服器。

跨平台:Nginx 可以在大多數OS編譯運作,而且也有Windows的版本;

配置異常簡單:非常容易上手。

非阻塞、高并發連接配接:官方測試能夠支撐5萬并發連接配接,在實際生産環境中跑到2~3萬并發連接配接數。(這得益于Nginx使用了最新的epoll模型);

注意:

對于一個Web伺服器來說,首先看一個請求的基本過程:建立連接配接—接收資料—發送資料,在系統底層看來:上述過程(建立連接配接—接收資料—發送資料)在系統底層就是讀寫事件。

如果采用阻塞調用的方式,當讀寫事件沒有準備好時,那麼就隻能等待,目前線程被挂起,等事件準備好了,才能進行讀寫事件。

如果采用非阻塞調用的方式:事件馬上傳回,告訴你事件還沒準備好呢,過會再來吧。過一會,再來檢查一下事件,直到事件準備好了為止,在這期間,你就可以先去做其它事情,然後再來看看事件好了沒。雖然不阻塞了,但你得不時地過來檢查一下事件的狀态,你可以做更多的事情了,但帶來的開銷也是不小的。非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞目前線程

事件驅動:通信機制采用epoll模型,支援更大的并發連接配接。

非阻塞通過不斷檢查事件的狀态來判斷是否進行讀寫操作,這樣帶來的開銷很大,是以就有了異步非阻塞的事件處理機制。這種機制讓你可以同時監控多個事件,調用他們是非阻塞的,但可以設定逾時時間,在逾時時間之内,如果有事件準備好了,就傳回。這種機制解決了上面阻塞調用與非阻塞調用的兩個問題。

以epoll模型為例:當事件沒有準備好時,就放入epoll(隊列)裡面。如果有事件準備好了,那麼就去處理;當事件沒有準備好時,才在 epoll裡面等着。這樣,我們就可以并發處理大量的并發了,當然,這裡的并發請求,是指未處理完的請求。線程隻有一個,是以同時能處理的請求當然隻有一個了,隻是在請求之間進行不斷地切換而已,切換也是因為異步事件未準備好,而主動讓出的。這裡的切換是沒有任何代價,你可以了解為循環處理多個準備好的事件。

多線程方式相比,這種事件處理方式是有很大的優勢的,不需要建立線程,每個請求占用的記憶體也很少,沒有上下文切換,事件處理非常的輕量級,并發數再多也不會導緻無謂的資源浪費(上下文切換)。對于apache伺服器,每個請求會獨占一個工作線程,當并發數上到幾千時,就同時有幾千的線程在處理請求了。這對作業系統來說,是個不小的挑戰:因為線程帶來的記憶體占用非常大,線程的上下文切換帶來的cpu開銷很大,自然性能就上不去,進而導緻在高并發場景下性能下降嚴重。

總結:通過異步非阻塞的事件處理機制,Nginx實作由程序循環處理多個準備好的事件,進而實作高并發和輕量級。

Master/Worker結構:一個master程序,生成一個或多個worker程序。注意:

Master-Worker設計模式主要包含兩個主要元件Master和Worker,Master維護着Worker隊列,将請求下發到多個Worker并行執行,Worker主要進行實際邏輯計算,并将結果傳回給Master。

nginx采用這種程序模型有什麼好處?采用獨立的程序,可以讓互相之間不會影響,一個程序退出後,其它程序還在工作,服務不會中斷,Master 程序則很快重新啟動新的Worker程序。當然,Worker程序的異常退出,肯定是程式有bug了,異常退出,會導緻目前Worker上的所有請求失敗,不過不會影響到所有work請求,是以降低了風險。

記憶體消耗小:處理大并發的請求記憶體消耗非常小。在3萬并發連接配接下,開啟的10個Nginx 程序才消耗150M記憶體(15M*10=150M)。

内置的健康檢查功能:如果 Nginx 代理的後端的某台 Web 伺服器當機了,不會影響前端通路。

節省帶寬:支援 GZIP 壓縮,可以添加浏覽器本地緩存的 Header 頭。

穩定性高:用于反向代理,當機的機率微乎其微。

nginx配置反向代理

配置nginx作為反向代理和負載均衡,同時利用其緩存功能,将靜态頁面放在nginx上緩存,以達到降低後端伺服器連接配接數的目的并檢查後端web伺服器的健康狀況。

環境:

OS:centos7.2

nginx:192.168.197.169

apache1:192.168.197.167

apache2:192.168.197.168

本人聲明:由于之前已經介紹過安裝Apache服務,是以這裡不再一一講解:

如果想看Apache詳細的安裝過程,請點選下面的連結即可:

(1.)安裝zlib-devel、pcre-devel等Nginx相關依賴包以及gcc編譯環境

yum -y install gcc gcc-c++ make libtool zlib zlib-devel pcre pcre-devel openssl openssl-devel

結合proxy和upstream子產品實作後端web負載均衡

使用proxy子產品實作靜态檔案緩存

結合nginx預設自帶的 ngx_http_proxy_module 子產品 和ngx_http_upstream_module子產品實作後端伺服器的健康檢查,也可以使用第三方子產品nginx_upstream_check_module

使用nginx-sticky-module擴充子產品實作Cookie會話黏貼(保持會話)

使用ngx_cache_purge實作更強大的緩存清除功能

上面提到的2個子產品都屬于第三方擴充子產品,需要提前下好源碼,然後編譯時通過–add-moudle=src_path一起安裝。

(2.)建立Nginx使用者群組,并且把使用者加入到組裡不讓使用者在控制台登入

[root@kang ~]# groupadd www

[root@kang ~]# useradd -g www www -s /sbin/nologin

(3.)編譯安裝Nginx

可以到官網去下載下傳最新版本Nginx:http://nginx.org/download/nginx-1.13.8.tar.gz

本章使用的是nginx-1.10.2.tar.gz版本來示範:

#tar zxf nginx-1.10.2.tar.gz

#tar zxf ngx_cache_purge-2.3.tar.gz

#tar zxf master.tar.gz

[root@kang ~]# tar zxf nginx-1.10.2.tar.gz

[root@kang ~]# tar zxf ngx_cache_purge-2.3.tar.gz

[root@kang ~]# tar zxf master.tar.gz

[root@kang ~]# cd nginx-1.10.2/

[root@kang nginx-1.10.2]#

注意:nginx的所有子產品必須在編譯的時候添加,不能再運作的時候動态加載。

[root@kang nginx-1.10.2]# ./configure --prefix=/usr/local/nginx1.10 --user=www --group=www --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --add-module=…/ngx_cache_purge-2.3 --with-http_flv_module --add-module=…/nginx-goodies-nginx-sticky-module-ng-08a395c66e42

[root@kang nginx-1.10.2]# make && make install

(4.)優化nginx程式的執行路徑

[root@kang nginx-1.10.2]# ln -s /usr/local/nginx1.10/sbin/nginx /usr/local/sbin/

(5.)檢測Nginx服務是否有錯誤

[root@kang nginx-1.10.2]# nginx -t

發現報如下錯誤資訊:

(6.)那是因為沒有那個指定的目錄,是以接下來建立指定的目錄,并設定相關操作權限

[root@kang nginx-1.10.2]# mkdir -p /var/tmp/nginx/client

[root@kang nginx-1.10.2]# chown -R www:www /var/tmp/nginx/

(7.)再次測試執行

nginx -t

2.編寫Nginx服務腳本

[root@kang ~]# vi /etc/init.d/nginx

内容如下:

#!/bin/bash

#chkconfig: 2345 99 20

#description: Nginx Service Control Script

PROG="/usr/local/nginx1.10/sbin/nginx"

PIDF="/usr/local/nginx1.10/logs/nginx.pid"

case “$1” in

start)

netstat -anplt |grep “:80” &> /dev/null && pgrep “nginx” &> /dev/null

if [ $? -eq 0 ]

then

echo “Nginx service already running.”

else

$PROG -t &> /dev/null

if [ $? -eq 0 ] ; then

$PROG

echo “Nginx service start success.”

$PROG -t

fi

;;

stop)

kill -s QUIT $(cat $PIDF)

echo “Nginx service stop success.”

echo “Nginx service already stop”

restart)

$0 stop

$0 start

status)

echo “Nginx service is running.”

echo “Nginx is stop.”

reload)

kill -s HUP $(cat $PIDF)

echo “reload Nginx config success.”

echo “Nginx service is not run.”

*)

echo “Usage: $0 {start|stop|restart|reload}”

exit 1

esac

(2.)給腳本添加可執行權限,以及設定服務開機自啟動

[root@kang ~]# chmod +x /etc/init.d/nginx

[root@kang ~]# chkconfig --add nginx

[root@kang ~]# chkconfig nginx on

(3.)啟動Nginx服務,檢視端口

(4.)通路Nginx網站測試

注意:關閉防火牆或者放行80端口:

[root@kang ~]# firewall-cmd --permanent --add-port=80/tcp

success

[root@kang ~]# firewall-cmd --reload

[root@kang ~]#

注意:如果你想在已安裝好的nginx上添加第三方子產品,依然需要重新編譯,但為了不覆寫你原有的配置,請不要make install,而是直接拷貝可執行檔案:

[root@kang ~]# nginx -V

[root@www nginx-1.10.2]#./configure --add-module=…… #你的第三方子產品

[root@www nginx-1.10.2] #make後不要make install,改為手動拷貝,先備份

[root@www nginx-1.10.2] #cp /usr/local/nginx1.10/sbin/nginx /usr/local/nginx1.10/sbin/nginx.bak

[root@www nginx-1.10.2] #cp objs/nginx /usr/local/nginx1.10/sbin/nginx

(1.)檢視Nginx加載的子產品

(2.)nginx-sticky-module子產品:

到同一個後端伺服器上處理,這樣一定程度上可以解決多個backend servers的session同步的問題 —— 因為不再需要同步,而RR輪詢模式必須要運維人員自己考慮session同步的實作。

這個子產品的作用是通過cookie黏貼的方式将來自同一個用戶端(浏覽器)的請求發送

另外内置的 ip_hash 也可以實作根據用戶端IP來分發請求,但它很容易造成負載不均衡的情況,而如果nginx前面有CDN網絡或者來自同一區域網路的通路,它接收的用戶端IP是一樣的,容易造成負載不均衡現象。nginx-sticky-module的cookie過期時間,預設浏覽器關閉就過期。

這個子產品并不合适不支援 Cookie 或手動禁用了cookie的浏覽器,此時預設sticky就會切換成RR。它不能與ip_hash同時使用。

例如:

upstream backend {

server 192.168.31.141:80 weight=1;

server 192.168.31.250:80 weight=1;

sticky; 重點子產品

}

配置起來超級簡單,一般來說一個sticky指令就夠了。

相關資訊可以檢視官方文檔https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng

(3.)load-balance其它排程方案:

這裡順帶介紹一下nginx的負載均衡子產品支援的其它排程算法:

輪詢(預設) :每個請求按時間順序逐一配置設定到不同的後端伺服器,如果後端某台伺服器當機,故障系統被自動剔除,使使用者通路不受影響。Weight 指定輪詢權值,Weight值越大,配置設定到的通路機率越高,主要用于後端每個伺服器性能不均的情況下。

ip_hash : 每個請求按通路IP的hash結果配置設定,這樣來自同一個IP的訪客固定通路一個後端伺服器,有效解決了動态網頁存在的session共享問題。當然如果這個節點不可用了,會發到下個節點,而此時沒有session同步的話就登出掉了。

least_conn :請求被發送到目前活躍連接配接最少的realserver上。會考慮weight的值。

url_hash : 此方法按通路url的hash結果來配置設定請求,使每個url定向到同一個後端伺服器,可以進一步提高後端緩存伺服器的效率。Nginx本身是不支援url_hash的,如果需要使用這種排程算法,必須安裝Nginx 的hash軟體包 nginx_upstream_hash 。

fair :這是比上面兩個更加智能的負載均衡算法。此種算法可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端伺服器的響應時間來配置設定請求,響應時間短的優先配置設定。Nginx本身是不支援fair的,如果需要使用這種排程算法,必須下載下傳Nginx的 upstream_fair 子產品。

(4.)負載均衡與健康檢查:

嚴格來說,nginx自帶是沒有針對負載均衡後端節點的健康檢查的,但是可以通過預設自帶的 ngx_http_proxy_module 子產品和ngx_http_upstream_module 子產品中的相關指令來完成當後端節點出現故障時,自動切換到下一個節點來提供通路。

sticky;

server 192.168.31.141:80 weight=1 max_fails=2 fail_timeout=10s;

server 192.168.31.250:80 weight=1 max_fails=2 fail_timeout=10s;

server {

……

location / {

proxy_pass http://backend;

weight : 輪詢權值也是可以用在ip_hash的,預設值為1

max_fails : 允許請求失敗的次數,預設為1。當超過最大次數時,傳回proxy_next_upstream子產品定義的錯誤。

fail_timeout : 有兩層含義,一是在10s 時間内最多容許2 次失敗;二是在經曆了 2 次失敗以後,10s時間内不配置設定請求到這台伺服器。

(5.)nginx的proxy緩存使用:

緩存也就是将js、css、image等靜态檔案從後端伺服器緩存到nginx指定的緩存目錄下,既可以減輕後端伺服器負擔,也可以加快通路速度,但這樣緩存及時清理成為了一個問題,是以需要 ngx_cache_purge 這個子產品來在過期時間未到之前,手動清理緩存。

proxy子產品中常用的指令時proxy_pass和proxy_cache.

nginx的web緩存功能的主要是由proxy_cache、fastcgi_cache指令集和相關指令集完成,proxy_cache指令負責反向代理緩存後端伺服器的靜态内容,fastcgi_cache主要用來處理FastCGI動态程序緩存。

http {

# u p s t r e a m c a c h e s t a t u s 記 錄 緩 存 命 中 率 l o g f o r m a t m a i n ′ upstream_cache_status記錄緩存命中率 log_format main ' upstreamc​aches​tatus記錄緩存命中率logf​ormatmain′remote_addr - r e m o t e u s e r [ remote_user [ remoteu​ser[time_local] “KaTeX parse error: Double superscript at position 34: … '̲status b o d y b y t e s s e n t " body_bytes_sent " bodyb​ytess​ent"http_referer” ’

‘“ h t t p u s e r a g e n t " " http_user_agent" " httpu​sera​gent""http_x_forwarded_for”’

‘"$upstream_cache_status"’;

access_log logs/access.log main;

proxy_buffering on; #代理的時候,開啟或關閉緩沖後端伺服器的響應

proxy_temp_path /usr/local/nginx1.10/proxy_temp;

proxy_cache_path /usr/local/nginx1.10/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;

listen 80;

server_name localhost;

root html;

index index.php index.html index.htm;

#ngx_cache_purge實作緩存清除

location ~/purge(/.) {

allow 127.0.0.1;

allow 192.168.31.0/24;

deny all;

proxy_cache_purge my-cache $host 1 1 1is_args$args;

location ~ ..(gif|jpg|png|html|htm|css|js|ico|swf|pdf)(.*) {

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_ignore_headers Set-Cookie;

proxy_hide_header Set-Cookie;

proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

proxy_cache my-cache;

add_header Nginx-Cache $upstream_cache_status;

proxy_cache_valid 200 304 301 302 8h;

proxy_cache_valid 404 1m;

proxy_cache_valid any 1d;

proxy_cache_key h o s t host hosturi i s a r g s is_args isa​rgsargs;

expires 30d;

相關選項說明:

proxy_buffering on; 代理的時候,開啟或關閉緩沖後端伺服器的響應。

當開啟緩沖時,nginx盡可能快地從被代理的伺服器接收響應,再将它存入緩沖區中。

proxy_temp_path : 緩存臨時目錄。後端的響應并不直接傳回用戶端,而是先寫到一個臨時檔案中,然後被rename一下當做緩存放在 proxy_cache_path 。0.8.9版本以後允許temp和cache兩個目錄在不同檔案系統上(分區),然而為了減少性能損失還是建議把它們設成一個檔案系統上。

proxy_cache_path: 設定緩存目錄,目錄裡的檔案名是cache_key 的MD5值。

levels=1:2 keys_zone=my-cache:100m表示采用2級目錄結構,第一層目錄隻有一個字元,是由levels=1:2設定,總共二層目錄,子目錄名字由二個字元組成。Web緩存區名稱為my-cache,記憶體緩存空間大小為100MB,這個緩沖zone可以被多次使用。檔案系統上看到的緩存檔案名類似于 /usr/local/nginx1.10/proxy_cache/c/29/b7f54b2df7773722d382f4809d65029c。

inactive=600 max_size=2g表示600分鐘沒有被通路的内容自動清除,硬碟最大緩存空間為2GB,超過這個大學将清除最近最少使用的資料。

需要在預設情況,nginx不緩存從後端響應的http頭中帶有Set-Cookie的對象。如果用戶端發送的請求帶有Cookie header,varnish将忽略緩存,直接将請求傳遞到後端。nginx中通過proxy_ignore_headers設定忽略它們,設定方法如下:

解決辦法:

proxy_cache : 引用前面定義的緩存區 my-cache

proxy_cache_key :定義如何生成緩存的鍵,設定web緩存的key值,nginx根據key值md5哈希存儲緩存

proxy_cache_valid : 為不同的響應狀态碼設定不同的緩存時間,比如200、302等正常結果可以緩存的時間長點,而404、500等緩存時間設定短一些,這個時間到了檔案就會過期,而不論是否剛被通路過。

add_header指令來設定response header,文法: add_header name value;

$upstream_cache_status這個變量來顯示緩存的狀态,我們可以在配置中添加一個http頭來顯示這一狀态,

$upstream_cache_status包含以下幾種狀态:

·MISS 未命中,請求被傳送到後端

·HIT 緩存命中

·EXPIRED 緩存已經過期請求被傳送到後端

·UPDATING 正在更新緩存,将使用舊的應答

·STALE 後端将得到過期的應答

expires : 在響應頭裡設定Expires:或Cache-Control:max-age,傳回給用戶端的浏覽器緩存失效時間。

(1.)下面的Nginx.conf實作nginx在前端做反向代理伺服器的完整配置檔案的例子,處理js、png等靜态檔案,jsp/php等動态請求轉發到其它伺服器tomcat/apache

user www www;

worker_processes 4;

worker_cpu_affinity 0001 0010 0100 1000;

error_log logs/error.log;

#error_log logs/error.log notice;

#error_log logs/error.log info;

worker_rlimit_nofile 10240;

pid logs/nginx.pid;

events {

use epoll;

worker_connections 4096;

include mime.types;

default_type application/octet-stream;

log_format main '$remote_addr - r e m o t e u s e r [ remote_user [ remoteu​ser[time_local] “KaTeX parse error: Double superscript at position 34: … '̲status b o d y b y t e s s e n t " body_bytes_sent " bodyb​ytess​ent"http_referer” ’

server_tokens off;

sendfile on;

#tcp_nopush on;

#keepalive_timeout 0;

keepalive_timeout 65;

#Compression Settings

gzip on;

gzip_comp_level 6;

gzip_http_version 1.1;

gzip_proxied any;

gzip_min_length 1k;

gzip_buffers 16 8k;

gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;

gzip_vary on;

#end gzip

# http_proxy Settings

client_max_body_size 10m;

client_body_buffer_size 128k;

proxy_connect_timeout 75;

proxy_send_timeout 75;

proxy_read_timeout 75;

proxy_buffer_size 4k;

proxy_buffers 4 32k;

proxy_busy_buffers_size 64k;

proxy_temp_file_write_size 64k;

proxy_buffering on;

proxy_cache_path /usr/local/nginx1.10/proxy_cache levels=1:2 keys_zone=my-cache:100m max_size=1000m inactive=600m max_size=2g;

#load balance Settings

#virtual host Settings

charset utf-8;

location /nginx_status {

stub_status on;

access_log off;

(2.)配置Nginx

[root@kang ~]# vim /usr/local/nginx1.10/conf/nginx.conf

main全局配置:

woker_processes 4

在配置檔案的頂級main部分,worker角色的工作程序的個數,master程序是接收并配置設定請求給worker處理。這個數值簡單一點可以設定為cpu的核數grep ^processor /proc/cpuinfo | wc -l,也是 auto 值,如果開啟了ssl和gzip更應該設定成與邏輯CPU數量一樣甚至為2倍,可以減少I/O操作。如果nginx伺服器還有其它服務,可以考慮适當減少。

worker_cpu_affinity

也是寫在main部分。在高并發情況下,通過設定cpu粘性來降低由于多CPU核切換造成的寄存器等現場重建帶來的性能損耗。如worker_cpu_affinity 0001 0010 0100 1000; (四核)。

附:

CPU工作狀況:(輸入 top 後,按1 檢視)

上面的配置表示:1核CPU,開啟1個程序。0001表示開啟第一個cpu核心, 0010表示開啟第二個cpu核心,依次類推;有多少個核,就有幾位數,1表示該核心開啟,0表示該核心關閉。

2核CPU,開啟2個程序

worker_processes 2;

worker_cpu_affinity 01 10;

2核CPU,開啟4程序

worker_cpu_affinity 01 10 01 10;

2核CPU,開啟8程序

worker_processes 8;

worker_cpu_affinity 01 10 01 10 01 10 01 10;

8核CPU,開啟2程序

worker_cpu_affinity 10101010 01010101;

說明:10101010表示開啟了第2,4,6,8核心,01010101表示開始了1,3,5,7核心

通過 apache 的ab測試檢視nginx對CPU的使用狀況:

如果多個CPU核心的使用率都相差不多,證明nginx己經成功的利用了多核CPU。測試結束後,CPU核心的負載應該都同時降低。

worker_connections 4096

寫在events部分。每一個worker程序能并發處理(發起)的最大連接配接數(包含與用戶端或後端被代理伺服器間等所有連接配接數)。

worker_rlimit_nofile 10240

寫在main部分。worker程序的最大打開檔案數限制。預設是沒有設定,如果沒設定的話,這個值為作業系統的限制(ulimit -n)。可以限制為作業系統最大的限制65535。把這個值設高,這樣nginx就不會有“too many open files”問題了。

use epoll

寫在events部分。在Linux作業系統下,nginx預設使用epoll事件模型,得益于此,nginx在Linux作業系統下效率相當高。同時Nginx在OpenBSD或FreeBSD作業系統上采用類似于epoll的高效事件模型kqueue。

http伺服器:

與提供http服務相關的一些配置參數。例如:是否使用keepalive啊,是否使用gzip進行壓縮等。

sendfile on

開啟高效檔案傳輸模式。

keepalive_timeout 65 :

長連接配接逾時時間,機關是秒,長連接配接請求大量小檔案的時候,可以減少重建連接配接的開銷,如果設定時間過長,使用者又多,長時間保持連接配接會占用大量資源。

client_max_body_size 10m

允許用戶端請求的最大單檔案位元組數。如果有上傳較大檔案,請設定它的限制值

client_body_buffer_size 128k

緩沖區代理緩沖使用者端請求的最大位元組數

隐藏nginx的版本号

子產品http_proxy:

這個子產品實作的是nginx作為反向代理伺服器的功能,包括緩存功能

proxy_connect_timeout 60

nginx跟後端伺服器連接配接逾時時間(代理連接配接逾時)

proxy_read_timeout 60

定義從後端伺服器讀取響應的逾時。此逾時是指相鄰兩次讀操作之間的最長時間間隔,而不是整個響應傳輸完成的最長時間。如果後端伺服器在逾時時間段内沒有傳輸任何資料,連接配接将被關閉。

定義向後端伺服器傳輸請求的逾時。此逾時是指相鄰兩次寫操作之間的最長時間間隔,而不是整個請求傳輸完成的最長時間。如果後端伺服器在逾時時間段内沒有接收到任何資料,連接配接将被關閉。

proxy_buffer_size 4k

設定緩沖區的大小為size。nginx從被代理的伺服器讀取響應時,使用該緩沖區儲存響應的開始部分。這部分通常包含着一個小小的響應頭。該緩沖區大小預設等于proxy_buffers指令設定的一塊緩沖區的大小,但它也可以被設定得更小。

proxy_buffers 8 4k

文法: proxy_buffers the_number is_size;

為每個連接配接設定緩沖區的數量為number,每塊緩沖區的大小為size。這些緩沖區用于儲存從被代理的伺服器讀取的響應。每塊緩沖區預設等于一個記憶體頁的大小。這個值是4K還是8K,取決于平台。

附:檢視Linux記憶體頁大小

[root@kang ~]# getconf PAGESIZE

4096

或者

getconf PAGE_SIZE

proxy_busy_buffers_size 64k

高負荷下緩沖大小(預設大小是proxy_buffers指令設定單塊緩沖大小的2倍)

proxy_max_temp_file_size

當 proxy_buffers 放不下後端伺服器的響應内容時,會将一部分儲存到硬碟的臨時檔案中,這個值用來設定最大臨時檔案大小,預設1024M。

proxy_temp_file_write_size 64k

當緩存被代理的伺服器響應到臨時檔案時,這個選項限制每次寫臨時檔案的大小。

子產品http_gzip:

gzip on : 開啟gzip壓縮輸出,減少網絡傳輸。

gzip_min_length 1k : 設定允許壓縮的頁面最小位元組數,頁面位元組數從header頭得content-length中進行擷取。建議設定成大于1k的位元組數,小于1k可能會越壓越大。

gzip_buffers 4 16k : 設定系統擷取幾個機關的緩存用于存儲gzip的壓縮結果資料流。416k代表以16k為機關,按照原始資料大小以16k為機關的4倍申請記憶體。如果沒有設定,預設值是申請跟原始資料相同大小的記憶體空間去存儲gzip壓縮結果

gzip_http_version 1.1 : 用于識别 http 協定的版本,早期的浏覽器不支援 Gzip 壓縮,使用者就會看到亂碼,是以為了支援前期版本加上了這個選項,如果你用了 Nginx 的反向代理并期望也啟用 Gzip 壓縮的話,由于末端通信是 http/1.1,故請設定為 1.1。

gzip_comp_level 6 : gzip壓縮比,1壓縮比最小處理速度最快,9壓縮比最大但處理速度最慢(傳輸快但比較消耗cpu)

gzip_types :比對mime類型進行壓縮,無論是否指定”text/html”類型總是會被壓縮的。

預設值: gzip_types text/html (預設不對js/css檔案進行壓縮)

#壓縮類型,比對MIME類型進行壓縮

#不能用通配符 text/*

#(無論是否指定)text/html預設已經壓縮

#設定哪壓縮種文本檔案可參考 conf/mime.types

gzip_proxied any : Nginx作為反向代理的時候啟用,根據某些請求和應答來決定是否在對代理請求的應答啟用gzip壓縮,是否壓縮取決于請求頭中的“Via”字段,指令中可以同時指定多個不同的參數,意義如下:

off – 關閉所有的代理結果資料的壓縮

expired – 啟用壓縮,如果header頭中包含 “Expires” 頭資訊

no-cache – 啟用壓縮,如果header頭中包含 “Cache-Control:no-cache” 頭資訊

no-store – 啟用壓縮,如果header頭中包含 “Cache-Control:no-store” 頭資訊

private – 啟用壓縮,如果header頭中包含 “Cache-Control:private” 頭資訊

no_last_modified – 啟用壓縮,如果header頭中不包含 “Last-Modified” 頭資訊

no_etag – 啟用壓縮 ,如果header頭中不包含 “ETag” 頭資訊

auth – 啟用壓縮 , 如果header頭中包含 “Authorization” 頭資訊

any – 無條件啟用壓縮

gzip_vary on :和http頭有關系,加個vary頭,給代理伺服器用的,有的浏覽器支援壓縮,有的不支援,是以避免浪費不支援的也壓縮,是以根據用戶端的HTTP頭來判斷,是否需要壓縮

子產品http_stream:

這個子產品通過一個簡單的排程算法來實作用戶端IP到後端伺服器的負載均衡,upstream後接負載均衡器的名字,後端realserver以 host:port options; 方式組織在 {} 中。如果後端被代理的隻有一台,也可以直接寫在 proxy_pass 。

Location:

root /var/www/html

定義伺服器的預設網站根目錄位置。如果locationURL比對的是子目錄或檔案,root沒什麼作用,一般放在server指令裡面或/下。

index index.jsp index.html index.htm

定義路徑下預設通路的檔案名,一般跟着root放

proxy_pass http:/backend

請求轉向backend定義的伺服器清單,即反向代理,對應upstream負載均衡器。也可以proxy_pass http://ip:port。

proxy_redirectoff;

指定是否修改被代理伺服器傳回的響應頭中的location頭域跟refresh頭域數值

設定後端伺服器“Location”響應頭和“Refresh”響應頭的替換文本。假設後端伺服器傳回的響應頭是 “Location: http://localhost:8000/two/some/uri/”,那麼指令

proxy_redirecthttp://localhost:8000/two/ http://frontend/one/;

将把字元串改寫為 “Location: http://frontend/one/some/uri/”。

proxy_set_header Host$host;

允許重新定義或者添加發往後端伺服器的請求頭。

Host的含義是表明請求的主機名,nginx反向代理伺服器會向後端真實伺服器發送請求,并且請求頭中的host字段重寫為proxy_pass指令設定的伺服器。因為nginx作為反向代理使用,而如果後端真實的伺服器設定有類似防盜鍊或者根據http請求頭中的host字段來進行路由或判斷功能的話,如果反向代理層的nginx不重寫請求頭中的host字段,将會導緻請求失敗。

proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;

後端的Web伺服器可以通過X-Forwarded-For擷取使用者真實IP

X_Forward_For字段表示該條http請求是有誰發起的?如果反向代理伺服器不重寫該請求頭的話,那麼後端真實伺服器在處理時會認為所有的請求都來自反向代理伺服器,如果後端有防攻擊政策的話,那麼機器就被封掉了。是以,在配置用作反向代理的nginx中一般會增加兩條配置,修改http的請求頭:

proxy_set_header X-Forward-For $remote_addr;

proxy_next_upstream error timeoutinvalid_header http_500 http_502 http_503 http_504;

增加故障轉移,如果後端的伺服器傳回502、504、執行逾時等錯誤,自動将請求轉發到upstream負載均衡池中的另一台伺服器,實作故障轉移。

proxy_set_headerX-Real-IP $remote_addr;

web伺服器端獲得使用者的真實ip但是,實際上要獲得使用者的真實ip,也可以通過X-Forward-For

(1.)下面我們來測試一下緩存功能

如果在緩存時間之内需要更新被緩存的靜态檔案怎麼辦呢,這時候就需要手動來清除緩存了。

ngx_cache_pure清除緩存子產品使用說明

用谷歌浏覽器測試的時候,可以按F12調用開發工具,選擇Network選項,我們可以看到,Response Headers,在這裡我們可以看到,我們請求的是否緩存

從圖中我們可以看到,我們通路的伺服器是192.168.197.169,緩存命中。

也可以檢視緩存目錄或nginx的通路日志

清除緩存:

上述配置的proxy_cache_purge指令用于友善的清除緩存,但必須按照第三方的 ngx_cache_purge 子產品才能使用

使用 ngx_cache_purge 子產品清除緩存(直接删除緩存目錄下的檔案也算一種辦法):

GET方式請求URL

即使用配置檔案中的location ~ /purge(/.*)

浏覽器通路http://192.168.197.169/purge/your/may/path來清除緩存

緩存清除成功。

備注:

(1)purge是ngx_cache_pure 子產品指令

(2)your/may/path 是要清除的緩存檔案URL路徑

(2.)測試負載均衡

通路Nginx伺服器的ip位址,不停重新整理頁面浏覽到後端的兩台Apache網站,證明通過反向代理實作了負載均衡測試成功!!!

如何修改Nginx版本等資訊

1、vi /usr/local/src/nginx-1.0.12/src/core/nginx.h #編譯前編輯

#define nginx_version

#define NGINX_VERSION

#define NGINX_VER

#define NGINX_VAR

修改上面的資訊,即可更改nginx顯示版本。

2、vi/usr/local/src/nginx-1.0.12/src/http/ngx_http_special_response.c #編譯前編輯

static u_char ngx_http_error_full_tail[] =

static u_char ngx_http_error_tail[] =

修改上面的資訊為你自己的。

3、vi/usr/local/src/nginx-1.0.12/src/http/ngx_http_header_filter_module.c #編譯前編輯

static char ngx_http_server_string[]=

4、編譯完成之後,修改/usr/local/nginx/conf目錄下面

fastcgi.conf、fastcgi.conf.default、fastcgi_params、fastcgi_params.default

這四個檔案裡面的版本名稱

/usr/local/nginx/sbin/nginx -V #檢視nginx版本号

(1.)Nginx的概念、特點、原理(正向、反向代理)、為什麼使用Nginx?

(2.)Nginx的安裝、

(3.)Nginx的優化、(gzip、cache、負載均衡、健康檢查、CPU核數、最大連接配接數、開啟epoll模型、第三方子產品、子產品優化)

(4.)驗證Nginx網頁、負載均衡、清除緩存、檢視緩存等、

(5.)Nginx不能動态加載子產品,需要提前編譯時安裝!!!

原作者部落格Alex’blog

繼續閱讀