1. 程式人生 > >Nginx快速入門(二)反向代理與負載均衡

Nginx快速入門(二)反向代理與負載均衡

接下來我們將介紹Ngix 反向代理 、負載均衡 、HTTP伺服器(包含動靜分離) 、正向代理 等幾個方面,由於本人接觸使用也沒有多久,所以還會有很多不全以及錯誤的地方,還望大家指正 共同進步。

1.反向代理

反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連線的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。簡單來說就是真實的伺服器不能直接被外部網路訪問,所以需要一臺代理伺服器,而代理伺服器能被外部網路訪問的同時又跟真實伺服器在同一個網路環境,當然也可能是同一臺伺服器,埠不同而已。

我們很多人應該都用過淘寶,要知道每天同時連線到淘寶網站的訪問人數已經爆表,單個伺服器遠遠不能滿足人民日益增長的購買慾望了,此時就出現了一個大家耳熟能詳的名詞:分散式部署;也就是通過部署多臺伺服器來解決訪問人數限制的問題
在這裡插入圖片描述

上圖表示的是全國各地的使用者在淘寶客戶端發出請求,經過了Nginx 反向代理伺服器,nginx伺服器接收到之後,按照一定的規則分發給了後端的業務處理伺服器進行處理。

此時~請求的來源也就是客戶端是明確的,但是請求具體由哪臺伺服器處理的並不明確了。Nginx扮演的就是一個反向代理角色。

總結下:反向代理,主要用於伺服器叢集分散式部署的情況下,反向代理隱藏了伺服器的資訊

server {  
  listen       80;                                                         
  server_name  localhost;                                               
  client_max_body_size 1024M;

  location / {
    proxy_pass http://localhost:8080;
    proxy_set_header Host $host:$server_port;
  }
}

儲存配置檔案後啟動Nginx,這樣當我們訪問localhost的時候,就相當於訪問localhost:8080了

2.負載均衡

負載均衡也是Nginx常用的一個功能,負載均衡其意思就是分攤到多個操作單元上進行執行,例如Web伺服器、FTP伺服器、企業關鍵應用伺服器和其它關鍵任務伺服器等,從而共同完成工作任務。簡單而言就是當有2臺或以上伺服器時,根據規則隨機的將請求分發到指定的伺服器上處理,負載均衡配置一般都需要同時配置反向代理,通過反向代理跳轉到負載均衡。而Nginx目前支援自帶3種負載均衡策略,還有2種常用的第三方策略。

RR(預設)

每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。 簡單配置

upstream test {
  server localhost:8080;
  server localhost:8081;
}
server {
  listen       81;                                                         
  server_name  localhost;                                               
  client_max_body_size 1024M;

  location / {
    proxy_pass http://test;
    proxy_set_header Host $host:$server_port;
  }
}

這裡我配置了2臺伺服器,當然實際上是一臺,只是埠不一樣而已,而8081的伺服器是不存在的,也就是說訪問不到,但是我們訪問 http://localhost 的時候,也不會有問題,會預設跳轉到 http://localhost:8080 具體是因為Nginx會自動判斷伺服器的狀態,如果伺服器處於不能訪問(伺服器掛了),就不會跳轉到這臺伺服器,所以也避免了一臺伺服器掛了影響使用的情況,由於Nginx預設是RR策略,所以我們不需要其他更多的設定。

權重

指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況。 例如

  upstream test {
    server localhost:8080 weight=9;
    server localhost:8081 weight=1;
  }

那麼10次一般只會有1次會訪問到8081,而有9次會訪問到8080

ip_hash

上面的2種方式都有一個問題,那就是下一個請求來的時候請求可能分發到另外一個伺服器,當我們的程式不是無狀態的時候(採用了session儲存資料),這時候就有一個很大的很問題了,比如把登入資訊儲存到了session中,那麼跳轉到另外一臺伺服器的時候就需要重新登入了,所以很多時候我們需要一個客戶只訪問一個伺服器,那麼就需要用iphash了,iphash的每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。

upstream test {
  ip_hash;
  server localhost:8080;
  server localhost:8081;
}
fair(第三方)

按後端伺服器的響應時間來分配請求,響應時間短的優先分配。

upstream backend { 
  fair; 
  server localhost:8080;
  server localhost:8081;
}

