nginx反向代理和負載均衡策略實戰案例

歡迎關注:glmapper_2018php

引言

先來看下nginx在web服務器排名上的趨勢: html

存在即合理,那爲何要使用nginx呢?這得看看nginx能幫咱們作些什麼。nginx

首先,nginx能作反向代理【關於反向代理和正向代理此處不作說明了,感興趣的小夥伴自行谷歌】;比方說,我想在本地使用 www.glmapper1.com 的域名去訪問www.taobao.com。那麼這個時候咱們就能夠經過nginx去實現。web

再者,nginx能實現負載均衡,什麼是負載均衡呢?就是說應用部署在不一樣的服務器上,可是經過統一的域名進入,nginx則對請求進行分發,將請求分發到不一樣的服務器上去處理,這樣就能夠有效的減輕了單臺服務器的壓力。算法

在上面這兩種狀況下,nginx服務器的做用都只是做爲分發服務器,真正的內容,咱們能夠放在其餘的服務器上,這樣來,還能起到一層安全隔壁的做用,nginx做爲隔離層。spring

解決跨域問題後端

同源:URL由協議、域名、端口和路徑組成,若是兩個URL的協議、域名和端口相同,則表示他們同源。跨域

瀏覽器的同源策略:瀏覽器的同源策略,限制了來自不一樣源的"document"或腳本,對當前"document"讀取或設置某些屬性。從一個域上加載的腳本不容許訪問另一個域的文檔屬性。瀏覽器

由於nginx和tomcat不能共用同一端口,url同樣,端口不一樣,這樣就會有跨域問題。緩存

PS:點到爲止,這裏本次測試沒有涉及,就不妄自菲薄了!!!

配置文件解析

配置文件主要由四部分組成:

  • main(全區設置)
  • server(主機配置)
  • http(控制着nginx http處理的全部核心特性)
    • location(URL匹配特定位置設置)。
  • upstream(負載均衡服務器設置)

下面以默認的配置文件來講明下具體的配置文件屬性含義:

#Nginx的worker進程運行用戶以及用戶組
#user nobody;

#Nginx開啓的進程數
worker_processes  1;

#定義全局錯誤日誌定義類型,[debug|info|notice|warn|crit]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#指定進程ID存儲文件位置
#pid logs/nginx.pid;


#事件配置
events {
    
    
    #use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
    #epoll模型是Linux內核中的高性能網絡I/O模型,若是在mac上面,就用kqueue模型。
    use kqueue;
    
    #每一個進程能夠處理的最大鏈接數,理論上每臺nginx服務器的最大鏈接數爲worker_processes*worker_connections。理論值:worker_rlimit_nofile/worker_processes
    worker_connections  1024;
}

