haproxy簡介
HAProxy是一個使用C語言編寫的自由及開源代碼軟件,其提供高可用性、負載均衡,以及基于TCP和HTTP的應(yīng)用程序代理。
HAProxy特別適用于那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運行在當前的硬件上,完全可以支持數(shù)以萬計的并發(fā)連接。并且它的運行模式使得它可以很簡單安全的整合進您當前的架構(gòu)中, 同時可以保護你的web服務(wù)器不被暴露到網(wǎng)絡(luò)上。
HAProxy實現(xiàn)了一種事件驅(qū)動,單一進程模型,此模型支持非常強大的開發(fā)并發(fā)連接數(shù)。多進程或多線程模型受內(nèi)存限制 、系統(tǒng)調(diào)度器限制以及無處不在的鎖限制,很少能處理數(shù)千并發(fā)連接。事件驅(qū)動模型因為更好的資源和時間管理的用戶空間實現(xiàn)所有這些任務(wù),所以沒問題。此模型的弊端是,在多核系統(tǒng)上,這些程序通常擴展性較差。這就是為什么他們必須進行優(yōu)化以使每個CPU時間片做更多的工作
包括GitHub、Bitbucket、stack Overflow、reddit、Tumbir、Twitter和Tuenti在內(nèi)的知名網(wǎng)站,及亞馬遜網(wǎng)絡(luò)服務(wù)系統(tǒng)都使用了HAProxy
haproxy與其他負載均衡的異同
相同點:在功能上,proxy通過反向代理方式實現(xiàn) WEB均衡負載。和 Nginx,ApacheProxy,lighttpd,Cheroke 等一樣。
不同點:Haproxy 并不是 web 服務(wù)器。以上提到所有帶反向代理均衡負載的產(chǎn)品,全都是WEB服務(wù)器。簡單說,就是他們能處理解析頁面。而Haproxy僅僅是一款的用于均衡負載的應(yīng)用代理。其自身并不能提供web服務(wù)。但其配置簡單,擁有非常不錯的服務(wù)器健康檢查功能還有專門的系統(tǒng)狀態(tài)監(jiān)控頁面,當其代理的后端服務(wù)器出現(xiàn)故障,HAProxy會自動將該服務(wù)器摘除,故障恢復(fù)后再自動將該服務(wù)器加入。
haproxy性能
HAProxy借助OS上幾種常見的技術(shù)來實現(xiàn)性能的最大化
- 單進程、事件驅(qū)動模型顯著降低了上下文切換的開銷及內(nèi)存占用。
- 事件檢查器允許其在高并發(fā)連接中對任何連接的任何事件實現(xiàn)即時探測。
- 在任何可用的情況下,單緩沖機制能以不復(fù)制任何數(shù)據(jù)的方式完成讀寫操作,這會節(jié)約大量的CPU時鐘周期及內(nèi)存帶寬
- 借助linux2.6上的splice系統(tǒng)調(diào)用,HAProxy可以實現(xiàn)零復(fù)制轉(zhuǎn)發(fā),在linux3.5及以上的OS中還可以實現(xiàn)零復(fù)制啟動
- 內(nèi)存分配器在固定大小的內(nèi)存池中可實現(xiàn)即時內(nèi)存分配,這能夠顯著減少創(chuàng)建一個會話的時長
- 樹型存儲:側(cè)重于使用作者多年前開發(fā)的彈性二叉樹,實現(xiàn)了以O(shè)(log(N))的低開銷來保持計時器命令、保持運行隊列命令及管理輪詢及最少連接隊列
- 優(yōu)化的HTTP首部分析:優(yōu)化的首部分析功能避免了在HTTP首部分析過程中重讀任何內(nèi)存區(qū)域
- 精心地降低了昂貴的系統(tǒng)調(diào)用,大部分工作都在用戶空間完成,如時間讀取、緩沖聚合及文件描述符的啟用和禁用等
實驗環(huán)境
| 主機 | IP |
|---|---|
| DR | 192.168.182.141 |
| rs1 | 192.168.182.130 |
| rs2 | 192.168.182.131 |
haproxy部署安裝web服務(wù)
配置流程
- 先成功配置httpd服務(wù),讓其訪問不同的內(nèi)容
- 再去配置DR調(diào)度器
- 然后進行驗證看能否調(diào)度到不同的內(nèi)容
這里是實驗環(huán)境,在生產(chǎn)環(huán)境中步驟與此一樣,但是要調(diào)度的內(nèi)容根據(jù)實際需求進行調(diào)整
因為官網(wǎng)無法使用所以去github去下載:https://github.com/haproxy/haproxy/tags?after=v2.5-dev1
第一步:
首先在rs1和rs2上安裝httpd
[root@rs1 ~]# yum -y install httpd
[root@rs2 html]# yum -y install httpd
啟動httpd服務(wù)
[root@rs1 ~]# systemctl start httpd
[root@rs2 html]# systemctl start httpd
因為這里rs1和rs2都是centos7.5,所以為了讓訪問界面不同,為了演示的效果修改web顯示頁面
修改rs的為web界面的顯示內(nèi)容
[root@rs2 html]# pwd
/var/www/html
[root@rs2 html]# cat index.html
This is rs2