url_hash(第三方)

按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。 在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method是使用的hash演算法

upstream backend { 
  hash $request_uri; 
  hash_method crc32; 
  server localhost:8080;
  server localhost:8081;
}

2.1 搭建負載均衡

nginx負載均衡原理圖

在這裡插入圖片描述
在nginx的nginx.conf裡面監聽80埠,並配置後端tomcat的地址,前端訪問的時候即可轉發到後端的tomcat

搭建步驟

2.1.1 首先我們將我們的伺服器複製兩份

cp -r apache-tomcat-7.0.47 tomcat8081  #複製
cp -r apache-tomcat-7.0.47 tomcat8082   #複製

2.1.2 分別修改tomcat8081,tomcat8082埠(需要修改三處)

vi tomcat8081/conf/server.xml
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
<Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
vi tomcat8082/conf/server.xml
<Server port="8006" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
<Connector port="8082" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
 <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />

2.1.3 防火牆開放埠

vi /etc/sysconfig/iptables 

-A INPUT -m state –-state NEW -m tcp -p tcp –-dport 8081 -j ACCEPT #(允許8001埠通過防火牆)
-A INPUT -m state –-state NEW -m tcp -p tcp –-dport 8082 -j ACCEPT #(允許8002埠通過防火牆)
-A INPUT -m state –-state NEW -m tcp -p tcp –-dport 80 -j ACCEPT #(允許8003埠通過防火牆)

service iptables restart  #重啟生效

2.1.4 在兩個tomcat的root目錄下分別放內容不一樣的index.html,然後啟動兩個tomcat

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>test</title>
  </head>
  <body>
 
    歡迎來到8082埠tomcat
  </body>
</html>
 cd /usr/local/tomcat8003/bin/
 ./startup.sh

可以看到 已經可以訪問了
在這裡插入圖片描述
在這裡插入圖片描述

2.1.5 修改nginx的配置檔案nginx.conf 並啟動

user root root; #使用什麼使用者啟動NGINX 在執行時使用哪個使用者哪個組
worker_processes 4; #啟動程序數,一般是18個,根據你的電腦CPU數,一般8個
worker_cpu_affinity 00000001 00000010 00000100 00001000; #CPU邏輯數——把每個程序分別綁在CPU上面,為每個程序分配一個CPU
#pid /usr/local/nginx/logs/nginx.pid
worker_rlimit_nofile 102400; #一個程序開啟的最大檔案數目,與NGINX併發連線有關係
 
#工作模式及連線數上限
events
{
  use epoll; #多路複用IO 基於LINUX2.6以上核心,可以大大提高NGINX的效能 uname -a檢視核心版本號
  worker_connections 102400; #單個worker process最大連線數,其中NGINX最大連線數=連線數*程序數,一般1GB記憶體的機器上可以開啟的最大數大約是10萬左右
  multi_accept on;   #儘可能多的接受請求,預設是關閉狀態
}
 
