Nginx 反向代理、負載均衡、頁面緩存、URL重寫以及讀寫分離


1.環境准備

前端Nginx:10.160.65.44

后端WEB服務器兩台:10.160.65.49/10.160.65.50

2.安裝Nginx:

下載nginx-1.9.15.tar.gz,放置在目錄/usr/local/src目錄下面,解壓。

./configure

make & make install

在/usr/local/目錄下生成了nginx目錄

configure的時候可以帶很多參數,參數的詳細解釋如下:

–prefix= 指向安裝目錄
–sbin-path 指向(執行)程序文件(nginx)
–conf-path= 指向配置文件(nginx.conf)
–error-log-path= 指向錯誤日志目錄
–pid-path= 指向pid文件(nginx.pid)
–lock-path= 指向lock文件(nginx.lock)(安裝文件鎖定,防止安裝文件被別人利用,或自己誤操作。)
–user= 指定程序運行時的非特權用戶
–group= 指定程序運行時的非特權用戶組
–builddir= 指向編譯目錄
–with-rtsig_module 啟用rtsig模塊支持(實時信號)
–with-select_module 啟用select模塊支持(一種輪詢模式,不推薦在高載環境下使用)禁用:–without-select_module
–with-poll_module 啟用poll模塊支持(功能與select相同,與select特性相同,為一種輪詢模式,不推薦在高載環境下使用)
–with-file-aio 啟用file aio支持(一種APL文件傳輸格式)
–with-ipv6 啟用ipv6支持
–with-http_ssl_module 啟用ngx_http_ssl_module支持(使支持https請求,需已安裝openssl)
–with-http_realip_module 啟用ngx_http_realip_module支持(這個模塊允許從請求標頭更改客戶端的IP地址值,默認為關)
–with-http_addition_module 啟用ngx_http_addition_module支持(作為一個輸出過濾器,支持不完全緩沖,分部分響應請求)
–with-http_xslt_module 啟用ngx_http_xslt_module支持(過濾轉換XML請求)
–with-http_image_filter_module 啟用ngx_http_image_filter_module支持(傳輸JPEG/GIF/PNG 圖片的一個過濾器)(默認為不啟用。gd庫要用到)
–with-http_geoip_module 啟用ngx_http_geoip_module支持(該模塊創建基於與MaxMind GeoIP二進制文件相配的客戶端IP地址的ngx_http_geoip_module變量)
–with-http_sub_module 啟用ngx_http_sub_module支持(允許用一些其他文本替換nginx響應中的一些文本)
–with-http_dav_module 啟用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:創建集合,COPY和MOVE方法)默認情況下為關閉,需編譯開啟
–with-http_flv_module 啟用ngx_http_flv_module支持(提供尋求內存使用基於時間的偏移量文件)
–with-http_gzip_static_module 啟用ngx_http_gzip_static_module支持(在線實時壓縮輸出數據流)
–with-http_random_index_module 啟用ngx_http_random_index_module支持(從目錄中隨機挑選一個目錄索引)
–with-http_secure_link_module 啟用ngx_http_secure_link_module支持(計算和檢查要求所需的安全鏈接網址)
–with-http_degradation_module  啟用ngx_http_degradation_module支持(允許在內存不足的情況下返回204或444碼)
–with-http_stub_status_module 啟用ngx_http_stub_status_module支持(獲取nginx自上次啟動以來的工作狀態)
–without-http_charset_module 禁用ngx_http_charset_module支持(重新編碼web頁面,但只能是一個方向–服務器端到客戶端,並且只有一個字節的編碼可以被重新編碼)
–without-http_gzip_module 禁用ngx_http_gzip_module支持(該模塊同-with-http_gzip_static_module功能一樣)
–without-http_ssi_module 禁用ngx_http_ssi_module支持(該模塊提供了一個在輸入端處理處理服務器包含文件(SSI)的過濾器,目前支持SSI命令的列表是不完整的)
–without-http_userid_module 禁用ngx_http_userid_module支持(該模塊用來處理用來確定客戶端后續請求的cookies)
–without-http_access_module 禁用ngx_http_access_module支持(該模塊提供了一個簡單的基於主機的訪問控制。允許/拒絕基於ip地址)
–without-http_auth_basic_module禁用ngx_http_auth_basic_module(該模塊是可以使用用戶名和密碼基於http基本認證方法來保護你的站點或其部分內容)
–without-http_autoindex_module 禁用disable ngx_http_autoindex_module支持(該模塊用於自動生成目錄列表,只在ngx_http_index_module模塊未找到索引文件時發出請求。)
–without-http_geo_module 禁用ngx_http_geo_module支持(創建一些變量,其值依賴於客戶端的IP地址)
–without-http_map_module 禁用ngx_http_map_module支持(使用任意的鍵/值對設置配置變量)
–without-http_split_clients_module 禁用ngx_http_split_clients_module支持(該模塊用來基於某些條件划分用戶。條件如:ip地址、報頭、cookies等等)
–without-http_referer_module 禁用disable ngx_http_referer_module支持(該模塊用來過濾請求,拒絕報頭中Referer值不正確的請求)
–without-http_rewrite_module 禁用ngx_http_rewrite_module支持(該模塊允許使用正則表達式改變URI,並且根據變量來轉向以及選擇配置。如果在server級別設置該選項,那么他們將在 location之前生效。如果在location還有更進一步的重寫規則,location部分的規則依然會被執行。如果這個URI重寫是因為location部分的規則造成的,那么 location部分會再次被執行作為新的URI。 這個循環會執行10次,然后Nginx會返回一個500錯誤。)
–without-http_proxy_module 禁用ngx_http_proxy_module支持(有關代理服務器)
–without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持(該模塊允許Nginx 與FastCGI 進程交互,並通過傳遞參數來控制FastCGI 進程工作。 )FastCGI一個常駐型的公共網關接口。
–without-http_uwsgi_module 禁用ngx_http_uwsgi_module支持(該模塊用來醫用uwsgi協議,uWSGI服務器相關)
–without-http_scgi_module 禁用ngx_http_scgi_module支持(該模塊用來啟用SCGI協議支持,SCGI協議是CGI協議的替代。它是一種應用程序與HTTP服務接口標准。它有些像FastCGI但他的設計 更容易實現。)
–without-http_memcached_module 禁用ngx_http_memcached_module支持(該模塊用來提供簡單的緩存,以提高系統效率)
-without-http_limit_zone_module 禁用ngx_http_limit_zone_module支持(該模塊可以針對條件,進行會話的並發連接數控制)
–without-http_limit_req_module 禁用ngx_http_limit_req_module支持(該模塊允許你對於一個地址進行請求數量的限制用一個給定的session或一個特定的事件)
–without-http_empty_gif_module 禁用ngx_http_empty_gif_module支持(該模塊在內存中常駐了一個1*1的透明GIF圖像,可以被非常快速的調用)
–without-http_browser_module 禁用ngx_http_browser_module支持(該模塊用來創建依賴於請求報頭的值。如果瀏覽器為modern ,則$modern_browser等於modern_browser_value指令分配的值;如 果瀏覽器為old,則$ancient_browser等於 ancient_browser_value指令分配的值;如果瀏覽器為 MSIE中的任意版本,則 $msie等於1)
–without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持(該模塊用於簡單的負載均衡)
–with-http_perl_module 啟用ngx_http_perl_module支持(該模塊使nginx可以直接使用perl或通過ssi調用perl)
–with-perl_modules_path= 設定perl模塊路徑
–with-perl= 設定perl庫文件路徑
–http-log-path= 設定access log路徑
–http-client-body-temp-path= 設定http客戶端請求臨時文件路徑
–http-proxy-temp-path= 設定http代理臨時文件路徑
–http-fastcgi-temp-path= 設定http fastcgi臨時文件路徑
–http-uwsgi-temp-path= 設定http uwsgi臨時文件路徑
–http-scgi-temp-path= 設定http scgi臨時文件路徑
-without-http 禁用http server功能
–without-http-cache 禁用http cache功能
–with-mail 啟用POP3/IMAP4/SMTP代理模塊支持
–with-mail_ssl_module 啟用ngx_mail_ssl_module支持
–without-mail_pop3_module 禁用pop3協議(POP3即郵局協議的第3個版本,它是規定個人計算機如何連接到互聯網上的郵件服務器進行收發郵件的協議。是因特網電子郵件的第一個離線協議標 准,POP3協議允許用戶從服務器上把郵件存儲到本地主機上,同時根據客戶端的操作刪除或保存在郵件服務器上的郵件。POP3協議是TCP/IP協議族中的一員,主要用於 支持使用客戶端遠程管理在服務器上的電子郵件)
–without-mail_imap_module 禁用imap協議(一種郵件獲取協議。它的主要作用是郵件客戶端可以通過這種協議從郵件服務器上獲取郵件的信息,下載郵件等。IMAP協議運行在TCP/IP協議之上, 使用的端口是143。它與POP3協議的主要區別是用戶可以不用把所有的郵件全部下載,可以通過客戶端直接對服務器上的郵件進行操作。)
–without-mail_smtp_module 禁用smtp協議(SMTP即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。SMTP協議屬於TCP/IP協議族,它幫助每台計算機在發送或中轉信件時找到下一個目的地。)
–with-google_perftools_module 啟用ngx_google_perftools_module支持(調試用,剖析程序性能瓶頸)
–with-cpp_test_module 啟用ngx_cpp_test_module支持
–add-module= 啟用外部模塊支持
–with-cc= 指向C編譯器路徑
–with-cpp= 指向C預處理路徑
–with-cc-opt= 設置C編譯器參數(PCRE庫,需要指定–with-cc-opt=”-I /usr/local/include”,如果使用select()函數則需要同時增加文件描述符數量,可以通過–with-cc- opt=”-D FD_SETSIZE=2048”指定。)
–with-ld-opt= 設置連接文件參數。(PCRE庫,需要指定–with-ld-opt=”-L /usr/local/lib”。)
–with-cpu-opt= 指定編譯的CPU,可用的值為: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64
–without-pcre 禁用pcre庫
–with-pcre 啟用pcre庫
–with-pcre= 指向pcre庫文件目錄
–with-pcre-opt= 在編譯時為pcre庫設置附加參數
–with-md5= 指向md5庫文件目錄(消息摘要算法第五版,用以提供消息的完整性保護)
–with-md5-opt= 在編譯時為md5庫設置附加參數
–with-md5-asm 使用md5匯編源
–with-sha1= 指向sha1庫目錄(數字簽名算法,主要用於數字簽名)
–with-sha1-opt= 在編譯時為sha1庫設置附加參數
–with-sha1-asm 使用sha1匯編源
–with-zlib= 指向zlib庫目錄
–with-zlib-opt= 在編譯時為zlib設置附加參數
–with-zlib-asm= 為指定的CPU使用zlib匯編源進行優化,CPU類型為pentium, pentiumpro
–with-libatomic 為原子內存的更新操作的實現提供一個架構
–with-libatomic= 指向libatomic_ops安裝目錄
–with-openssl= 指向openssl安裝目錄
–with-openssl-opt 在編譯時為openssl設置附加參數
–with-debug 啟用debug日志

