http://www.07net01.com/linux/Haproxypeizhixiangjie_645322_1380518936.html
本文借鉴了网友写的博客,以上是源地址。
##一、haproxy简介
HAProxy是一种高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。
需要注意的是Haproxy只是http协议的方向代理,不提供缓存功能。
HAProxy是一种http反向代理,它有以下特性:
- 作者开发的独特的弹性二叉树数据结构,使数据结构的复杂性上升到了0(1),即数据的查寻速度不会随着数据条目的增加而速度有所下降;
- 支持客户端的keepalive功能,减少客户端与haproxy的多次三次握手导致资源浪费,让多个请求在一个tcp连接中完成;
- 支持TCP加速,零复制功能,类似于mmap机制;
- 支持响应池(response buffering)
- 支持RDP协议
- 基于源的粘性,类似nginx的ip_hash功能,把来自同一客户端的请求在一定时间内始终调度到上游的同一服务器;
- 更好统计数据接口,有一个web接口显示后端集群中各个服务器的接收、发送、拒绝、错误等数据的统计信息;(stats页面)
- 详细的健康状态检测,web接口中有关于对上游服务器的健康检测状态,并提供了一定的管理功能;
- 基于流量的健康评估机制;
- 基于http认证;
- 基于命令行的管理接口
- 基于ACL,用于访问控制等;
- 日志分析器,可对日志进行分析。
##二、haproxy配置文件概述
HAProxy的配置处理3类来主要参数来源:
——最优先处理的命令行参数,
——“global”配置段,用于设定全局配置参数;
——proxy相关配置段,如“defaults”、“listen”、“frontend”和“backend”;
haproxy配置文件主要分为两个部分:全局配置段、代理配置段
##三、Haproxy配置文件分析
#cat /etc/haproxy/haproxy.cfg
global 全局配置段
log 127.0.0.1 local2 #定义haproxy日志,与rsyslog相关,local2定义于/etc/rsyslog.conf中后续文章有介绍
chroot /var/haproxy #chroot运行的路径,增加安全性
uid 99 #以该id运行该程序
gid 99 #程序运行的用户组id
daemon #以后台形式运行haproxy
nbproc 1 #number of process进程数量,不建议修改
pidfile /var/run/haproxy.pid #haproxy的pid存放路径
maxconn 4000 #默认最大连接数
defaults
mode http #;工作模式 http,tcp....
option dontlognull
log global #;记录日志
option http-server-close #;启用服务器端关闭
option forwardfor except 127.0.0.0/8 #;传递客户端ip
option redispatch #;当服务器组中的某台设备故障后,自动将请求重定向到组内其他主机。
retries 3 #;请求重试的次数
timeout http-request 10s #;http请求超时时间
timeout queue 1m #;一个请求在队列里的超时时间·
timeout connect 10s #;连接服务器超时时间
timeout client 1m #;设置客户端侧最大非活动时间
timeout server 1m #;设置服务器侧最大非活动时间
timeout http-keep-alive 10s #;设置http-keep-alive的超时时间
timeout check 10s #;当一个连接建立之后,
maxconn 3000 #;同时处理的最大连接数
#errorfile 403 /etc/haproxy/errorfiles/403.http 自定义的错误页面
#errorfile 500 /etc/haproxy/errorfiles/500.http
#errorfile 502 /etc/haproxy/errorfiles/502.http
#errorfile 503 /etc/haproxy/errorfiles/503.http
#errorfile 504 /etc/haproxy/errorfiles/504.http
#启用stats查看,认证等功能:
#默认的查看路径/haproxy?stats http://172.18.14.1/haproxy?stats
listen stas #自定义监听名,任意取
bind 172.18.14.8080 #监听的地址和端口
mode http #模式
stats enable #启用状态监控
stats hide-version #隐藏软件版本号
stats auth admin:admin #登陆用户名和密码
stats realm HAproxy\ stats #提示信息,空格之前加\
stats admin if TRUE #当通过认证才可管理
stats uri /stats #自定义访问路径 http://172.18.14.1/admin?stats
stats refresh 5 #页面自动刷新间隔
stats refresh 20s --每隔20s刷新
stats hide-version --隐藏haproxy版本信息
stats uri /haproxy-stats --在域名后面添加/haproxy-stats可以查看haproxy监控状态
stats auth haproxy:system --用户名和密码 stats hide-version
stats admin if TRUE --可以手动启动和停止服务
##四、 配置示例
动静分离部署wordpress,动静都要能实现负载均衡。
拓扑图:
>计划用9台虚拟机,1台客户机(172.18.14.66),
1台NFS(wordpress共享目录 /var/www/html,172.18.14.39)
1台mysql(172.18.14.38)
2台lap(lap1 172.18.13.37; lap2 172.18.14.36 , http目录供)
2台nginx : nginx1(172.18.14.35) nginx2(172.18.14.34)
2台haproxy : haproxy1(keepalive1:172.18.14.33);haproxy2(keepalvie1: 172.18.14.32)
###A
- NFS共享WordPress目录:
[root@localhost ~]# mkdir /data/www/html -pv
mkdir: created directory ‘/data/www/html’
[root@localhost ~]#chown apache:apache -R /data/www/html/
[root@localhost ~]# mkdir /data/www/html/wordpress/wp-content
upload
[root@localhost ~]# yum install nfs-utils
[root@localhost wp-content]# vim /etc/exports
[root@localhost wp-content]# cat /etc/exports
/data/www/html 172.18.0.0/16(rw,all_squash,anonuid=48,anongid=48)
/data/www/html/wordpress/wp-content/upload 172.18.0.0/16(rw,all_squash,anonuid=48,anongid=48)
[root@localhost wp-content]# systemctl restart rpcbind
[root@localhost wp-content]# systemctl restart nfs
[root@localhost wp-content]# showmount -e 172.18.14.39
###B
- mysql服务器准备数据库:
[root@localhost ~]# yum install mariadb -y
[root@localhost ~]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.52-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database haproxy;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> grant all privileges on haproxy.* to 'haproxy'@'%' identified by "haproxy";
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]>
###C
- lap1 准备lap环境,挂载共享目录**:
[root@localhost ~]#
[root@localhost ~]# yum install httpd php php-mysql nfs-utils -y
- 挂载共享目录
[root@localhost ~]# mount -t nfs 172.18.14.39:/data/www/html/ /var/www/html/
- 测试php是否正常访问
[root@localhost ~]# cat /var/www/html/test.php
lap 1 172.18.14.37
<?php
phpinfo();
?>
[root@localhost ~]# systemctl restart httpd
- 测试远程数据库是否连接正常:
[root@localhost ~]# yum install mariadb-server -y
[root@localhost ~]# cat /var/www/html/test.php
lap 1 172.18.14.37
<?php
$conn=mysql_connect('172.18.14.38','haproxy','haproxy');
if ($conn)
echo "ok";
else
echo "failure";
phpinfo();
?>
###D
- lap2准备lap环境,挂载共享目录:
[root@localhost ~]#
[root@localhost ~]# yum install httpd php php-mysql nfs-utils -y
挂载共享目录
[root@localhost ~]# mount -t nfs 172.18.14.39:/data/www/html/ /var/www/html/
测试php是否正常访问:
[root@localhost ~]# cat /var/www/html/test.php
lap 1 172.18.14.37
<?php
phpinfo();
?>
[root@localhost ~]# systemctl restart httpd
- 测试远程数据库是否连接正常:
[root@localhost ~]# yum install mariadb-server -y
[root@localhost ~]# cat /var/www/html/test.php
lap 1 172.18.14.37
<?php
$conn=mysql_connect('172.18.14.38','haproxy','haproxy');
if ($conn)
echo "ok";
else
echo "failure";
phpinfo();
?>
###E
准备nginx 环境:nginx1
[root@localhost ~]# id apache
uid=48(apache) gid=48(apache) groups=48(apache)
[root@localhost ~]# yum install nginx-1.10.0-1.el7.ngx.x86_64.rpm -y
[root@localhost ~]#
[root@localhost ~]# mount -t nfs 172.18.14.39:/data/www/html/wordpress/wp-content/uploads /usr/share/nginx/html/
测试:
[root@localhost ~]# !cu
curl 172.18.14.35
wordpress upload
nginx page
#
###F
准备nginx 环境:nginx2
[root@localhost ~]# id apache
uid=48(apache) gid=48(apache) groups=48(apache)
[root@localhost ~]# yum install nginx-1.10.0-1.el7.ngx.x86_64.rpm -y
[root@localhost ~]#
[root@localhost ~]# mount -t nfs 172.18.14.39:/data/www/html/wordpress/wp-content/uploads /usr/share/nginx/html/
里需要注意的需要额外解压一份wordpress资源到uploads目录下,否则在解析的时候,upload目录下没有需要的静态资源,如js,css等,wordpress页面将会是文本框
这样一来,用户写博客上传的图片就是可以直接以http://172.18.14.31/baidu.jpg的形式访问了,而且访问http://172.18.14.31/wordpress 也不会出现文本的情况。
- 测试:
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# curl 172.18.14.34
wordpress upload 172.18.14.39
nginx page
###G
- 准备haproxy haproxy1:
[root@bnpanda ~]#yum install haproxy -y
[root@bnpanda ~]#systemctl start haproxy
[root@bnpanda haproxy]#cat 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:
#
# 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
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 172.18.14.34:80 check
server static 172.18.14.35:80 check
server static 127.0.0.1:80 backup check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
cookie WEBSRV insert nocache indirect
balance roundrobin
server app1 172.18.14.36:80 check cookie app1
server app2 172.18.14.37:80 check cookie app2
- 重启服务
[root@bnpanda haproxy]#
[root@bnpanda haproxy]#systemctl restart haproxy.service
[root@bnpanda haproxy]#systemctl status -l haproxy.service #确保服务状态正常
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2017-05-18 11:05:44 CST; 1min 35s ago
。。。。。。
-
测试
-
将后端Apache服务人为:关闭一台,依然能提供服务:
-
再破坏一台apache服务:由于动态服务器组没有设置sorryserver,所以出现503错误
-
恢复所有Apache服务器
-
haproxy2: 配置文件和haproxy1一样的,注意下。
###H
- 准备 keepalive ( haproxy1):
[root@bnpanda haproxy]#
[root@bnpanda keepalived]#yum install psmisc -y
[root@bnpanda haproxy]#yum install keepalived -y
[root@bnpanda keepalived]#cat keepalived.conf #keepalive配置文件
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from mask@foxmail.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.14.14 #自定义组播地址
}
vrrp_script chk_haproxy { #自定义健康检测脚本
script "killall -0 haproxy && exit 0 || exit1"
interval 1
weight -5
fall 2
rise 1
}
vrrp_instance my1 { #路由实例
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.18.14.31 dev ens33 label ens33:0
}
track_script { #调用上面定义的检测脚本
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master" #调用通知脚本
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
[root@bnpanda keepalived]#cat notify.sh #通知脚本示例
#!bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(ohstname)to be $1,vip floating"
mailbody="$(date +'%F %T'):vrrp transition, $(hostname)to be $!"
echo "$mailbody" | mail -s "mailsubject" $contack
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage:$(basename $0){master|backup|fault}"
exit 1
;;
esac
- 开启日志功能:
[root@localhost haproxy]# cat /etc/rsyslog.conf
# rsyslog configuration file
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
#### MODULES ####
# The imjournal module bellow is now used as a message source instead of imuxsock.
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
#$ModLoad imklog # reads kernel messages (the same are read from journald)
#$ModLoad immark # provides --MARK-- message capability
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
#### GLOBAL DIRECTIVES ####
# Where to place auxiliary files
$WorkDirectory /var/lib/rsyslog
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on
# Include all config files in /etc/rsyslog.d/
$IncludeConfig /etc/rsyslog.d/*.conf
# Turn off message reception via local log socket;
# local messages are retrieved through imjournal now.
$OmitLocalLogging on
# File to store the position in the journal
$IMJournalStateFile imjournal.state
#### RULES ####
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
# Everybody gets emergency messages
*.emerg :omusrmsg:*
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
local2.* /var/log/haproxy.log #haproxy日志定义
# ### begin forwarding rule ###
# The statement between the begin ... end define a SINGLE forwarding
# rule. They belong together, do NOT split them. If you create multiple
# forwarding rules, duplicate the whole block!
# Remote Logging (we use TCP for reliable delivery)
#
# An on-disk queue is created for this action. If the remote host is
# down, messages are spooled to disk and sent when it is up again.
#$ActionQueueFileName fwdRule1 # unique name prefix for spool files
#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible)
#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
#$ActionQueueType LinkedList # run asynchronously
#$ActionResumeRetryCount -1 # infinite retries if host is down
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
#*.* @@remote-host:514
# ### end of the forwarding rule ###
[root@localhost keepalived]# cat keepalived.conf #haproxy 1 keepalive配置
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from mask@foxmail.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.14.14
}
vrrp_script chk_haproxy {
script "killall -0 haproxy && exit 0 || exit1"
interval 1
weight -5
fall 2
rise 1
}
vrrp_instance my1 {
state BACKUP
interface eno16777736
virtual_router_id 51
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.18.14.31 dev eno16777736 label ens33:0
}
track_script {
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
[root@localhost keepalived]# cat notify.sh
#!bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(ohstname)to be $1,vip floating"
mailbody="$(date +'%F %T'):vrrp transition, $(hostname)to be $!"
echo "$mailbody" | mail -s "mailsubject" $contack
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage:$(basename $0){master|backup|fault}"
exit 1
;;
esac
###K
keepalived (haproxy2) 配置
[root@localhost keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from mask@foxmail.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node1
vrrp_mcast_group4 224.0.14.14
}
vrrp_script chk_haproxy {
script "killall -0 haproxy && exit 0 || exit1"
interval 1
weight -5
fall 2
rise 1
}
vrrp_instance my1 {
state BACKUP
interface eno16777736
virtual_router_id 51
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.18.14.31 dev eno16777736 label ens33:0
}
track_script {
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
[root@localhost keepalived]# cat notify.sh
#!bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(ohstname)to be $1,vip floating"
mailbody="$(date +'%F %T'):vrrp transition, $(hostname)to be $!"
echo "$mailbody" | mail -s "mailsubject" $contack
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage:$(basename $0){master|backup|fault}"
exit 1
;;
esac
开启日志功能请参考 第J章节 keepalive(haproxy 1)
###L
一切准备完毕,测试: