一、HAproxy简介
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在时下的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
二、安装配置
安装
yum install haproxy -y
配置说明:
### 主配置文件是/etc/haproxy/haproxy.conf ### 配置文件主要有: global settings: 全局配置段 主要用于定义haproxy进程自身的工作特性; proxies: 代理配置段 backend: 后端服务器组 frontend: 定义面向客户的监听的地址和端口,以及关联到的后端服务器组; listen: 组合方式直接定义frontend及相关的backend的一种机制; defaults: 定义默认配置 ################################################################################# gloab的默认选项: log 127.0.0.1 local2 # 记录日志,此时要借助于本机的rsyslod的日志服务,需要开启udp端口监听 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats ################################################################################# defaults配置选项: mode http # 工作模式,有TCP和http,代表4层代理、7层代理 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 # 最大并发连接数
一、简单的实现负载均衡
实验主机 | 安装软件 |
172.16.10.9 | haproxy,反向代理的前端 |
172.16.10.77 | httpd,后端主机 |
172.16.10.1 | httpd,后端主机 |
## 配置过程: 在172.16.10.1和172.16.10.77上: yum install httpd -y 创建测试页面: echo "[email protected]" > /var/www/html/index.html echo "[email protected]" > /var/www/html/index.html ############################################################## ## 在172.16.10.9上配置,在配置文件中添加以下内容,就可以实现: frontend http *:80 default_backend web backend web balance roundrobin server web1 172.16.10.77:80 server web2 172.16.10.1:80 ###############################################################
此时会出现负载均衡的效果:
此时查看后端web日志:
解决办法:
编辑http的配置文件中,修改以下内容:(修改记录的http的头部信息) LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 修改为: LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
二、负载均衡算法介绍
在上面的的使用中,使用到了balance关键字,这个关键字的作用是指定负载均衡算法的。
### haproxy使用的调度算法:常用的 ### 使用范围:defaults forntend backend listen 1、roundrobin: 相当于lvs的 wrr, 是一种dynamic调度算法,支持weight指定权重。所谓的动态是 可以再服务器运行中调整,慢启动。对后端服务器数目由限制 4096 2、static-rr: wrr, static调度算法,对后端服务器数目没有限制 3、leastconn: 类似于lvs的wlc, dynamic方法 4、source: 建议用于基于TCP模式调度,且不支持使用cookie插入模式时使用; 由hash-type参数决定其为dynamic或者static等价于ipvs: sh,nginx: ip_hash 5、uri: 基于请求报文中的uri的左半部分(查询条件之前的部分)或全部的URI进行调度; 常用于backend server为cache server的场景中;由hash-type参数决定其为dynamic或者static 6、url_params: 常用于后端服务器需要对用户进行认证的场景中; 由hash-type参数决定其为dynamic或者static 7、hdr():根据用户请求报文中,指定的http首部的值进行调度 hdr(host):常用于实现将对同一个虚拟主机的请求始终发往同个backend server; use_domain_only: 在计算hash值时仅使用域名;由hash-type参数决定其为dynamic或者static
hash_type的取值有:
map-based:hash表是一个包含了所有在线服务器的静态数组。 挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时, 大多数连接将会被重新派发至一个与此前不同的服务器上。 对于缓存服务器的工作场景来说,此方法不适用。 consistent:hash表是一个由各服务器填充而成的树状结构; 基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的, 支持在运行时修改服务器权重。 添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的 场景。 不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此, 可能需要不时的调整服务器的权重以获得更好的均衡性。
cookie实现根据客户端cooike信息来实现持久连接。实现的原理:
cookie关键字用法说明: nocacahe:将附加cookie信息的资源不缓存于缓存服务器中 insert:插入cooike信息 rewrite:重写cookie prefix:作为前缀
测试:修改haproxy的配置文件
backend web balance roundrobin cookie webser insert nocache server web1 172.16.10.77:80 cookie web1 server web2 172.16.10.1:80 cookie web2
测试:
三、HAproxy的状态页
### 在配置文件中添加: listen stats mode http bind 0.0.0.0:1080 stats enable stats hide-version stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth admin:admin stats admin if TRUE
四、后端监控状态检测
### 修改配置文件,如下: backend web balance roundrobin server web1 172.16.10.77:80 check port 80 inter 2 fall 2 rise 1 server web2 172.16.10.1:80 check port 80 inter 2 fall 2 rise 1 server back 172.16.10.9:8080 backup
当后端主机全都不在线时,测试:
一旦手段主机重新上线,访问恢复:
五、利用haproxy实现动态分离
此时要利用到haproxy的ACL机制:
haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决 策,这大大增强了其配置弹性。其配置法则通常分为两步,首先去定义ACL,即定义一个测试条件, 而后在条件得到满足时执行某特定的动作,如阻止请求或转发至某特定的后端。 定义ACL的语法格式如下。 acl[flags] [operator] ... :ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、 .(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl; :测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整; 而有些测试标准也可以需要为其在 之前指定一个操作符[operator]; [flags]:目前haproxy的acl支持的标志位有3个: -i:不区分 中模式字符的大小写; -f:从指定的文件中加载模式; --:标志符的强制结束标记,在模式中的字符串像标记符时使用; :acl测试条件支持的值有以下四类: 整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标 识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt; 字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义; 如果在模式首部出现了-i,可以在其之前使用“--”标志位; 正则表达式:其机制类同字符串匹配; IP地址及网络地址 同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。 条件间的组合测试关系有三种:“与”(默认即为与操作)、“或”(使用“||”操作符)以及 “非”(使用“!”操作符)。
示例:
acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js acl host_static hdr_beg(host) -i img. video. download. ftp. acl being_scanned be_sess_rate gt 50
实验环境:
在172.16.10.9:
1、提供haproxy的配置文件,内容如下: global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats 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 listen stats mode http bind 0.0.0.0:1080 stats enable stats hide-version stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth admin:admin stats admin if TRUE frontend http bind *:80 acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js use_backend static if url_static default_backend web backend static balance roundrobin server static 172.16.10.122 check backend web balance roundrobin server web1 172.16.10.77:80 check port 80 inter 2 fall 2 rise 1 server web2 172.16.10.1:80 check port 80 inter 2 fall 2 rise 1 server back 172.16.10.9:8080 backup ################################################################################### 2、提供nfs服务 mkdir /data setfacl -m d:u:48:rwx /data/ ################################################################################### 3、提供Discuzz的数据库授权用户 mysql> GRANT ALL ON discuzz.* TO disuser@'172.16.10.%' IDENTIFIED BY 'dispass'; mysql> FLUSH PRIVILEGES; ################################################################################## 启动服务: service nfs start service haproxy restart
在172.16.10.1、172.16.10.77上:
yum install php php-mysql -y mkdir /var/www/html/discuzz service httpd restart
在172.16.10.122上:
这个节点上只需响应静态页面,可以不安装php php-mysql。直接挂载
在任意一台上,挂载nfs,开始安装discuzz.这里以172.16.10.77为例:
大致步骤: 1、mount -t nfs 172.16.10.9:/data/ /var/www/html/discuzz/ 2、解压discuzz安装包,将解压后的upload中的所有文件复制到/var/www/html/discuzz/ 3、开始安装:http;//172.16.10.77/discuzz/install/index.php
按照提示解决问题并安装,最关键的是数据库信息的填写:
安装完成后,在172.16.10.122和172.16.10.1上:mount -t nfs 172.16.10.9:/data/ /var/www/html/discuzz/ 开始测试:
前端调度:
此时,将静态页面服务器172.16.10.122停止,结果:
实现了一定程度上的动静分离。
关于haproxy更多,更详细的内容,参考官方文档。