一.Haproxy简介
HAProxy是一个使用C语言编写的自由及开放源代码软件[1],其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动,单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以使每个CPU时间片(Cycle)做更多的工作。 包括 GitHub、Bitbucket[3]、StackOverflow[4]、Reddit、Tumblr、Twitter[5][6]和 Tuenti[7]在内的知名网站,及亚马逊网络服务系统都使用了HAProxy。 [1]
二.HAProxy实验
实验环境准备
3台rhel7.5的虚拟机,且selinux and firewalld disabled
主机名 | 作用 |
---|---|
server1(172.25.66.1) | Haproxy |
server2(172.25.66.2) | 后端httpd |
server3(172.25.66.3) | 后端httpd |
server1配置Haproxy实现反向代理
- 1.我们这里直接使用yum安装haproxy
yum install -y haproxy.x86_64
查看其安装的相关文件:
[root@haserver1 haproxy]# rpm -qa | grep haproxy
haproxy-1.5.18-7.el7.x86_64
[root@haserver1 haproxy]# rpm -ql haproxy-1.5.18-7.el7.x86_64
- 2.修改配置文件
vim /etc/haproxy/haproxy.cfg
将配置文件60行以后改为:
- 3.分别在server2、3上安装httpd 写发布页面
yum install -y httpd
vim /var/www/html/index.html
systemctl start httpd
- 4.开启haproxy服务,物理机测试,实现轮询访问,我们这里就实现了反向代理。
systemctl start haproxy.service
- 5.server1 上添加日志 vim /etc/rsyslog.conf 重启rsyslog服务,可以看到haproxy日志信息
[root@server1 ~]# vim /etc/rsyslog.conf
进入后开启UDP并写入日志类型和等级,及存储位置。
[root@server1 ~]# systemctl restart rsyslog.service
此时,在物理机轮询访问HAproxy时,会有相关日志记录。
vim /var/log/haproxy.log
- 6.ha配置文件中添加下面参数,可以实现web监控。
修改完成后,重启服务systemctl restart haproxy.service
进入浏览器测试,输入http://172.25.66.1/admin/stats,会有认证信息,填写配置文件里的帐号密码即可。
web监控:
返回状态码:
- 7.haproxy设置黑名单,实现访问控制。
配置文件中写入:
acl blacklist src 172.25.66.250
http-request deny if blacklist
errorloc 403 http://172.25.66.1:8080/index.html
同时,我们需要下载httpd,配置监听端口和发布页面。
[root@server1 ~]# yum install -y httpd
[root@server1 ~]# vim /etc/httpd/conf/httpd.conf
[root@server1 ~]# vim /var/www/html/index.html
[root@server1 ~]# cat /var/www/html/index.html
你已被加入黑名单...
[root@server1 ~]# systemctl start httpd
haproxy实现动静分离
- 在server3上安装php,编辑动态页面,完成后重启服务
[root@server3 ~]# yum install -y php
[root@server3 ~]# vim /var/www/html/index.php
[root@server3 ~]# cat /var/www/html/index.php
<?php
phpinfo()
?>
[root@server3 ~]# systemctl restart httpd
- 在server1上编辑haproxy的配置文件
[root@server1 ~]# vim /etc/haproxy/haproxy.cfg
- 重启haproxy服务
systemctl restart haproxy.service
- 测试:
默认访问静态服务器页面:
访问以php结尾的定向到动态服务器:
haproxy实现读写分离
- server1上编辑配置文件,如果有写入操作,访问的是写主机server3
文件编辑内容如下:
- 在server3的默认发布目录下,添加index.php(选择上传图片的页面)和uoload_file.php(上传图片后返回页面),建立存放图片的目录upload目录,给upload目录添加相应的权限以便进行写操作。
index.php文件和upload_file.php的内容如下:
[root@server3 html]# cat index.php
<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename(server3):</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"] < 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";
}
?>
[root@server3 html]# chmod 777 upload
[root@server3 html]# ll
total 12
-rw-r--r-- 1 root root 8 Jul 27 22:01 index.html
-rwxr-xr-x 1 root root 266 Jul 27 23:02 index.php
drwxrwxrwx 2 root root 6 Jul 27 23:01 upload
-rwxr-xr-x 1 root root 929 Jul 27 23:02 upload_file.php
-
server3上开启httpd服务
systemctl restart httpd
-
将编辑好的文件scp到server2上,方便对比,是否实现读写分离:
这里注意修改主机名,方便对比。
[root@server3 html]# scp index.php upload_file.php upload root@172.25.66.2:/var/www/html/
- 在server2上安装php,并重启httpd
[root@server2 ~]# yum install -y php
[root@server2 ~]# vim /var/www/html/index.php
[root@server2 ~]# systemctl restart httpd
- 测试:
发现读取页面始终是在server2上,
而实际上传文件(写)是到server3上,这样就实现了读写分离。