Nginx TCP和UDP負載均衡

1    介紹

負載均衡是指有效的經過多個後端服務器分發網絡流量。正則表達式

Nginx能代理和負載均衡TCP、UDP通訊。TCP(傳輸控制協議)、UDP(用戶數據包協議)是許多流行應用程序和服務的協議,例如LDAP、MySQL和RTMP使用TCP協議,DNS、syslog和RADIUS。算法

2    須要

  • 使用--with-stream配置標記構建最新Nginx,或最新的Nginx+(不須要額外構建步驟)數據庫

  • 應用程序、數據庫或服務基於TCP或UDP通訊後端

  • Upstream服務器運行相同的應用程序、數據庫或服務實例緩存

3    配置反向代理

首先,你須要配置反向代理,所以,Nginx轉發來自客戶端的TCP鏈接或UDP數據包到upstream組或一個代理服務器。服務器

打開Nginx配置文件並執行如下步驟:網絡

  • 建立頂級stream {}塊app

stream {負載均衡

...tcp

}

 在頂級stream {}上下文中爲每一個虛擬主機定義一個或多個server {}配置塊。

  • 在每一個server {}配置塊中包括listen指令定義服務器監聽的IP地址和/或端口。對於UDP通訊,也包括udp參數。TCP是stream上下文的默認協議:

stream {

    server {

        listen 12345;

        ...

    }

    server {

        listen 53 udp;

        ...

    }

    ...

}

  •  包括proxy_pass指令定義代理服務器或upstream組

stream {

    server {

        listen     12345;

        proxy_pass stream_backend;

    }

 

    server {

        listen     12346;

        proxy_pass backend.example.com:12346;

    }

 

    server {

        listen     53 udp;

        proxy_pass dns_servers;

    }

    ...

}

  •  可選,若是你的代理服務器多個網絡接口,你能配置Nginx選擇源IP地址鏈接到upstream服務器。代理服務器在Nginx後面配置爲從特定IP網絡或IP地址範圍接收鏈接是有用的。

 指定proxy_bind指令和必要的網絡接口的IP地址:

stream {

    ...

    server {

        listen     127.0.0.1:12345;

        proxy_pass backend.example.com:12345;

        proxy_bind 127.0.0.1:12345;

    }

}

  • 可選,你能調整兩個內存緩存,Nginx能從客戶端和upstream鏈接放入數據。若是有一個體積小的數據,減小緩存能夠節約內存資源。若是有大量數據,增長緩存大小減小套接字讀寫操做次數。一旦在一個鏈接接收到數據,Nginx讀取它並在其它鏈接轉發。緩存使用proxy_buffer_size指令控制:

stream {

    ...

    server {

        listen            127.0.0.1:12345;

        proxy_pass        backend.example.com:12345;

        proxy_buffer_size 16k;

    }

}

4    配置TCP和UDP負載均衡

爲了配置負載均衡:

一、建立服務器組,或upstream組將負載均衡通訊。定義一個或多個upstream {}配置塊在頂級steam {}上下文,設置upstream組的名字,例如,TCP服務器steam_backed和UDP服務器dns_servers:

stream {

    upstream stream_backend {

        ...    

    }

 

    upstream dns_servers {

        ...    

    }

    ...

}

二、在upstream組中填充upstream服務器。upstream {}塊中,爲每一個upstream服務器添加server指令,指定IP地址或主機名(解析多個IP地址)和必須的端口號。 

 stream {

    upstream stream_backend {

        server backend1.example.com:12345;

        server backend2.example.com:12345;

        server backend3.example.com:12346;

        ...

    }

    upstream dns_servers {

        server 192.168.136.130:53;

        server 192.168.136.131:53;

        ...

    }

    ...

}

三、配置負載均衡方法

  • round-robin(輪詢)——默認,Nginx使用輪詢算法負載均衡通訊。由於是默認方法,因此沒有round-robin指令;只建立upstream配置塊在頂級stream上下文並像以前步驟添加server指令。

  • last_conn(最少鏈接)——Nginx選擇當前活躍鏈接數較少的服務器。

  • least_tome——Nginx選擇最低平均延遲和最少活躍鏈接的服務器。最低活躍鏈接基於least_time指令的如下參數計算:

    • connect——鏈接upstream服務器的時間

    • first_byte——接收第一個數據字節的時間

    • last_byte——從服務器接收完整響應的時間

upstream stream_backend {

    least_time first_byte;

 

    server backend1.example.com:12345;

    server backend2.example.com:12345;

    server backend3.example.com:12346;

}

  • hash——Nginx基於用戶定義鍵選擇服務器,例如,源IP地址

upstream stream_backend {

    hash $remote_addr;

 

    server backend1.example.com:12345;

    server backend2.example.com:12345;

    server backend3.example.com:12346;

}