#處理http請求的一個應用配置段
http
{
  #引用mime.types,這個型別定義了很多,當web伺服器收到靜態的資原始檔請求時,依據請求檔案的字尾名在伺服器的MIME配置檔案中找到對應的MIME #Type,根據MIMETYPE設定並response響應型別(Content-type)
  include       mime.types; 
  default_type  application/octet-stream; #定義的資料流,有的時候預設型別可以指定為text,這跟我們的網頁釋出還是資源下載是有關係的
  fastcgi_intercept_errors on; #表示接收fastcgi輸出的http 1.0 response code
  charset utf-8;
  server_names_hash_bucket_size 128; #儲存伺服器名字的hash表
  #用來快取請求頭資訊的,容量4K,如果header頭資訊請求超過了,nginx會直接返回400錯誤,先根據client_header_buffer_size配置的值分配一個buffer,如果##分配的buffer無法容納request_line/request_header,那麼就會##再次根據large_client_header_buffers配置的引數分配large_buffer,如果large_buffer還是無#法容納,那麼就會返回414(處理request_line)/400(處理request_header)錯誤。
  client_header_buffer_size 4k; 
  large_client_header_buffers 4 32k;
  client_max_body_size 300m; #允許客戶端請求的最大單檔案位元組數 上傳檔案時根據需求設定這個引數
  #指定NGINX是否呼叫這個函式來輸出檔案,對於普通的檔案我們必須設定為ON,如果NGINX專門做為一個下載端的話可以關掉,好處是降低磁碟與網路的IO處理數及#系統的UPTIME
  sendfile on; 
  #autoindex on;開啟目錄列表訪問,適合下載伺服器
  tcp_nopush on; #防止網路阻塞
  #非常重要,根據實際情況設定值,超時時間,客戶端到服務端的連線持續有效時間,60秒內可避免重新建立連線,時間也不能設太長,太長的話,若請求數10000##,都佔用連線會把服務託死
  keepalive_timeout 60;
  tcp_nodelay on; #提高資料的實時響應性
  client_body_buffer_size 512k; #緩衝區代理緩衝使用者端請求的最大位元組數(請求多)
 
  proxy_connect_timeout   5; #nginx跟後端伺服器連線超時時間(代理連線超時)
  proxy_read_timeout      60; #連線成功後,後端伺服器響應時間(代理接收超時)
  proxy_send_timeout      5; #後端伺服器資料回傳時間(代理髮送超時)
  proxy_buffer_size       16k; #設定代理伺服器(nginx)儲存使用者頭資訊的緩衝區大小
  proxy_buffers           4 64k; #proxy_buffers緩衝區,網頁平均在32k以下的話,這樣設定
  proxy_busy_buffers_size 128k; #高負荷下緩衝大小
  proxy_temp_file_write_size 128k; #設定快取資料夾大小,大於這個值,將從upstream伺服器傳
 
  gzip on; #NGINX可以壓縮靜態資源,比如我的靜態資源有10M,壓縮後只有2M,那麼瀏覽器下載的就少了
  gzip_min_length  1k;
  gzip_buffers     4 16k;
  gzip_http_version 1.1;
  gzip_comp_level 2; #壓縮級別大小,最小1,最大9.值越小,壓縮後比例越小,CPU處理更快,1,10M壓縮完後8M,但設為9,壓縮完可能只有2M了。一般設定為2
  gzip_types       text/plain application/x-javascript text/css application/xml; #壓縮型別:text,js css xml 都會被壓縮
  gzip_vary on; #作用是在http響應中增加一行目的是改變反向代理伺服器的快取策略
 
#日誌格式 
log_format  main '$remote_addr - $remote_user [$time_local] "$request" ' #ip 遠端使用者 當地時間  請求URL
                 '$status $body_bytes_sent "$http_referer" ' #狀態  傳送的大小  響應的頭
         '"$http_user_agent" $request_time'; #客戶端使用的瀏覽器  頁面響應的時間
 
#動態轉發         
upstream web1 {
    #每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。配置了ip_hash就沒有負載均衡的效果了,每次訪問的都是同一個tomcat
    #ip_hash; 
    #轉發的後端的tomcat伺服器,weight表示轉發的權重,越大轉發的次數越多,機器效能不一樣配置的weight值不一樣     
     server   127.0.0.1:8082 weight=1 max_fails=2 fail_timeout=30s;
     server   127.0.0.1:8081 weight=8 max_fails=2 fail_timeout=30s;
}

 
server {
    listen       80; #監聽80埠
    server_name  192.168.52.128; #域名
    index  index.jsp index.html index.htm;
    root   /usr/local/nginx/html; #定義伺服器的預設網站根目錄位置
 
    #監聽完成以後通過斜杆(/)攔截請求轉發到後端的tomcat伺服器
    location / 
        {
            #如果後端的伺服器返回502504、執行超時等錯誤,自動將請求轉發到upstream負載均衡池中的另一臺伺服器,實現故障轉移。
            proxy_next_upstream http_502 http_504 error timeout invalid_header;
            proxy_set_header Host  $host; #獲取客戶端的主機名存到變數Host裡面,從而讓tomcat取到客戶端機器的資訊
            proxy_set_header X-Real-IP $remote_addr; #獲取客戶端的主機名存到變數X-Real-IP裡面,從而讓tomcat取到客戶端機器的資訊
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://web1; #跳轉到對應的應用web1
        }
 
    }
 
 
}

啟動nginx

/usr/local/nginx/sbin/nginx

我們多重新整理幾次 發現實現了負載均衡,根據權重訪問不同的伺服器
在這裡插入圖片描述

在這裡插入圖片描述