nginx反向代理緩存服務器構建

博主QQ:819594300

博客地址:http://zpf666.blog.51cto.com/

有什麼疑問的朋友可以聯繫博主,博主會幫你們解答,謝謝支持!

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

正向代理: 用於代理內部網絡對Internet的連接請求(如***/NAT),客戶端指定代理服務器,並將本來要直接發送給目標Web服務器的HTTP請求先發送到代理服務器上, 然後由代理服務器去訪問Web服務器,並將Web服務器的Response回傳給客戶端:

反向代理: 與正向代理相反,如果局域網向Internet提供資源,並讓Internet上的其他用戶可以訪問局域網內資源, 也可以設置一個代理服務器, 它提供的服務就是反向代理. 反向代理服務器接受來自Internet的連接,然後將請求轉發給內部網絡上的服務器,並將Response回傳給Internet上請求連接的客戶端:

一、nginx反向代理:Web服務器的調度器

1、反向代理(ReverseProxy)方式是指以代理服務器來接受客戶端的連接請求,然後將請求轉發給網絡上的web服務器(可能是apache、nginx、tomcat、iis等),並將從web服務器上得到的結果返回給請求連接的客戶端,此時代理服務器對外就表現爲一個服務器。

wKiom1kSY_iQY7K0AAGBf4rptSY659.jpg

從上圖可以看出:反向代理服務器代理網站Web服務器接收Http請求,對請求進行轉發。而且nginx作爲反向代理服務器可以根據用戶請求的內容把請求轉發給後端不同的web服務器,例如靜動分離,再例如在nginx上創建多個虛擬主機,這樣就成功的做到了在瀏覽器中輸入不同域名(url)的時候訪問後端的不同web服務器或web羣集。

 

2、反向代理的作用

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

wKioL1kSY_mR8OyvAAERTWX_GKs678.jpg

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

wKioL1kSY_nShnkpAAEXP--OGZM164.jpg

③實現負載均衡:充當負載均衡服務器均衡地分發請求,平衡集羣中各個服務器的負載壓力;

wKiom1kSY_rQC3sXAAC9NbLXAto221.jpg

二、什麼是nginx

1、nginx簡介

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

Nginx的應用現狀

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

在國內,已經有淘寶、新浪博客、新浪播客、網易新聞、六間房、56.com、Discuz!、水木社區、豆瓣、YUPOO、海內、迅雷在線 等多家網站使用 Nginx 作爲Web服務器或反向代理服務器。

2、Nginx的核心特點

(1)跨平臺:Nginx 可以在大多數OS編譯運行,而且也有Windows的版本;

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

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

注:

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

 

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

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

(4)事件驅動:通信機制採用epoll模型,支持更大的併發連接。

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

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

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

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

(5)Master/Worker結構:一個master進程,生成一個或多個worker進程。

wKiom1kSY_vge-8bAAD3k23EEvo947.jpg

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

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

(6)內存消耗小:處理大併發的請求內存消耗非常小。在3萬併發連接下,開啓的10個Nginx 進程才消耗150M內存(15M*10=150M)。

(7)內置的健康檢查功能:如果 Nginx 代理的後端的某臺 Web 服務器宕機了,不會影響前端訪問。

(8)節省帶寬:支持 GZIP 壓縮,可以添加瀏覽器本地緩存的 Header 頭。

(9)穩定性高:用於反向代理,宕機的概率微乎其微。

三、Nginx+apache構築Web服務器集羣的負載均衡

nginx配置反向代理

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

wKioL1kSY_vDzyfiAADKHdBWMRg909.jpg

1、安裝nginx

環境:

OS:centos7.2

nginx:192.168.1.6

apache1:192.168.1.7

apache2:192.168.1.8

安裝zlib-devel、pcre-devel等依賴包

wKioL1kSY_ujDUcuAACXAgfScZI649.jpg

注:

結合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一起安裝。

安裝nginx

wKiom1kSY_yAHmDIAAFZbgPdlUk537.jpg

wKiom1kSY_yTi-QIAAHQVLkrTrQ281.jpg

wKioL1kSY_2TtVpAAAJLf8i0Hy4637.jpg

上圖中內容如下:

./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 && make && make install