編譯執行安裝完nginx之后,可以將nginx加入到自啟動:

在/etc/init.d/目錄下面新建nginx文件,加上可執行權限,文件內容如下:

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
 
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
 
make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -z "`grep $user /etc/passwd`" ]; then
       useradd -M -s /bin/nologin $user
   fi
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
 
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
 
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
 
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    $nginx -s reload
    RETVAL=$?
    echo
}
 
force_reload() {
    restart
}
 
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
 
rh_status() {
    status $prog
}
 
rh_status_q() {
    rh_status >/dev/null 2>&1
}
 
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

然后執行:

chkconfig --add nginx

chkconfig --level 2345 nginx on

請注意:

為了實現rewrite功能,我們需要安裝pcre,這么我們沒有安裝。后續操作的時候安裝。上述服務器列表中有pcre-8.38.tar.gz。

3.正向代理與反向代理

正向代理:一台私有網段的服務器不能上網,在前端放置一台代理服務器,然后通過代理服務器訪問網絡,通過代理可以訪問所有的站點

反向代理:一台公網上的服務器,需要訪問私有的服務器,但是私有服務器不允許所有的訪問,於是設置一個代理,讓訪問的客戶端覺得這就是你需要訪問的服務器,它只代理后端的這一台或者多台服務器

(1).正向代理的概念

       正向代理,也就是傳說中的代理,他的工作原理就像一個跳板,簡單的說,我是一個用戶,我訪問不了某網站,但是我能訪問一個代理服務器,這個代理服務器呢,他能訪問那個我不能訪問的網站,於是我先連上代理服務器,告訴他我需要那個無法訪問網站的內容,代理服務器去取回來,然后返回給我。從網站的角度,只在代理服務器來取內容的時候有一次記錄,有時候並不知道是用戶的請求,也隱藏了用戶的資料,這取決於代理告不告訴網站。

       結論就是,正向代理 是一個位於客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理發送一個請求並指定目標(原始服務器),然后代理向原始服務器轉交請求並將獲得的內容返回給客戶端。客戶端必須要進行一些特別的設置才能使用正向代理。