#http參數
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"';
    
    #鏈接日誌的路徑,指定的日誌格式放在最後。
    #access_log logs/access.log main;

    #開啓高效傳輸模式
    sendfile        on;
    
    #防止網絡阻塞
    #tcp_nopush on;

    #客戶端鏈接超時時間,單位是秒
    #keepalive_timeout 0;
    keepalive_timeout  65;

    #開啓gzip壓縮輸出
    #gzip on;

    #虛擬主機基本設置
    server {
        #監聽的端口號
        listen       80;
        #訪問域名
        server_name  localhost;
        
        #編碼格式,若是網頁格式與當前配置的不一樣的話將會被自動轉碼
        #charset koi8-r;

        #虛擬主機訪問日誌定義
        #access_log logs/host.access.log main;
        
        #對URL進行匹配
        location / {
            #訪問路徑,可相對也可絕對路徑
            root   html;
            #首頁文件,匹配順序按照配置順序匹配
            index  index.html index.htm;
        }
        
        #錯誤信息返回頁面
        #error_page 404 /404.html;
        
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        
        #訪問URL以.php結尾則自動轉交給127.0.0.1
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        # proxy_pass http://127.0.0.1;
        #}
        
        #php腳本請求所有轉發給FastCGI處理
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        # root html;
        # fastcgi_pass 127.0.0.1:9000;
        # fastcgi_index index.php;
        # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
        # include fastcgi_params;
        #}

        #禁止訪問.ht頁面
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        # deny all;
        #}
    }

    #第二個虛擬主機配置
    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    # listen 8000;
    # listen somename:8080;
    # server_name somename alias another.alias;

    # location / {
    # root html;
    # index index.html index.htm;
    # }
    #}


    #HTTPS虛擬主機定義
    # HTTPS server
    #
    #server {
    # listen 443 ssl;
    # server_name localhost;

    # ssl_certificate cert.pem;
    # ssl_certificate_key cert.key;

    # ssl_session_cache shared:SSL:1m;
    # ssl_session_timeout 5m;

    # ssl_ciphers HIGH:!aNULL:!MD5;
    # ssl_prefer_server_ciphers on;

    # location / {
    # root html;
    # index index.html index.htm;
    # }
    #}
    include servers/*;
}

複製代碼

反向代理實例

假設我如今須要本地訪問www.baidu.com;配置以下:

server {
    #監聽80端口
    listen 80;
    server_name localhost;
     # individual nginx logs for this web vhost
    access_log /tmp/access.log;
    error_log  /tmp/error.log ;

    location / {
        proxy_pass http://www.baidu.com;
    }
複製代碼

驗證結果:

能夠看到,我在瀏覽器中使用localhost打開了百度的首頁...

負載均衡實例

下面主要驗證最經常使用的三種負載策略。虛擬主機配置:

server {
    #監聽80端口
    listen 80;
    server_name localhost;
    
    # individual nginx logs for this web vhost
    access_log /tmp/access.log;
    error_log  /tmp/error.log ;

    location / {
        #負載均衡
        #輪詢 
        #proxy_pass http://polling_strategy;
        #weight權重
        #proxy_pass http://weight_strategy;
        #ip_hash
        # proxy_pass http://ip_hash_strategy;
        #fair
        # proxy_pass http://fair_strategy;
        #url_hash
        # proxy_pass http://url_hash_strategy;
        #重定向
        #rewrite ^ http://localhost:8080;
    }
複製代碼

輪詢策略

# 一、輪詢(默認)
# 每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。 
upstream polling_strategy { 
    server glmapper.net:8080; # 應用服務器1
    server glmapper.net:8081; # 應用服務器2
} 
複製代碼

測試結果(經過端口號來區分當前訪問):

8081:hello
8080:hello
8081:hello
8080:hello
複製代碼

權重策略

#二、指定權重
#指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。 
upstream  weight_strategy { 
    server glmapper.net:8080 weight=1; # 應用服務器1
    server glmapper.net:8081 weight=9; # 應用服務器2
}
複製代碼

測試結果:總訪問次數15次,根據上面的權重配置,兩臺機器的訪問比重:2:13;知足預期!

ip hash策略

#三、IP綁定 ip_hash
#每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,
#能夠解決session的問題;在不考慮引入分佈式session的狀況下,
#原生HttpSession只對當前servlet容器的上下文環境有效
upstream ip_hash_strategy { 
    ip_hash; 
    server glmapper.net:8080; # 應用服務器1
    server glmapper.net:8081; # 應用服務器2
} 
複製代碼

iphash 算法:ip是基本的點分十進制,將ip的前三個端做爲參數加入hash函數。這樣作的目的是保證ip地址前三位相同的用戶通過hash計算將分配到相同的後端server。做者的這個考慮是極爲可取的,所以ip地址前三位相同一般意味着來着同一個局域網或者相鄰區域,使用相同的後端服務讓nginx在必定程度上更具備一致性。

爲何說要解釋下iphash,由於採坑了;和豬弟在進行這個策略測試時使用了5臺機器來測試的,5臺機器均在同一個局域網內【192.168.3.X】;測試時發現5臺機器每次都路由到了同一個服務器上,一開始覺得是配置問題,可是排查以後也排除了這個可能性。最後考慮到多是對於同網段的ip作了特殊處理,驗證以後確認了猜想。

其餘負載均衡策略

這裏由於須要安裝三方插件,時間有限就不驗證了,知悉便可!

#四、fair(第三方)
#按後端服務器的響應時間來分配請求,響應時間短的優先分配。 
upstream fair_strategy { 
    server glmapper.net:8080; # 應用服務器1
    server glmapper.net:8081; # 應用服務器2
    fair; 
} 

#五、url_hash(第三方)
#按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,
#後端服務器爲緩存時比較有效。 
upstream url_hash_strategy { 
    server glmapper.net:8080; # 應用服務器1
    server glmapper.net:8081; # 應用服務器2 
    hash $request_uri; 
    hash_method crc32; 
} 
複製代碼

重定向rewrite

location / {
    #重定向
    #rewrite ^ http://localhost:8080;
}
複製代碼

驗證思路:本地使用localhost:80端口進行訪問,根據nginx的配置,若是重定向沒有生效,則最後會停留在當前localhost:80這個路徑,瀏覽器中的地址欄地址不會發生改變;若是生效了則地址欄地址變爲localhost:8080;

經過驗證,知足預期!

總結

本文先對nginx的做用和基本的配置作了簡單說明;而後經過負載均衡的實例測試了不一樣負載均衡算法的具體應用反饋結果。幫助本身更加深入的理解nginx服務器中的一些配置細節。感謝劉祕提供的helloworld程序【基於springboot的腳手架,有須要的能夠聯繫他獲取;還有就是劉祕是個男的...😜】

參考

  • http://nginx.org/
  • https://www.nginx.com/
  • http://www.sohu.com/a/161411719_324809
相關文章
相關標籤/搜索