注:nginx的所有模塊必須在編譯的時候添加,不能再運行的時候動態加載。

解釋:

--add-module:添加第三方模塊

--with-http_gzip_static_module:添加gzip模塊

--http-client-body-temp-path=/var/tmp/nginx/client:添加緩存目錄,該目錄需要手動創建

優化nginx程序的執行路徑

wKioL1kSY_6QhrA2AAFxwyxndo8920.jpg

2、編寫nginx服務腳本:

wKiom1kSY_7A0srAAACzxmiOC6E901.jpg

#!/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 alreadyrunning."

   else

     $PROG -t &> /dev/null

     if [ $? -eq 0 ] ; then

       $PROG

       echo "Nginx service start success."

     else

     $PROG -t

     fi

   fi

   ;;

  stop)

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

   if [ $? -eq 0 ]

   then

    kill -s QUIT $(cat $PIDF)

    echo "Nginx service stopsuccess."

   else

    echo "Nginx service already stop"

   fi

   ;;

  restart)

    $0 stop

    $0 start

    ;;

  status)

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

   if [ $? -eq 0 ]

   then

     echo "Nginx service is running."

   else

     echo "Nginx is stop."

   fi

  ;;

  reload)

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

   if [ $? -eq 0 ]

   then

    $PROG -t &> /dev/null

    if [ $? -eq 0 ] ; then

      kill -s HUP $(cat $PIDF)

      echo "reload Nginx configsuccess."

    else

      $PROG -t

    fi

   else

    echo "Nginx service is not run."

   fi

    ;;

  *)

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

   exit 1

esac

wKioL1kSY_-CB7bXAAHzNutWu8o039.jpg

wKioL1kSY__QzDRuAAE1BXBg8aU101.jpg

注:如果你想在已安裝好的nginx上添加第三方模塊,依然需要重新編譯,但爲了不覆蓋你原有的配置,請不要makeinstall,而是直接拷貝可執行文件,解決辦法如下:

nginx   -V   //可以查看你當前nginx已經安裝的模塊

[[email protected]]#./configure  --add-module=……   #你的第三方模塊

[[email protected]] #make後不要make install,改爲手動拷貝,先備份

[[email protected]] #cp /usr/local/nginx1.10/sbin/nginx/usr/local/nginx1.10/sbin/nginx.bak

[[email protected]] #cp objs/nginx/usr/local/nginx1.10/sbin/nginx

配置nginx反向代理:反向代理+負載均衡+健康探測

查看nginx加載的模塊:

wKiom1kSY__SZT9hAAIyfrHUMsg639.jpg

再次申明:nginx的所有模塊必須在編譯的時候添加,不能再運行的時候動態加載。

 

3、nginx-sticky-module模塊:

這個模塊的作用是通過cookie黏貼的方式將來自同一個客戶端(瀏覽器)的請求發送到同一個後端服務器上處理,這樣一定程度上可以解決多個backend servers的session同步的問題 —— 因爲不再需要同步,而RR輪詢模式必須要運維人員自己考慮session同步的實現。

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

這個模塊並不合適不支持 Cookie 或手動禁用了cookie的瀏覽器,此時默認sticky就會切換成RR。它不能與ip_hash同時使用。

wKioL1kSZADhneVqAADuQ70YQbA770.jpg

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

相關信息可以查看官方文檔https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng

4、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 模塊。

5、負載均衡與健康檢查:

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

wKiom1kSZAGjFhBhAAJR1NtQCjo119.jpg

weight : 輪詢權值也是可以用在ip_hash的,默認值爲1

max_fails : 允許請求失敗的次數,默認爲1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

fail_timeout : 有兩層含義,一是在10s 時間內最多容許2 次失敗;二是在經歷了 2 次失敗以後,10s時間內不分配請求到這臺服務器。

6、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動態進程緩存。

wKioL1kSZAHiW6z0AAKyQeFNtY4961.jpg

wKiom1kSZAOBreL1AAN4swlxnA0932.jpg

相關選項說明:

proxy_buffering on; 代理的時候,開啓或關閉緩衝後端服務器的響應。

當開啓緩衝時,nginx儘可能快地從被代理的服務器接收響應,再將它存入緩衝區中。

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

