Haproxy实现负载均衡
1 Haproxy的简介
Haproxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
Haproxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。Haproxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。其支持从4层至7层的网络交换,即覆盖所有的TCP协议
Haproxy的架构:
相同点:在功能上,proxy通过反向代理方式实现 WEB均衡负载。和 Nginx,ApacheProxy,lighttpd,Cheroke 等一样。
不同点:Haproxy 并不是 web 服务器。以上提到所有带反向代理均衡负载的产品,都清一色是 WEB 服务器。简单说,就是他们能处理解析页面的。而Haproxy 仅仅是一款的用于均衡负载的应用代理。其自身并不能提供web服务。但其配置简单,拥有非常不错的服务器健康检查功能还有专门的系统状态监控页面,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。
2 Haproxy的部署
2.1 实验环境
- haproxy服务:server1
- 客户端:server2、server3,配置apache服务并编辑apache的默认发布页面
2.2 下载Haproxy软件
(1)下载软件:yum install haproxy.x86_64 -y
(2)haproxy的配置文件:/etc/haproxy/haproxy.cfg
2.3 查看Haproxy监控页面
stats uri /status ##设置Haproxy 监控统计页面的URL 路径,可随意指定
stats auth user:passwd ##定义查看Haproxy 监控统计页面的用户:密码
编辑haproxy的配置文件: vim /etc/haproxy/haproxy.cfg
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 ##设置Haproxy 监控统计页面的URL 路径,可随意指定
stats auth user:passwd ##定义查看Haproxy 监控统计页面的用户:密码
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend 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
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
#backend static
# balance roundrobin
# server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
server app1 172.25.12.2:80 check
server app2 172.25.12.3:80 check
(2)启动haproxy服务:systemctl start haproxy.service
(3)测试:172.25.12.1/status
,输入正确的账号密码即可访问
- 停止server2的apache服务,刷新监控界面
2.4 日志路径
linux资源限制配置文件是/etc/security/limits.conf;限制用户进程的数量对于linux系统的稳定性非常重要。
limits.conf文件限制着用户可以使用的最大文件数,最大线程,最大内存等资源使用量。
core - 限制内核文件的大小
date - 最大数据大小
fsize - 最大文件大小
memlock - 最大锁定内存地址空间
nofile - 打开文件的最大数目
(1)编辑linux资源限制配置文件:/etc/security/limits.conf
(2)编辑haproxy的配置文件:vim /etc/haproxy/haproxy.cfg
(3) 编辑rsyslog参数:/etc/sysconfig/rsyslog
- 在“SYSLOGD_OPTIONS”行上加“-r”选项以允许接受外来日志消息
(4)编辑rsyslog的配置文件:vim /etc/rsyslog.conf
- 允许514端口接收使用UDP协议转发过来的日志
- local2的所有日志信息存放到
/var/log/haproxy.log
(5)重启服务
- 重启日志服务:
systemctl restart rsyslog.service
- 重新加载服务:
systemctl reload haproxy.service
(6)测试
- 访问172.25.12.1,生成日志信息,可以发现日志文件已经生成
2.5 Haproxy的负载均衡算法(balance)
Haproxy的8种负载均衡算法:
roundrobin,表示简单的轮询
static-rr,表示根据权重,
leastconn,表示最少连接者先处理,
source,表示根据请求源IP,
uri,表示根据请求的URI;
url_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name
hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。
balance roundrobin :haproxy把请求轮流的转发到每一个服务器上,依据每台服务器的权重,此权重会动态调整。最常见的默认配置。
balance source :haproxy按照客户端的IP地址进行负载均衡策略,即同一IP地址的所有请求都发送到同一服务器时,需要配置此选项。
测试:balance source
(1)编辑haproxy的配置文件:vim /etc/haproxy/haproxy.cfg
(2)重新加载服务:systemctl reload haproxy.service
(3)测试,在浏览器中输入172.24.12.1
时,所有的请求发送到server2
2.6 静动分离的实现
(1)编辑配置文件:vim /etc/haproxy/haproxy.cfg
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
##测试URL以/static /images /javascript /stylesheets开头的策略url_static
acl url_static path_end -i .jpg .gif .png .css .js
##测试URI是否以.jpg .gif .png .css .js结尾
#
use_backend static if url_static ##如果是静态
default_backend app ##默认动态
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 172.25.12.3:80 check ##静态访问server3
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
#balance source
server app1 172.25.12.2:80 check ##动态访问server2
#server app2 172.25.12.3:80 check
(2)在server3中创建apache的默认发布目录:mkdir /varwww/html/images
,并在此目录上传图片1.jpg
(3)重启服务
- 重新加载haproxy服务:
systemctl reload haproxy.service
- 重启apache服务:
systemctl restart httpd.service
(4)测试:在浏览器中输入 172.25.12.1/images/1.jpg
,验证访问以.jpg结尾的URL访问的是server3
在浏览器中输入172.25.254.1,访问的是server2
2.7 访问控制的实现
(1)禁止 172.25.12网段的用户访问 172.25.12.1
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
acl blacklist src 172.25.12.0/24
block if blacklist
#
use_backend static if url_static
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets
重新加载服务:systemctl reload haproxy.service
测试:在浏览器中输入172.25.254.1,提示403错误
(2)将错误页面进行重定向
重定向(临时)旧地址依旧在,但网站希望你访问新的(盗链)
- 编辑配置文件:
vim /etc/haproxy/haproxy.cfg
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
acl blacklist src 172.25.12.0/24
block if blacklist
errorloc 403 http://www.baidu.com ##如果出现403错误,页面将重定向到百度
#
use_backend static if url_static
default_backend app
- 重新加载服务:
systemctl reload haproxy.service
- 测试:在浏览器中输入172.25.254.1,页面将重定向到 http://www.baidu.com
重定向(永久)旧地址永久移除
- 编辑配置文件:
vim /etc/haproxy/haproxy.cfg
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
acl blacklist src 172.25.12.0/24
redirect location http://www.163.com ##永久重定向
#block if blacklist
#errorloc 403 http://www.baidu.com
#
use_backend static if url_static
default_backend app
- 重新加载服务:
systemctl reload haproxy.service
- 测试:在浏览器中输入172.25.254.1,页面将重定向到
http://www.163.com
2.8 读写分离的实现
(1)编辑haproxy的配置文件:vim /etc/haproxy/haproxy.cfg
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
acl write method POST ##method表示“方式”,写有两种方式:POST、PUT
acl write method PUT
#acl blacklist src 172.25.12.0/24
#redirect location http://www.163.com
#block if blacklist
#errorloc 403 http://www.baidu.com
#
use_backend static if write ##写操作是访问static,也即server3
default_backend app ##默认访问app,也即srver2
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 172.25.12.3:80 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
#balance source
server app1 172.25.12.2:80 check
#server app2 172.25.12.3:80 check
(2)server2和server3均安装php插件,都使用php编辑“读”时的发布页面和文件写入的信息页面,为了验证读写分离,server2和server3的apache新建upload目录:/var/www/html/upload
yum install php
mkdir /var/www/html/upload
chmod 777 /var/www/html/upload/ ##更改目录的权限
- 编辑php的发布页面:
/var/www/html/index.php
<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">server2 filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
- 编辑上传的发布页面:
/var/www/html/upload_file.php
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2000000))
{
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";
}
?>
(3)重启服务
- 重新加载haproxy服务:
systemctl reload haproxy.service
- 重启apache服务:
systemctl restart httpd.service
(4)测试
- 在浏览器中输入172.25.254.1/index.php,此时可以验证读是在server2上完成的
- 在网页上传文件1.jpg
- 可以发现文件的写是在server3上完成的