[root@server1 ~]# yum install -y haproxy##安裝
[root@server1 ~]# rpm -qi haproxy##檢視詳情資訊
Name : haproxy
Version : 1.5.18##版本號
Release : 8.el7
Architecture: x86_64
Install Date: Sun 09 Aug 2020 09:37:17 AM CST
Group : System Environment/Daemons
Size : 2690238
License : GPLv2+
Signature : RSA/SHA256, Thu 26 Jul 2018 10:00:42 AM CST, Key ID 199e2f91fd431d51
Source RPM : haproxy-1.5.18-8.el7.src.rpm
Build Date : Wed 25 Jul 2018 11:16:41 PM CST
Build Host : x86-040.build.eng.bos.redhat.com
Relocations : (not relocatable)
Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
Vendor : Red Hat, Inc.
URL : http://www.haproxy.org/
Summary : TCP/HTTP proxy and load balancer for high availability environments
[root@server1 ~]# rpm -ql haproxy
/etc/haproxy
/etc/haproxy/haproxy.cfg ##組態檔
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
/usr/bin/halog
/usr/bin/iprange
/usr/lib/systemd/system/haproxy.service
/usr/sbin/haproxy
us | 微秒(microseconds),即1/1000000秒 |
---|---|
ms | 毫秒(milliseconds),即1/10000 秒 |
s: | 秒(seconds) |
m | 分鐘(minutes) |
h | 小時(hours) |
d | 天(days) |
global
log 127.0.0.1 local2 ##定義全域性的syslog伺服器,最多可以定義兩個;
chroot /var/lib/haproxy ##修改haproxy的工作目錄至指定的目錄並在放棄許可權之前執行chroot()操作,可以提升haproxy的安全級別,不過需要注意的是要確保指定的目錄爲空目錄且任何使用者均不能有寫許可權
pidfile /var/run/haproxy.pid ##當前進程id檔案
maxconn 4000 #最大連線數
user haproxy#所屬使用者
group haproxy#所屬組
daemon ##讓haproxy以守護行程的方式工作於後台,其等同於「-D」選項的功能,當然,也可以在命令列中以「-db」選項將其禁用;
# turn on stats unix socket
stats socket /var/lib/haproxy/stats#基於原生的檔案傳輸
defaults
mode http##預設的模式mode{ tcp|http|health} ,tcp是4層,http是7層,health返回ok
log global##應用全域性的日誌設定
option httplog
##啓用日誌HTTP請求,預設haproxy日誌記錄是不記錄HTTP請求日誌
option dontlognull
#啓用該項,日誌中將不會記錄空連線。所謂空連線就是在上遊的負載均衡器或者監控系統爲了探測該服務是否存活可用時,需要定期的連線或者獲取某一固定的元件或頁面,或者探測掃描埠是否在監聽或開放等動作被稱爲空連線;官方文件中標註,如果該服務上遊沒有其他的負載均衡器的話,建議不要使用該參數,因爲網際網路上的惡意掃描或其他動作就不會被記錄下來
option http-server-close ##每次請求完畢後主動關閉http通道
option forwardfor except 127.0.0.0/8#如果伺服器上的應用程式想記錄發起請求的用戶端的IP地址,需要設定此選項,這樣 HAProxy會把用戶端的IP資訊發送給伺服器,在HTTP請求中新增"X-Forwarded-For"欄位。啓用X-Forwarded-For,在requests頭部插入用戶端IP發送給後端的server,使後端server獲取到用戶端的真實IP
option redispatch
# 當使用了cookie時,haproxy將會將其請求的後端伺服器的serverID插入到cookie中,以保證對談的SESSION永續性;而此時,如果後端的伺服器宕掉了, 但是用戶端的cookie是不會重新整理的,如果設定此參數,將會將客戶的請求強制定向到另外一個後端server上,以保證服務的正常。
retries 3##定義連線後端伺服器的失敗重連次數,連線失敗次數超過此值後將會將對應後端伺服器標記爲不可用
timeout http-request 10s ##在用戶端建立連線但不請求數據時,關閉用戶端連線
timeout queue 1m##等待最大時長
timeout connect 10s##定義haproxy將用戶端請求轉發至後端伺服器所等待的超時時長
timeout client 1m ##用戶端非活動狀態的超時時長
timeout server 1m##用戶端與伺服器端建立連線後,等待伺服器端的超長時長
timeout http-keep-alive 10s ##定義保持連線的超長時長
timeout check 10s##健康狀態監測的超時時間,過短會誤判,過長資源消耗
maxconn 3000 ##設定每個haproxy進程所接受的最大併發連線數,其等同於命令列選項「-n」;「ulimit -n」自動計算的結果正是參照此參數設定的;
frontend main *:80 ##監聽埠爲80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend app##預設存取的是app
backend static
#使用了靜態動態分離(如果url_path匹配 .jpg .gif .png .css .js靜態檔案則存取此後端)
balance roundrobin
server static 127.0.0.1:4331 check
##靜態檔案部署在本機(也可以部署在其他機器)
backend app
#定義一個名爲app後端部分。PS:此處app只是一個自定義名字而已,但是需要與frontend裏面設定項default_backend 值相一致
balance roundrobin
server app1 127.0.0.1:5001 check
server app2 127.0.0.1:5002 check
server app3 127.0.0.1:5003 check
server app4 127.0.0.1:5004 check
roundrobin:基於權重進行輪叫,在伺服器的處理時間保持均勻分佈時,這是最平衡、最公平的演算法。此演算法是動態的,這表示其權重可以在執行時進行調整,不過,在設計上,每個後端伺服器僅能最多接受4128個連線;並支援慢啓動。
static-rr:基於權重進行輪叫,與roundrobin類似,但是爲靜態方法,在執行時調整其伺服器權重不會生效;不過,其在後端伺服器連線數上沒有限制;不支援慢啓動,在高負荷的情況下,伺服器重新上線時會立即被分配大量連線。
leastconn(WLC):適用於長連線的對談,新的連線請求被派發至具有最少連線數目的後端伺服器;在有着較長時間對談的場景中推薦使用此演算法,如LDAP、SQL等,其並不太適用於較短對談的應用層協定,如HTTP;此演算法是動態的,可以在執行時調整其權重;
source:將請求的源地址進行hash運算,並由後端伺服器的權重總數相除後派發至某匹配的伺服器;這可以使得同一個用戶端IP的請求始終被派發至某特定的伺服器;不過,當伺服器權重總數發生變化時,如某伺服器宕機或新增了新的伺服器,許多用戶端的請求可能會被派發至與此前請求不同的伺服器;常用於負載均衡無cookie功能的基於TCP的協定;其預設爲靜態,不過也可以使用hash-type修改此特性;
1)對原地址hash,第一次排程時使用WLC source:IP層,位於同一個NAT伺服器背後的多個請求都會定向至同一個upstream
server,不利於負載均衡,一般只有不支援使用cookie插入又需要保持對談時使用 cookie:應用層,有更好的負載均衡效果;2)hash/weight%ip :除以權重取模
uri:對URI的左半部分(「問題」標記之前的部分)或整個URI進行hash運算,並由伺服器的總權重相除後派發至某匹配的伺服器;這可以使得對同一個URI的請求總是被派發至某特定的伺服器,除非伺服器的權重總數發生了變化;此演算法常用於代理快取或反病毒代理以提高快取的命中率;需要注意的是,此演算法僅應用於HTTP後端伺服器場景;其預設爲靜態演算法,不過也可以使用hash-type修改此特性;
url_param:通過爲URL指定的參數在每個HTTP GET請求中將會被檢索;如果找到了指定的參數且其通過等於號「=」被賦予了一個值,那麼此值將被執行hash運算並被伺服器的總權重相除後派發至某匹配的伺服器;此演算法可以通過追蹤請求中的使用者標識進而確保同一個使用者ID的請求將被送往同一個特定的伺服器,除非伺服器的總權重發生了變化;如果某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫演算法對相應請求進行排程;此演算法預設爲靜態的,不過其也可以使用hash-type修改此特性;
hdr():對於每個HTTP請求,通過指定的HTTP首部將會被檢索;如果相應的首部沒有出現或其沒有有效值,則使用輪叫演算法對相應請求進行排程;其有一個可選選項「use_domain_only」,可在指定檢索類似Host類的首部時僅計算域名部分(比如通過www.feiyu.com來說,僅計算feiyu字串的hash值)以降低hash演算法的運算量;此演算法預設爲靜態的,不過其也可以使用hash-type修改此特性;
rdp-cookie(name) 表示根據據cookie(name)來鎖定並雜湊每一次TCP請求。
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
stats uri /status ## 自定義統計頁面的url
stats auth admin:123456##統計頁面使用者名稱和密碼的設定
stats hide-version##隱藏統計頁面上的HAproxy的版本資訊
stats refresh 5s## 統計頁面自動重新整理時間
frontend main *:80
default_backend app
backend app
balance roundrobin
server app1 192.168.43.3:80 check
server app2 192.168.43.4:80 check
vim /etc/rsyslog.conf
systemctl restart rsyslog
重新啓動日誌服務vim /etc/haproxy.haproxy.cfg
rontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets##後面的允許格式可以自己進行增刪
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
backend static
balance roundrobin
server static 192.168.43.3:80 check
backend app
balance roundrobin
server app2 192.168.43.4:80 check
server backup 192.168.43.2:80 backup
[root@server4 html]# cat index.php
<?php
phpinfo()
?>
vim /etc/haproxy.haproxy.cfg
frontend main *:80
acl read_request method GET ##請求方法
acl read_request method POST
acl write_request method PUT
acl write_request method POST
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if read_request##如果是讀請求用 static
use_backend app if write_request ##如果是寫請求用 app
default_backend app
backend static
balance roundrobin
server static 192.168.43.3:80 check
backend app
balance roundrobin
server app2 192.168.43.4:80 check
server backup 192.168.43.2:80 backup
- [root@server3 html]# cat index.php
<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
[root@server3 html]# cat upload_file.php
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
}
}
}
else
{
echo "Invalid file";
}
?>
在server4中/var/www/html建立一個upload目錄並開滿許可權,用於圖片的寫入
chmod 777 /var/ww/html/upload
實驗結果測試
server4中upload下成功寫入上傳圖片