proxy_cache_path: 設置緩存目錄,目錄裏的文件名是 cache_key 的MD5值。

levels=1:2keys_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_ignore_headersSet-Cookie;

proxy_hide_headerSet-Cookie;

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

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

proxy_cache_valid : 爲不同的響應狀態碼設置不同的緩存時間,比如200、302等正常結果可以緩存的時間長點,而404、500等緩存時間設置短一些,這個時間到了文件就會過期,而不論是否剛被訪問過。

add_header指令來設置responseheader, 語法: add_header name value;

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

$upstream_cache_status包含以下幾種狀態:

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

·HIT 緩存命中

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

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

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

expires : 在響應頭裏設置Expires:或Cache-Control:max-age,返回給客戶端的瀏覽器緩存失效時間。

 

下面是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;

}

http{

    include       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"'

                     '"$upstream_cache_status"';

access_log  logs/access.log  main;

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/csstext/javascript application/json application/javascriptapplication/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_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 max_size=1000m inactive=600m max_size=2g;

    #load balance Settings

    upstream backend {

        sticky;

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

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

    }

    #virtual host Settings

    server {

        listen      80;

        server_name  localhost;

        charset utf-8;

        location  ~/purge(/.*) {

           allow 127.0.0.1;

           allow 192.168.1.0/24;

deny all;

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

        }

        location / {

            index  index.php index.html index.htm;

            proxy_pass        http://backend;

            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;

        }

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

           proxy_pass  http://backend;

           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_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 $host$uri$is_args$args;

           expires 30d;

        }

 location /nginx_status {

            stub_status on;

            access_log off;

            allow 192.168.1.0/24;

            deny all;

        }

    }

}

          

注:nginx代理服務器這裏server_name  localhost;而後臺web服務器上每個服務器上都必須是ServerName www.benet.com

常用指令說明:

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_affinity0001 0010 0100 1000; (四核)。

附:

CPU工作狀況:(輸入 top 後,按1 查看)

wKiom1kSZASzbcZSAADz2ARukHU951.jpg

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

例如:

1、2核CPU,開啓2個進程

worker_processes  2;

worker_cpu_affinity01 10;

2、2核CPU,開啓4進程

worker_processes4;

worker_cpu_affinity01 10 01 10;

3、2核CPU,開啓8進程

worker_processes  8;

worker_cpu_affinity01 10 01 10 01 10 01 10;

4、8核CPU,開啓2進程

worker_processes  2;

worker_cpu_affinity10101010  01010101;

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

通過 apache 的ab測試查看nginx對CPU的使用狀況:

wKioL1kSZATBB-G2AAD1sr-YmcY185.jpg

如果多個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

緩衝區代理緩衝用戶端請求的最大字節數

server_tokens off;

隱藏nginx的版本號

模塊http_proxy:

這個模塊實現的是nginx作爲反向代理服務器的功能,包括緩存功能

proxy_connect_timeout

nginx跟後端服務器連接超時時間(代理連接超時)

 

proxy_read_timeout

定義從後端服務器讀取響應的超時。此超時是指相鄰兩次讀操作之間的最長時間間隔,而不是整個響應傳輸完成的最長時間。如果後端服務器在超時時間段內沒有傳輸任何數據,連接將被關閉。

 

proxy_send_timeout

定義向後端服務器傳輸請求的超時。此超時是指相鄰兩次寫操作之間的最長時間間隔,而不是整個請求傳輸完成的最長時間。如果後端服務器在超時時間段內沒有接收到任何數據,連接將被關閉。

 

proxy_buffer_size 4k

設置緩衝區的大小爲size。nginx從被代理的服務器讀取響應時,使用該緩衝區保存響應的開始部分。這部分通常包含着一個小小的響應頭。該緩衝區大小默認等於proxy_buffers指令設置的一塊緩衝區的大小,但它也可以被設置得更小。

 

proxy_buffers 8 4k

語法: proxy_buffers the_number is_size;

爲每個連接設置緩衝區的數量爲number,每塊緩衝區的大小爲size。這些緩衝區用於保存從被代理的服務器讀取的響應。每塊緩衝區默認等於一個內存頁的大小。這個值是4K還是8K,取決於平臺。

附:查看Linux內存頁大小