第二步:
下載haproxy的源碼包
[root@DR ~]# wget https://github.com/haproxy/haproxy/archive/refs/tags/v2.4.0.tar.gz
安裝依賴包
[root@DR ~]# yum -y install make gcc pcre-devel bzip2-devel openssl-devel systemd-devel
創(chuàng)建用戶haproxy
[root@DR ~]# useradd -r -M -s /sbin/nologin haproxy
解壓源碼包
[root@DR ~]# tar xf haproxy-2.4.0.tar.gz
如何安裝haproxy在haproxy目錄的名為INSTALL的文件里面說明了
[root@DR haproxy-2.4.0]# vim INSTALL
[root@DR haproxy-2.4.0]# pwd
/root/haproxy-2.4.0


編譯安裝haproxy
[root@DR haproxy-2.4.0]# make clean
[root@DR haproxy-2.4.0]# make -j $(grep 'processor' /proc/cpuinfo |wc -l) \
TARGET=linux-glibc \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_PCRE=1 \
USE_SYSTEMD=1
make install PREFIX=/usr/local/haproxy
[root@DR haproxy-2.4.0]# make install PREFIX=/usr/local/haproxy //將haproxy安裝到/usr/local/haproxy里面
[root@DR ~]# which haproxy
/usr/bin/which: no haproxy in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
因為我們編譯的位置系統(tǒng)找不到所以需要設(shè)置環(huán)境變量
[root@DR ~]# echo 'export PATH=/usr/local/haproxy/sbin:$PATH' > /etc/profile.d/haproxy.sh
[root@DR ~]# source /etc/profile.d/haproxy.sh
[root@DR ~]# which haproxy
/usr/local/haproxy/sbin/haproxy
配置內(nèi)核參數(shù)
[root@DR haproxy]# echo 'net.ipv4.ip_nonlocal_bind = 1' >> /etc/sysctl.conf
[root@DR haproxy]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@DR haproxy]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
為haproxy提供配置文件
配置文件可以根據(jù)haproxy的解壓目錄的quick-test.cfg 的文件進行修改。
[root@DR ~]# mkdir /etc/haproxy
[root@DR ~]# cat > /etc/haproxy/haproxy.cfg <<EOF
#--------------全局配置----------------
global
log 127.0.0.1 local0 info
#log loghost local0 info
maxconn 20480
#chroot /usr/local/haproxy
pidfile /var/run/haproxy.pid
#maxconn 4000
user haproxy
group haproxy
daemon
#---------------------------------------------------------------------
#common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option dontlognull
option httpclose
option httplog
#option forwardfor
option redispatch
balance roundrobin
timeout connect 10s
timeout client 10s
timeout server 10s
timeout check 10s
maxconn 60000
retries 3
#--------------統(tǒng)計頁面配置------------------
listen admin_stats
bind 0.0.0.0:8189
stats enable
mode http
log global
stats uri /haproxy_stats
stats realm Haproxy\ Statistics
stats auth admin:admin
#stats hide-version
stats admin if TRUE
stats refresh 30s
#---------------web設(shè)置-----------------------
listen webcluster
bind 0.0.0.0:80
mode http
#option httpchk GET /index.html
log global
maxconn 3000
balance roundrobin
#下面兩行改為rs1和rs2的IP地址
server web01 192.168.182.130:80 check inter 2000 fall 5
server web02 192.168.182.131:80 check inter 2000 fall 5
EOF
編寫haproxy的service文件
這里的選項可以使用haproxy --help命令查看
[root@DR ~]# cat > /usr/lib/systemd/system/haproxy.service <<EOF
> [Unit]
> Description=HAProxy Load Balancer
> After=syslog.target network.target
>
> [Service]
> ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q //這是-c選項的意思 -c check mode : only check config files and exit ,檢查并退出 -q是quiet mode : don't display messages,靜默模式
> ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid
> ExecReload=/bin/kill -USR2 $MAINPID
>
> [Install]
> WantedBy=multi-user.target
> EOF
啟動服務(wù)并設(shè)置開機自啟
[root@DR ~]# systemctl enable --now haproxy
[root@DR ~]# ss -anlt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 0.0.0.0:8189 0.0.0.0:*
啟動日志服務(wù)
[root@DR ~]# vim /etc/rsyslog.conf
[root@DR ~]# systemctl restart rsyslog.service
65 local0.* /var/log/haproxy.log //添加此行內(nèi)容
第三步訪問并測試



