Linux下Haproxy实现负载均衡,访问控制,动静分离及读写分离+修改haproxy日志路径
一、Haproxy简介:
- HAProxy是一个使用C语言编写的自由及开放源代码软件[1],其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
- HAProxy是一个使用C语言编写的自由及开放源代码软件[1],其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
- HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
二、实验环境(rhel6.5版本)
主机环境:rhel6.5 selinux 和iptables 都必须是disabled状态
各主机信息
主机名 | IP | 服务 |
---|---|---|
server1 | 172.25.83.1 | Haproxy+http |
server2 | 172.25.83.2 | http |
server3 | 172.25.83.3 | http |
物理机 | 172.25.83.83 | 用于测试nginx |
三、Haproxy相关配置
1、负载均衡
配置server1:
(1)官网下载haproxy软件包,并解压
[[email protected] ~]# ls
haproxy-1.7.3.tar.gz
[[email protected] ~]# tar zxf haproxy-1.7.3.tar.gz
[[email protected] ~]# ls
haproxy-1.7.3 haproxy-1.7.3.tar.gz
(2)安装编译依赖包,并进行编译
[[email protected] ~]# yum install rpm-build pcre-devel gcc -y
[[email protected] ~]# rpmbuild -tb haproxy-1.7.3.tar.gz
[[email protected] ~]# ls #自动生成rpmbuil目录
haproxy-1.7.3 haproxy-1.7.3.tar.gz rpmbuild
(3)安装haproxy服务
[[email protected] ~]# cd rpmbuild/RPMS/x86_64/
[[email protected] x86_64]# ls
haproxy-1.7.3-1.x86_64.rpm
[[email protected] x86_64]# rpm -ivh haproxy-1.7.3-1.x86_64.rpm
(4)拷贝配置文件到/etc/haproxy目录下,并进行编辑
[[email protected] x86_64]# cd ~/haproxy-1.7.3/examples/
[[email protected] examples]# cp content-sw-sample.cfg /etc/haproxy/haproxy.cfg #拷贝配置文件
[[email protected] examples]# vim haproxy.cfg #编辑配置文件
1 #
2 # This is a sample configuration. It illustrates how to separate static objects
3 # traffic from dynamic traffic, and how to dynamically regulate the server load.
4 #
5 # It listens on 192.168.1.10:80, and directs all requests for Host 'img' or
6 # URIs starting with /img or /css to a dedicated group of servers. URIs
7 # starting with /admin/stats deliver the stats page.
8 #
9
10 global
11 maxconn 10000
12 stats socket /var/run/haproxy.stat mode 600 level admin
13 log 127.0.0.1 local0
14 uid 200
15 gid 200
16 chroot /var/empty
17 daemon
18 defaults
19 mode http
20 log global
21 option httplog
22 option dontlognull
23 monitor-uri /monitoruri
24 maxconn 8000
25 timeout client 30s
26 retries 2
27 option redispatch
28 timeout connect 5s
29 timeout server 30s
30 timeout queue 30s
31 stats uri /admin/stats
32
33 # The public 'www' address in the DMZ
34 frontend public
35 bind *:80 name clear
36 #bind 192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem
37 #use_backend static if { hdr_beg(host) -i img }
38 #use_backend static if { path_beg /img /css }
39 default_backend dynamic
40
41 # the application servers go here
42 backend dynamic
43 balance roundrobin
44 server web1 172.25.83.2:80 check inter 1000
45 server web2 172.25.83.3:80 check inter 1000
(5)创建haproxy用户和组,实现对haproxy服务的控制
[[email protected] examples]# groupadd -g 200 haproxy
[[email protected] examples]# useradd -u 200 -g 200 -s /sbin/nologin -M haproxy #这里200是由haproxy.cfg该配置文件决定的
(6)开启haproxy服务
[[email protected] examples]# /etc/init.d/haproxy start
[[email protected] examples]# netstat -antulpe #haproxy服务的监听端口为80,这是由haproxy.cfg该配置文件决定的
Active Internet connections (servers and established)
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 12947 1480/haproxy
server2和server3配置(安装apache,默认发布目录下编写发布文件):
#server2端
[[email protected] ~]# yum install httpd -y
[[email protected] ~]# /etc/init.d/httpd start
[[email protected] ~]# netstat -antulpe | grep 80
tcp 0 0 :::80 :::* LISTEN 0 14558 1778/httpd
[[email protected] ~]# echo server2 > /var/www/html/index.html
#server3端
[[email protected] ~]# yum install httpd -y
[[email protected] ~]# /etc/init.d/httpd start
[[email protected] ~]# netstat -antulpe | grep 80
tcp 0 0 :::80 :::* LISTEN 0 14558 1778/httpd
[ro[email protected] ~]# echo server3 > /var/www/html/index.html
测试:
(1)网页输入172.25.83.1/admin/monitoruri,查看haproxy服务的状态
(2)网页输入172.25.83.1/admin/stats,对haproxy负载均衡的后端服务器进行监控
(3)如何对监控页面进行加密呢?
编辑haproxy配置文件:
[[email protected] examples]# vim /etc/haproxy/haproxy.cfg #在指定行写入
32 stats auth admin:westos #登陆用户名及密码
33 stats refresh 5s #5s刷新一次
[[email protected] examples]# /etc/init.d/haproxy restart #修改完配置文件之后,重启haproxy服务
刷新web界面
(4)
第一种情况:server2和server3中任意一端的httpd服务挂掉(这里以关闭server3上的httpd服务为例)
[[email protected] ~]# /etc/init.d/httpd stop
[[email protected] ~]# netstat -antulpe | grep 80 #过滤不到任何信息
第二种情况:server2和server3端的httpd服务都挂掉(因为第一种情况挂掉了server3端的httpd服务,所以这里只需要挂掉server2端的httpd服务就可以了)
[[email protected] ~]# /etc/init.d/httpd stop
[[email protected] ~]# netstat -antulpe | grep 80 #过滤不到任何信息
启动server2和server3端的httpd服务,以免影响后续的实验
[[email protected] ~]# /etc/init.d/httpd start
[[email protected] ~]# netstat -antulpe | grep 80
tcp 0 0 :::80 :::* LISTEN 0 15236 1894/httpd
[[email protected] ~]# /etc/init.d/httpd start
[[email protected] ~]# netstat -antulpe | grep 80
tcp 0 0 :::80 :::* LISTEN 0 10623 1250/httpd
2、修改haproxy日志路径
(1)修改日志配置文件(存储位置),并重启rsyslog服务
[[email protected] examples]# vim /etc/rsyslog.conf
13 $ModLoad imudp #去掉注释
14 $UDPServerRun 514 #去掉注释
42 *.info;mail.none;authpriv.none;cron.none;local0.none /var/log/ messages #添加local0.none
62 local0.* /var/log/haproxy.log #将日志放在haproxy日志文件
[[email protected] examples]# /etc/init.d/rsyslog restart
(2)测试:
网页访问server1后查看日志:
3、访问控制
访问控制的配置方法一:
(1)修改haproxy配置文件,并重载haproxy服务
[[email protected] log]# vim /etc/haproxy/haproxy.cfg
41 acl blacklist src 172.25.83.83
42 http-request deny if blacklist
43 errorloc 403 http://172.25.83.1:8080/index.html #其实这行可加可不加,但是不加的话,当172.25.83.83主机访问172.25.83.1时显示的界面不友好(默认的403报错的界面)
[[email protected] log]# /etc/init.d/haproxy reload #修改完配置文件之后,重载haproxy服务
(2)server1安装apache,修改端口为8080,编辑默认发布文件,并启动httpd服务
[[email protected] log]# yum install httpd -y
[[email protected] log]# vim /etc/httpd/conf/httpd.conf
136 Listen 8080 #将默认监听端口80改为8080(因为80端口被haproxy服务占用)
[[email protected] log]# echo "你已被拉黑..." > /var/www/html/index.html
[[email protected] log]# /etc/init.d/httpd start
[[email protected] log]# netstat -antulpe | grep 8080
tcp 0 0 :::8080 :::* LISTEN 0 19300 1640/httpd
(3)测试:
server2端可以访问
server3端可以访问
物理机不能访问(访问的必须是172.25.83.1:8080,输入172.25.83.1没有任何输出)
网页输入172.25.83.1,自动跳转到172.25.83.1:8080的页面
访问控制的配置方法二:
(1)修改haproxy配置文件,并重载haproxy服务
[[email protected] log]# vim /etc/haproxy/haproxy.cfg
41 acl blacklist src 172.25.83.83
42 http-request deny if blacklist
43 #errorloc 403 http://172.25.83.1:8080/index.html #注释之前编写的这行代码
44 redirect location http://172.25.83.1:8080/index.html if blacklist #添加这行代码(与43行代码的效果想同) #其实这行可加可不加,但是不加的话,当172.25.83.83主机访问172.25.83.1时显示的界面不友好(默认的403报错的界面)
[[email protected] log]# /etc/init.d/haproxy reload #修改完配置文件之后,重载haproxy服务
(2)server1安装apache,修改端口为8080,编辑默认发布文件,并启动httpd服务——上面一经做过,这里不需要再做
(3)测试:
server2端可以访问
server3端可以访问
物理机不能访问(访问的必须是172.25.83.1:8080,输入172.25.83.1是403报错的默认输出)
网页输入172.25.83.1
网页输入172.25.83.1:8080
总结:这两种方法所起的作用是相同的,都是禁止172.25.83.83这个主机访问172.25.83.1。差别就在172.25.83.83主机访问172.25.83.1时的访问方法,以及结果。
4、动静分离
(1)在server2中编辑默认发布目录下的index.html文件——前面一经做过这一步,这里不需要再做
配置完之后,web界面进行测试,以确保配置的是成功的
(2)在server3上编辑默认发布目录下的index.php文件,并安装php,安装完php之后要重启httpd服务
[[email protected] ~]# vim /var/www/html/index.php
<?php
phpinfo()
?>
[[email protected] ~]# yum install php -y
配置完之后,web界面进行测试,以确保配置的是成功的
(3)server1上haproxy配置文件中添加动静分离配置,并重载haproxy服务
[[email protected] log]# vim /etc/haproxy/haproxy.cfg
36 frontend public #将之前编写的访问控制的内容,进行注释(因为之前访问控制设置的是172.25.83.83主机不能访问,而我们现在的测试需要在172.25.83.83主机上进行测试)
37 bind *:80 name clear
38 #bind 192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem
39 #use_backend static if { hdr_beg(host) -i img }
40 #use_backend static if { path_beg /img /css }
41 #acl blacklist src 172.25.83.83
42 #http-request deny if blacklist
43 ##errorloc 403 http://172.25.83.1:8080/index.html
44 #redirect location http://172.25.83.1:8080/index.html if blacklist
45
46 use_backend dynamic if { path_end .php } #这行以下是修改及添加的内容
47 default_backend static
48 backend static
49 balance roundrobin
50 server web1 172.25.83.2:80 check inter 1000
51
52 # the application servers go here
53 backend dynamic
54 balance roundrobin
55 server web2 172.25.83.3:80 check inter 1000
[[email protected] log]# /etc/init.d/haproxy reload #修改完配置文件之后,重载haproxy服务
(4)测试:
网页访问,静态访问到server2的页面内容
动态访问到server3的php动态页面(配置文件中设定的以.php结尾的访问是动态访问)
5、读写分离
(1)编辑haproxy配置文件,并重载haproxy服务
[[email protected] log]# vim /etc/haproxy/haproxy.cfg
45 acl write method POST
46 acl write method PUT
47 acl read method GET
48 acl read method HEAD
49
50 use_backend static if write
51 default_backend dynamic
[[email protected] log]# /etc/init.d/haproxy reload #编辑完配置文件之后,重载haproxy服务
(2)在server2端和server3端的httpd默认发布目录,放进去两个文件
- index.php(选择图片的静态页面)
- upload_file.php(上传图片的动态页面)
[[email protected] ~]# cd /var/www/html/
[[email protected] html]# ll #为了安全,应使index.php文件和upload_file.php文件的权限为644
total 12
-rw-r--r-- 1 root root 8 Apr 29 19:56 index.html
-rw-r--r-- 1 root root 257 Apr 29 22:29 index.php
-rw-r--r-- 1 root root 927 Apr 29 22:29 upload_file.php
[[email protected] html]# cat index.php #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>
[[email protected] html]# cat upload_file.php #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";
}
?>
#server3端的操作同server2端
(3)在server2端和server3端的httpd的默认发布目录下建立upload目录,并修改该目录的权限为777,该目录用来存放上传图片
[[email protected] html]# mkdir upload
[[email protected] html]# ll -d upload
drwxr-xr-x 2 root root 4096 Apr 29 22:32 upload
[[email protected] html]# chmod 777 upload
[[email protected] html]# ll -d upload
drwxrwxrwx 2 root root 4096 Apr 29 22:32 upload
#server3端的操作同server2端
(4)在server2端和server3端修改上传的大小限制(以免产生因大小受限所导致的错误)
[[email protected] html]# vim upload_file.php
5 && ($_FILES["file"]["size"] < 2000000))
#server3端的操作同server2端
(5)在server2端安装php软件(以使得其支持php语言),安装完该软件之后重启httpd服务
[[email protected] html]# rpm -q php
package php is not installed
[[email protected] html]# yum install php -y
[[email protected] html]# rpm -q php
php-5.3.3-26.el6.x86_64
[[email protected] html]# /etc/init.d/httpd restart #安装完php软件之后重启httpd服务
(6)测试:
浏览器输入:172.25.83.1/index.php
点击Browse,选择上传的图片(我这里选择的图片是之前在网上下载好的redhat.jpg图片),在点击Submit提交
查看,上传图片保存在server2上的/var/www/html/upload目录下,server3没有