[root@www~]# getconf PAGESIZE

4096

[root@www~]# getconf PAGE_SIZE

4096

 

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的壓縮結果數據流。4 16k代表以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:portoptions;方式組織在 {} 中。如果後端被代理的只有一臺,也可以直接寫在 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_redirect off;

指定是否修改被代理服務器返回的響應頭中的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_header X-Forwarded-For $proxy_add_x_forwarded_for;

後端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP

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

proxy_set_headerHost $host;

proxy_set_headerX-Forward-For $remote_addr;

 

proxy_next_upstreamerror timeout invalid_header http_500 http_502 http_503 http_504;

增加故障轉移,如果後端的服務器返回502、504、執行超時等錯誤,自動將請求轉發到upstream負載均衡池中的另一臺服務器,實現故障轉移。

 

proxy_set_header X-Real-IP $remote_addr;

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

7、驗證:nginx反向代理的緩存功能、負載均衡及健康檢查

說明:

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

如果在緩存時間之內需要更新被緩存的靜態文件怎麼辦呢,這時候就需要手動來清除緩存了。

ngx_cache_pure清除緩存模塊使用說明

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

wKiom1kSZAWie1mBAAEJRc0M0yc627.jpg

說明:第一次訪問是MISS,刷新一下這個頁面就是HIT命中了。

從圖中我們可以看到,我們訪問的服務器是192.168.1.6,緩存命中。

也可以查看緩存目錄或nginx的訪問日誌。

wKioL1kSZAXR0toYAACbeeBR6gg146.jpg

wKioL1kSZAbBQCO9AAH9_AsUKtE934.jpg

清除緩存:

上述配置的proxy_cache_purge指令用於方便的清除緩存,但必須按照第三方的ngx_cache_purge 模塊才能使用

使用 ngx_cache_purge 模塊清除緩存(直接刪除緩存目錄下的文件也算一種辦法):

GET方式請求URL

即使用配置文件中的location ~ /purge(/.*)

瀏覽器訪問http://192.168.1.6/purge/your/may/path來清除緩存。

wKiom1kSZAbB-MaoAACg6cFrg08274.jpg

緩存清除成功。

備註:

      (1)purge是ngx_cache_pure 模塊指令

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

 

2)若只有一臺客戶端要驗證負載均衡和健康檢查可以先關掉緩存功能和保持session會話。

wKiom1kSZAeCuQB3AABA0huDdpA569.jpg

wKioL1kSZAeQn3CHAAAfP909vag881.jpg

wKiom1kSZAeyMKlcAADNfKK5ATQ809.jpg

測試:

注:可以yum安裝apache,在配置文件http.conf中將ServerName字段後面的改成www.benet.com


改成這樣:ServerName www.benet.com


wKioL1kSZAjjo82WAACpx9FZCAM740.jpg

wKiom1kSZAjCwN_oAAC14tAIaGg309.jpg

驗證健康檢查:

首先關閉一臺後端的web服務器的web服務:

wKioL1kSZAiBdalEAADl4yYtA1Y956.jpg

開始驗證:

wKiom1kSZAmw5WguAABzdnEyHDQ077.jpg

中間不卡頓,一直訪問的是apache2的網頁。

重新啓動宕機的apache1的web服務:

wKiom1kSZB_xYPvNAADha67HOkY152.jpg

再次驗證:

wKioL1kSZB_gsb8RAAB71VzKyfg502.jpg

wKiom1kSZB-i3-VOAABuK8L6Kxc135.jpg

又可以來回切換的正常訪問了。

在後端服務器上查看訪問日誌:

wKioL1kSZCDCmfhwAAEM-y3qFQM982.jpg

可以看見,訪問日誌記錄的訪問者是nginx反向代理服務器的IP,那怎麼讓它記錄的是客戶機的真是IP,而不是nginx代理服務器的呢?

解決辦法如下:

wKiom1kSZCDDqGo0AADic2bnYTU094.jpg

wKiom1kSZCDRaTyQAACQKHXDjew466.jpg

wKioL1kSZCHhdNJpAACkW5Jlqa4861.jpg

再次查看:

wKioL1kSZCHRU1mOAAC0X5X32a0535.jpg

注:192.168.1.4是我客戶機的IP。


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