這是haproxy的web界面

haproxy配置負載均衡https
生成證書
[root@rs1 ~]# yum -y install openssl
[root@web1 conf.d]# yum -y install mod_ssl
[root@rs1 keys]# openssl genrsa -out passport.com.key 2048
[root@rs1 keys]# openssl req -new -key passport.com.key -out passport.com.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HuBei
Locality Name (eg, city) [Default City]:WuHan
Organization Name (eg, company) [Default Company Ltd]:test
Organizational Unit Name (eg, section) []:passport
Common Name (eg, your name or your server's hostname) []:rs1.com
Email Address []:passport@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:1
string is too short, it needs to be at least 4 bytes long
A challenge password []:1@2.com
An optional company name []:
[root@rs1 keys]# openssl x509 -req -days 3650 -in passport.com.csr -signkey passport.com.key -out passport.com.crt
Signature ok
subject=/C=CN/ST=HuBei/L=WuHan/O=test/OU=passport/CN=rs1.com/emailAddress=passport@qq.com
Getting Private key
[root@rs1 keys]# ls
passport.com.crt passport.com.csr passport.com.key
將生成的證書傳到另一臺主機
[root@web1 keys]# scp passport.com.crt passport.com.key root@192.168.182.131:/root
若scp用不來了
[root@web1 keys]# vim /etc/hosts
在里面添加IP和主機名
如:
192.168.182.131 web2
192.168.182.130 web
在兩臺web主機上配置https
[root@web1 conf.d]# mkdir /etc/httpd/ssl
[root@web1 ~]# cd keys/
[root@web1 keys]# ls
passport.com.crt passport.com.csr passport.com.key
[root@web1 keys]# mv passport.com.* /etc/httpd/ssl/
[root@web1 httpd]# vim /etc/httpd/conf.d/ssl.conf
DocumentRoot "/var/www/html"
ServerName www.example.com:443
取消上面兩行注釋
修改下面兩行
SSLCertificateFile /etc/httpd/ssl/passport.com.crt
SSLCertificateKeyFile /etc/httpd/ssl/passport.com.key
[root@web1 httpd]# systemctl restart httpd.service
web1和web2上都是同樣的操作
[root@web1 conf.d]# pwd
/etc/httpd/conf.d
[root@web1 conf.d]# vim ssl.conf
defaults
mode tcp
log global
isten admin_stats
bind :0.0.0.0:8189
stats enable
listen webcluster
bind :0.0.0.0:443
mode tcp
#option httpchk GET /indexhtm