(2).反向代理的概念

繼續舉例:    

       例用戶訪問 http://www.test.com/readme,但www.test.com上並不存在readme頁面,他是偷偷從另外一台服務器上取回來,然后作為自己的內容返回用戶,但用戶並不知情。這里所提到的 www.test.com 這個域名對應的服務器就設置了反向代理功能。

       結論就是,反向代理正好相反,對於客戶端而言它就像是原始服務器,並且客戶端不需要進行任何特別的設置。客戶端向反向代理的命名空間(name-space)中的內容發送普通請求,接着反向代理將判斷向何處(原始服務器)轉交請求,並將獲得的內容返回給客戶端,就像這些內容原本就是它自己的一樣。

(3).兩者區別

從用途上來講:

       正向代理的典型用途是為在防火牆內的局域網客戶端提供訪問Internet的途徑。正向代理還可以使用緩沖特性減少網絡使用率。反向代理的典型用途是將防火牆后面的服務器提供給Internet用戶訪問。反向代理還可以為后端的多台服務器提供負載平衡,或為后端較慢的服務器提供緩沖服務。另外,反向代理還可以啟用高級URL策略和管理技術,從而使處於不同web服務器系統的web頁面同時存在於同一個URL空間下。

從安全性來講:

       正向代理允許客戶端通過它訪問任意網站並且隱藏客戶端自身,因此你必須采取安全措施以確保僅為經過授權的客戶端提供服務。反向代理對外都是透明的,訪問者並不知道自己訪問的是一個代理。

  Nginx的Modules:  http://nginx.org/en/docs/

 4.配置Nginx反向代理:

        location /forum/ {
                proxy_pass http://192.168.144.49/bbs/;
        }

  通過訪問http://10.160.65.44/forum/---->http://10.160.65.49/bbs/

 我們使用正則表達式來處理

 在Nginx服務上定義配置文件:

        location ~* ^/Forum {      #~*表示不區分大小寫
                proxy_pass http://192.168.144.49;
        }

  由於使用正則表達式,那么代理的路徑后面不能再接原字符了,所以它只能指向一台服務器。因此apache1服務器是的目錄需要跟nginx服務器上目錄一致,將bbs修改為forum。

  通過訪問http://10.160.65.44/forum/---->http://10.160.65.49/forum/

   但是這樣訪問存在一個問題,在/var/log/httpd/access_log里面,寫入的日志是這樣的:

