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

glmapper發表於2018-04-22

歡迎關注:glmapper_2018

引言

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

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

存在即合理,那為什麼要使用nginx呢?這得看看nginx能幫我們做些什麼。

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

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

在上面這兩種情況下,nginx伺服器的作用都只是作為分發伺服器,真正的內容,我們可以放在其他的伺服器上,這樣來,還能起到一層安全隔壁的作用,nginx作為隔離層。

解決跨域問題

同源: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;
    }
複製程式碼

驗證結果:

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

可以看到,我在瀏覽器中使用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;
    }
複製程式碼

輪詢策略

# 1、輪詢(預設)
# 每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。 
upstream polling_strategy { 
    server glmapper.net:8080; # 應用伺服器1
    server glmapper.net:8081; # 應用伺服器2
} 
複製程式碼

測試結果(通過埠號來區分當前訪問):

8081:hello
8080:hello
8081:hello
8080:hello
複製程式碼

權重策略

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

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

ip hash策略

#3、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做了特殊處理,驗證之後確認了猜測。

其他負載均衡策略

這裡因為需要安裝三方外掛,時間有限就不驗證了,知悉即可!

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

#5、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

相關文章