hash負載均衡方法也用於配置回話持久化。哈希函數基於客戶端IP地址,來自指定客戶端的鏈接老是傳遞給相同的服務器,除非服務器宕機或不可用。指定一個可選的consistent參數應用ketama一致性哈希方法

hash $remote_addr consistent; 

四、可選,指定最大鏈接數、服務器權重等

 upstream stream_backend {

    hash   $remote_addr consistent;

    server backend1.example.com:12345 weight=5;

    server backend2.example.com:12345;

    server backend3.example.com:12346 max_conns=3;

}

 

upstream dns_servers {

    least_conn;

    server 192.168.136.130:53;

    server 192.168.136.131:53;

    ...

}

若是你經過主機名標識服務器,配置主機名解析多個IP地址,而後Nginx經過IP地址使用輪詢算法負載均衡。在這種狀況下,你必須在proxy_pass指令中指定服務器的端口號,沒必要指定協議:

stream {

    ...

    server {

        listen     12345;

        proxy_pass backend.example.com:12345;

    }

}

5    被動健康檢查

若是試圖鏈接upstream服務器超時或出錯,Nginx標記服務器爲不可用並在指定時間內中止發送請求給該服務器。爲了定義不可用條件,包括如下參數到server指令:

  • fail_timeout——同Nginx負載均衡章節

  • max_fails——同Nginx負載均衡章節

fail_timeout默認爲10秒,max_fails默認爲1次。所以,若是鏈接10秒內嘗試至少一次失敗,Nginx標記服務器10秒內不可用。

upstream stream_backend {

    server backend1.example.com:12345 weight=5;

    server backend2.example.com:12345 max_fails=2 fail_timeout=30s;

    server backend3.example.com:12346 max_conns=3;

}

6    主動健康檢查

健康檢查能配置測試廣範圍的錯誤類型。例如,Nginx能不斷測試upstream服務器的響應能力並避免服務器故障。

6.1    工做原理

Nginx發送特定健康檢查請求到每一個upstream服務器並檢查響應知足某一條件。若是不能鏈接到服務器,那麼健康檢查失敗,服務器不健康。Nginx不代理客戶端鏈接到不健康的服務器。若是多個健康檢查定義在服務器組中,相應服務器的任意一個檢查不經過該服務器都是不健康的。

6.2    預備條件

  • 你在stream上下文中配置upstream服務器組

stream {

    upstream stream_backend {

 

    server backend1.example.com:12345;

    server backend2.example.com:12345;

    server backend3.example.com:12345;

   }

}

  • 你配置一臺服務器傳遞通訊(在這種狀況下,是TCP鏈接)到服務器組

server {

    listen     12345;

    proxy_pass stream_backend;

}

6.3    基礎配置

  • 指定共享內存區域

stream {

    upstream stream_backend {

 

        zone   stream_backend 64k;

        server backend1.example.com:12345;

        server backend2.example.com:12345;

        server backend3.example.com:12345;

   }

}

  • 啓用健康檢查 

server {

    listen        12345;

    proxy_pass    stream_backend;

    health_check;

    health_check_timeout 5s;

}

health_check指令啓用健康檢查功能,health_check_timeout覆蓋健康檢查的proxy_timeout。

爲了啓用健康檢查UDP通訊,爲health_check指令指定udp參數:

server {

    listen       5053;

    proxy_pass   dns_servers;

    health_check udp;

    health_check_timeout 5s;

}

 6.4    健康檢查調優

默認,Nginx嘗試每5秒鏈接upstream服務器組中的每臺服務器。若是不能創建鏈接,Nginx認爲健康檢查失敗,標記爲不健康,中止轉發客戶端鏈接到服務器。

爲了改變默認行爲,包括參數到health_check指令:

  • interval——Nginx多久發送一次健康檢查請求(默認5秒)

  • passes——服務器連續多少次響應健康檢查認爲是健康(默認是1次)

  • fails——服務器連續多少次健康檢查失敗認爲是不健康(默認是1次)

server {

    listen       12345;

    proxy_pass   stream_backend;

    health_check interval=10 passes=2 fails=3;

}

在例子中,TCP健康檢查時間間隔增長到10秒,服務器認爲連續3次健康檢查失敗是不健康,服務器須要連續2次經過健康檢查纔再次認爲是健康的。

默認,Nginx發送健康檢查消息給upstream塊中的server指令的特定端口。你能指定其它的健康檢查端口,當許多服務在相同主機檢查健康時很是有用。爲了覆蓋端口,指定health_check指令的port參數:

server {

    listen       12345;

    proxy_pass   stream_backend;

    health_check port=8080;

}

 6.5    使用match配置塊調優健康檢查

你能經過配置大量健康檢查測試驗證服務響應。這些測試放置在stream{}上下文中的match {}配置塊。指定match {}塊並設置它的名字,例如,tcp_test:

stream {

    ...

    match  tcp_test {

        ...

    }

}

而後在health_check指令包括match參數和match塊相同名稱引用塊: 

stream {

    server {

        listen       12345;

        health_check match=tcp_test;

        proxy_pass   stream_backend;

    }

}

健康檢查的條件或測試使用send和expect參數設置:

  • send——發送給服務器文本字符串或十六進制字符(「/x」後面跟兩個十六進制數字)
  • expect——服務器返回的數據匹配的字符串貨正則表達式

這些參數能用於不一樣的組合,但不能同時制定超過一個send和一個expect參數。參數配置也依賴於使用(TCP或UDP)的協議。

6.5.1    調優TCP健康檢查

爲了調優TCP健康檢查,你能組合send和expect參數:

  • 若是沒有send或expect參數指定,測試鏈接服務器能力。

  • 若是expect參數被指定,服務器指望無條件發送數據:

match pop3 {

    expect ~* "\+OK";

}

  • 若是send參數指定,它指望鏈接將成功創建並指定字符串發送給服務器: 

match pop_quit {

    send QUIT;

}

  • 若是send和expect參數被指定 

stream {

    upstream   stream_backend {

        zone   upstream_backend 64k;

        server backend1.example.com:12345;

    }

 

    match http {

        send      "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";

        expect ~* "200 OK";

    }

 

    server {

    listen       12345;

    health_check match=http;

    proxy_pass   stream_backend;

    }

}

例子顯示爲了健康檢查傳入,HTTP請求必須發送到服務器,並指望服務器結果包含」200 OK」表示HTTP響應成功。

6.5.2    UDP健康檢查調優

爲了調優UDP健康檢查,你應該指定send和expect參數:

  • NTP例子

match ntp {

   send \xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;

   expect ~* \x24;

}

  • DNS例子

match dns {

   send \x00\x2a\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x73\x74\x6c\x04\x75\x6d\x73\x6c\x03\x65\x64\x75\x00\x00\x01\x00\x01;

   expect ~* "health.is.good";

}

7    動態配置

Upstream服務器組能容易使用簡單的HTTP接口從新動態配置。使用該接口,你能瀏覽全部服務器在upstream組或特定服務器,修改服務器參數,並添加或刪除upstream服務器。

爲了啓用動態配置:

  • 建立頂級http {}塊或確保在你的配置文件中存在

http {

    ...

}

  • 建立配置請求的location,例如,upstream_conf。

http {

 

    server {

        location /upstream_conf {

            ...

        }

   }        

}

  • 在該location中指定upstream_conf指令——一個能用於解釋和從新配置upstream組的處理器

http {

 

    server {

        location /upstream_conf {

            upstream_conf;

            ...

        }

   }        

}

  • 限制該location的訪問

 

http {

 

    server {

        location /upstream_conf {

            upstream_conf;

            allow 127.0.0.1;

            deny  all;

        }

   }        

}

  •  建立共享內存區域

stream {

    upstream stream_backend {

        zone backend 64k;

        ...

    }

}

7.1    動態配置例子

stream {

    ...

    upstream appservers {

        zone appservers 64k;

 

        server appserv1.example.com:12345 weight=5;

        server appserv2.example.com:12345 fail_timeout=5s;

 

        server backup1.example.com:12345 backup;

        server backup2.example.com:12345 backup;

    }

 

    server {

        proxy_pass appservers;

        health_check;

    }

}

 

http {

    ...

    server {

        location /upstream_conf {

            upstream_conf;

            allow 127.0.0.1;

            deny  all;

        }

    }

}

  •  瀏覽全部備機

http://127.0.0.1/upstream_conf?stream=&upstream=appservers&backup=

  •  添加新服務器到服務器組

http://127.0.0.1/upstream_conf?stream=&add=&upstream=appservers&server=appserv3.example.com:12345&weight=2&max_fails=3

  •  從服務器組刪除服務器

http://127.0.0.1/upstream_conf?stream=&remove=&upstream=appservers&id=2

  • 修改指定服務器

 http://127.0.0.1/upstream_conf?stream=&upstream=appservers&id=2&down=

8    TCP和UDP負載均衡配置例子

stream {

    upstream stream_backend {

        least_conn;

        server backend1.example.com:12345 weight=5;

        server backend2.example.com:12345 max_fails=2 fail_timeout=30s;

        server backend3.example.com:12346 max_conns=3;

    }

 

    upstream dns_servers {

        least_conn;

        server 192.168.136.130:53;

        server 192.168.136.131:53;

        server 192.168.136.132:53;

    }

 

    server {

        listen        12345;

        proxy_pass    backend;

        proxy_timeout 3s;

        proxy_connect_timeout 1s;

    }

 

    server {

        listen     53 udp;

        proxy_pass dns_servers;

    }

 

    server {

        listen     12346;

        proxy_pass backend.example.com:12346;

    }

}

相關文章
相關標籤/搜索