192.168.144.44 - - [28/Oct/2016:12:03:09 +0800] "GET /forum HTTP/1.0" 301 316 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5"
192.168.144.44 - - [28/Oct/2016:12:03:18 +0800] "HEAD /forum HTTP/1.0" 301 - "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5"
~

  這並不是從Client訪問過來的IP地址,對於我們做數據分析提取是無效的,因此修改改為源地址記錄:

  在nginx端修改

        location ~* ^/Forum {
                proxy_pass http://192.168.144.49;
                proxy_set_header X-Real-IP $remote_addr;
        }

  在Apache端修改日志記錄格式:

  修改/etc/httpd/conf/httpd.conf

LogFormat "%{X-Real-IP}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

  重啟httpd服務,再次刷新的時候就可以看到相關的遠端IP了。

10.140.65.135 192.168.144.44 - - [28/Oct/2016:13:01:11 +0800] "GET /forum/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"

5.負載均衡

   負載均衡需要使用ngx_http_upstream_module這個模塊,http://nginx.org/en/docs/http/ngx_http_upstream_module.html,其定義在server之外:

    upstream websrvs {
        server 192.168.144.49 weight=1;
        server 192.168.144.50 weight=1;
        }

  然后修改location里面的定義:

        location / {
                proxy_pass http://websrvs/bbs/;
                proxy_set_header X-Real-IP $remote_addr;
        }

  這樣就實現了負載均衡,通過http://10.160.65.44/可以輪詢訪問到定義的兩個節點。

  在upstream里面修改websrvs的定義:

    upstream websrvs {
        server 192.168.144.49 weight=1 max_fails=2 fail_timeout=2s;
        server 192.168.144.50 weight=1 max_fails=2 fail_timeout=2s;
        }

  我們任意停掉一台機器的HTTP服務,負載均衡會自動檢測到故障的服務器,而不去訪問。

  如果兩台主機都down掉,我們定義一個默認的頁面:/web/errorpages/bbs/index.html

  定義一台server

    server {
        listen  localhost:8080;
        server_name     localhost;
        root    /web/errorpages;
        index   index.html;
    }

  在upstream中定義backup server

    upstream websrvs {
        server 192.168.144.49 weight=1 max_fails=2 fail_timeout=2s;
        server 192.168.144.50 weight=1 max_fails=2 fail_timeout=2s;
        server 127.0.0.1:8080 backup;
        }

  這樣,當服務器訪問到的所有后端服務都down掉的時候,就會訪問到backup server定義的默認頁面。 

  down,表示當前的server暫時不參與負載均衡。
  backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,才會請求backup機器,因此這台機器的壓力最輕。
  max_fails,允許請求失敗的次數,默認為1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。
  fail_timeout,在經歷了max_fails次失敗后,暫停服務的時間。max_fails可以和fail_timeout一起使用。
  注,當負載調度算法為ip_hash時,后端服務器在負載均衡調度中的狀態不能是weight和backup。

 6.Nginx的調度算法

round-robin;
ip-hash;  #使用ip_hash的時候不能使用backup,不然如果定位到backup上去了就會一直定位到backup上去。
least_conn;

7.Nginx的緩存

  cache:共享內存,存儲鍵和緩存對象元數據

  磁盤空間:存儲數據

  利用proxy_cache_path,不能定義在server{}上下文中,只能定義在httpd的上下文中。

  修改nginx.conf文件

    upstream websrvs {
        server 192.168.144.49 weight=1; server 192.168.144.50 weight=1; } proxy_temp_path /tmp/proxy_temp_dir; proxy_cache_path /tmp/proxy_cache_dir levels=1:2 keys_zone=first:200m inactive=3d max_size=30g; location / { proxy_pass http://websrvs/bbs/; proxy_set_header X-Real-IP $remote_addr; proxy_cache first; proxy_cache_valid 200 302 7d; proxy_cache_valid 301 3d; proxy_cache_valid any 1m; }

  訪問以后,在對應的/tmp/proxy_cache_dir目錄下有生成相應的cache文件:

[root@nginx proxy_cache_dir]# tree 
.
`-- 3 `-- d8 `-- 73d4237ea45b2bde4eeccdd106ac3d83 2 directories, 1 file

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM