实验环境:haproxy主机:server2[172.25.5.2]
后端真实服务器(httpd):server3[172.25.5.3]、server4[172.25.5.4]
haproxy特点:支持四层和七层调度、高并发处理能力强、不会后将后端真实服务器暴露
软件的安装
[root@server2 ~]# yum install haproxy.x86_64 -y
简单调度的实现
编辑配置文件/etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to: ##对haproxy日志的一些设置
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
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
#---------------------------------------------------------------------
# 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
## 默认后端为 app
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
#---------------------------------------------------------------------
## 定义app后端主机及调度算法(轮询)
backend app
balance roundrobin
server app1 172.25.5.3:80 check
server app2 172.25.5.4:80 check
配置完成后,启动haproxy:
systemctl start haproxy.service
此时一个简单的副在均衡就完成了。
测试:首先server3和server4上启动httpd
在另外一台主机对haproxy主机的80端口进行访问,结果为:
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
成功实现调度。
关闭server3上的httpd,再次进行访问,测试健康检查是否工作正常:
[root@server3 ~]# systemctl stop httpd
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@server3 ~]# systemctl start httpd
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
后端健康检查工作正常!
也可以设置为加权轮询的方式:
测试结果:
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server4
注意:haproxy开启80端口,haproxy上不能能开启端口为80的httpd,否则haproxy启动会失败。
端口映射
这里修改server4上httpd的端口为8080:
修改完成后重启httpd。
在haproxy主机上修改haproxy配置文件:
修改完成后reload haproxy。
进行访问测试:
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
访问成功!
在后端所有服务器都挂掉的情况下,访问本机的8080端口
在一般情况下,当后端所有服务器都挂掉的情况下,一般会直接访问本机的httpd,告诉客户端一些信息(服务正在维护,请稍候再试)
。
首先在haproxy主机上安装httpd,安装完成后修改httpd的端口为8080
注意:若不修改,此端口和haproxy的端口冲突!
在httpd的默认发布页面放上信息服务正在维护,请稍候再试, 打开httpd服务。
编辑haproxy配置文件:
修改完成后reload haproxy。 手动关掉server3,server4的httpd,再次进行访问测试:
成功!
监控的添加
在配置文件中添加监控项:
添加完成后,重启haproxy服务,在浏览器进行访问:server2/status即可查看监控:
添加监控的认证
此监控信息为内部信息,不能随意被访问,所以这里给监控页面添加一个认证:
编辑配置文件:
认证账号为admin 密码为redhat。
设置完成后,systemctl reload haproxy
再次访问监控,此时已经需要输入账号和密码了:
输入错误不能访问,在输入正确的认证后才能访问到监控页面。
访问控制
目标:实现对haproxy的访问控制:
禁止ip地址为172.25.5.1对后端服务器的访问:
编辑配置文件:
编辑完成后,reload haproxy。
访问测试:
其他主机访问server2:
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
[root@foundation5 cluster]# curl server2
server4
[root@foundation5 cluster]# curl server2
server3
server1访问server2:
[root@server1 ~]# curl server2
[root@server1 ~]# curl -I server2
HTTP/1.1 302 Found
Cache-Control: no-cache
Content-length: 0
Location: http://172.25.5.2:8080
haproxy的日志设置:
在配置文件中,已经告诉我们haproxy日志的设置方法:
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
在/etc/rsyslog.conf中添加
local2.* /var/log/haproxy.log
并且在设置messages接受haproxy的日志信息
打开UDP的两个参数:
在/etc/sysconfig/rsyslog 中添加-r参数:
重启rsyslog服务,此时,查看/var/log/会产生haproxy.log来专门记录haproxy产生的日志信息。haproxy的日志信息此时也不会在message中查看。
简单的动静分离
动态页面:
在server4上安装php
yum install php -y
在httpd的默认发布目录新建目录images
在images下新建index.php文件
编辑此文件:
进行访问测试:
访问正常!
静态页面:
我们在server3的默认发布页放上一张图来进行访问:
静态页面访问正常!
在haproxy主机编辑haproxy配置文件:
frontend main *:80
acl blacklist src 172.25.5.1
block if blacklist
errorloc 403 http://172.25.5.2:8080
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 172.25.5.3:80 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
# server app1 172.25.5.3:80 check
server app2 172.25.5.4:80 check
server backup 127.0.0.1:8080 backup
编辑完成后reload haproxy
访问测试:
访问成功!动静分离成功!
简单的读写分离
这里通过读取和上传来模拟用户读写行为
在paproxy配置文件中定义acl
读请求的方式:
acl read_request method GET
acl read_request method HEAD
写请求的方式:
acl write_request method PUT
acl write_request method POST
编辑配置文件:
frontend main *:80
# acl blacklist src 172.25.5.1
# block if blacklist
# errorloc 403 http://172.25.5.2:8080
# acl url_static path_beg -i /static /images /javascript /stylesheets
# acl url_static path_end -i .jpg .gif .png .css .js
acl read_request method GET
acl read_request method HEAD
acl write_request method PUT
acl write_request method POST
use_backend static if read_request
use_backend app if write_request
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 172.25.5.3:80 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
在server3、server4上安装php,并且在httpd的默认发布目录新建upload目录,添加模拟上传的php页面:
[root@server3 html]# ls
images index.html index.php upload 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:</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"] < 200000))
{
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";
}
?>
修改目录upload权限为777
[root@server4 html]# ll
total 12
-rw-r--r-- 1 root root 8 Aug 5 09:56 index.html
-rw-r--r-- 1 root root 257 Aug 9 15:39 index.php_backup
drwxrwxrwx 2 root root 53 Aug 7 15:03 upload
-rw-r--r-- 1 root root 929 Aug 7 14:50 upload_file.php
reload server3、server4上的httpd
reload server2上的haproxy
访问server2/index.php页面:
此时访问的是server3上的index.php
进行上传:
可以看到,上传成功!
此时,查看两台服务器的发布目录下的upload目录中查看是否有刚才上传的文件:
[root@server3 html]# ll upload
total 0
[root@server4 html]# ll upload
total 312
-rw-r--r-- 1 apache apache 225325 Aug 9 16:53 iso7.gif
-rw-r--r-- 1 apache apache 89081 Aug 7 15:03 Screenshot from 2020-08-07 15-03-19.gif
可以看到,文件被成功上传到server4。
读写分离 成功!