一、HAProxy概述:

  HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。
  HAProxy特别适用于那些负载特大的web站点, 这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
其支持从4层至7层的网络交换,即覆盖所有的TCP协议。就是说,Haproxy 甚至还支持 Mysql的均衡负载。

  相同点:在功能上,proxy通过反向代理方式实现 WEB均衡负载。和 Nginx,ApacheProxy,lighttpd,Cheroke 等一样。
  不同点:Haproxy 并不是 web 服务器。以上提到所有带反向代理均衡负载的产品,都清一色是 WEB 服务器。简单说,就是他们能处理解析页面的。而Haproxy 仅仅是一款的用于均衡负载的应用代理。其自身并不能提供web服务。但其配置简单,拥有非常不错的服务器健康检查功能还有专门的系统状态监控页面,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。
  www.haproxy.org       #打不开
  http://haproxy.com/    #收费
  http://haproxy.1wt.eu/     #社区版地址, 打不开
  https://github.com/haproxy/haproxy/releases/ 在github 可以下载
实验拓扑图:

shard的负载均衡 负载均衡 haproxy_vim

二、实战

1.安装依赖

[root@xuegod63 ~]# yum -y install make gcc gcc-c++ openssl-devel

2.安装haproxy

[root@xuegod63 ~]# tar -zxvf haproxy-2.3.5.tar.gz
[root@xuegod63 haproxy-2.3.5]# cd /usr/local/haproxy-2.3.5
[root@xuegod63 haproxy-2.3.5]# uname -r   #查看内核版本
3.10.0-1127.el7.x86_64
[root@xuegod63 haproxy-2.3.5]# make TARGET=linux-glibc PREFIX=/usr/local/haproxy     #指定操作系统内核类型和安装的路径。也可以直接修改Makefile配置文件中这两个变量的值。如下:
[root@xuegod63 haproxy-2.3.5]# vim Makefile
#   [g]make help
#   [g]make help TARGET=linux-glibc
[root@xuegod63 haproxy-2.3.5]# make install PREFIX=/usr/local/haproxy    
#如果没有修改Makefile配置文件中PREFIX变量的值,就必须在此重新对,PREFIX=/usr/local/haproxy赋值,否则直接执行 make install 时,make install会直接读取Makefile文件中PREFIX的变量值。
[root@xuegod63 haproxy-2.3.5]# ls /usr/local/haproxy/
doc  sbin  share

3. 创建HAProxy运行账户和组

#添加haproxy组
groupadd -r haproxy
#创建nginx运行账户haproxy并加入到haproxy组,不允许haproxy用户直接登录系统
useradd -r -g haproxy -M -s /sbin/nologin haproxy

4. 没有生成配置文件,自己手动写一个HAproxy配置文件

[root@node203 haproxy]# mkdir -p /usr/local/haproxy/conf log errorfiles
[root@node203 haproxy]# touch /usr/local/haproxy/conf/haproxy.cfg
[root@node203 conf]# vim /usr/local/haproxy/conf/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log    127.0.0.1 local3 info         ###[err warning info debug]
    chroot  /usr/local/haproxy
    pidfile  /var/run/haproxy.pid   ###haproxy的pid存放路径,启动进程的用户必须有权限访问此文件
    maxconn  65530                   ###最大连接数,默认4000
    user   haproxy
    group   haproxy
    daemon                          ###创建1个进程进入deamon模式运行。此参数要求将运行模式设置为"daemon"

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    log     global                 ###采用全局定义的日志
    log     127.0.0.1 local3 info  ###日志文件的输出定向。产生的日志级别为local3. 系统中local1-7,用户自己定义
    mode    http                   ###工作模式,所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
    option  httplog                ###日志类别,记载http日志
    option  dontlognull            ###不记录空连接产生的日志信息
    option  httpclose              ###每次请求完毕后主动关闭http通道,haproxy不支持keep-alive
    retries                 3      ###3次连接失败就认为服务器不可用,主要通过后面的check检查
    maxconn 65530                  #最大连接数
    timeout http-request    10s
    timeout queue           1m
    timeout connect         60s    ###default 10 second timeout if a backend is not found
    timeout client          2m     ###客户端连接超时
    timeout server          2m     ###服务器连接超时
    timeout http-keep-alive 10s
    timeout check           10s
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend frontend_emqx_tcp
    bind *:1883
    option tcplog
    mode tcp
    default_backend backend_emqx_tcp

frontend frontend_emqx_dashboard
    bind *:18083
    option tcplog
#    mode tcp
    mode http
    default_backend backend_emqx_dashboard
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------

backend backend_emqx_tcp
    mode tcp
    balance roundrobin
    server emqx_node_1 192.168.3.143:1883 check-send-proxy send-proxy-v2 check inter 10s fall 2 rise 5
    server emqx_node_2 192.168.3.144:1883 check-send-proxy send-proxy-v2 check inter 10s fall 2 rise 5

    # inter 10s 健康检查时间间隔10秒
    # rise 2 检测多少次才认为是正常的
    # fall 5 失败多少次才认为是不可用的

backend backend_emqx_dashboard
    mode http
    balance roundrobin
    server emqx_node_1 192.168.3.143:18083 check
    server emqx_node_2 192.168.3.144:18083 check

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------

 listen haproxy_stats
         stats   enable
         bind    *:8082
         mode    http
         option  httplog
         log     global
         maxconn 10
         stats   refresh 30s
         stats   uri /admin
         stats   realm haproxy
         stats   auth admin:admin
         stats   hide-version
         stats   admin if TRUE

关于负载均衡算法
  #source    根据请求源IP
  #static-rr   根据权重
  #leastconn    最少连接者先处理
  #uri     根据请求的uri
  #url_param   根据请求的url参数
  #rdp-cookie  据据cookie(name)来锁定并哈希每一次请求
  #hdr(name)  根据HTTP请求头来锁定每一次HTTP请求
  #roundrobin  轮询方式

5.设置haproxy启动脚本

[root@node203 conf]# cp /usr/local/haproxy-2.3.5/examples/haproxy.init /etc/init.d/haproxy
[root@node203 conf]# chmod 755 /etc/init.d/haproxy
[root@node203 conf]# vim /etc/init.d/haproxy   #修改后的脚本
#!/bin/sh
#
# chkconfig: - 85 15
# description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited \
#              for high availability environments.
# processname: haproxy
# config: /etc/haproxy/haproxy.cfg
# pidfile: /var/run/haproxy.pid

# Script Author: Simon Matter <simon.matter@invoca.ch>
# Version: 2004060600

# Source function library.
if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
else
  exit 0
fi

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

# This is our service name
# 替换之前内容
# 修改调整Begin
BASENAME=`haproxy`
BIN=/usr/local/haproxy/sbin/haproxy
CFG=/usr/local/haproxy/conf/haproxy.cfg
[ -f $CFG ] || exit 1

PIDFILE=/var/run/haproxy.pid
LOCKFILE=/var/lock/subsys/$BASENAME
# 修改调整END
RETVAL=0

start() {
  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi

  echo -n "Starting $BASENAME: "
  daemon $BIN -D -f $CFG -p $PIDFILE
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && touch $LOCKFILE
  return $RETVAL
}

stop() {
  echo -n "Shutting down $BASENAME: "
  killproc $BASENAME -USR1
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
  [ $RETVAL -eq 0 ] && rm -f $PIDFILE
  return $RETVAL
}

restart() {
  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi
  stop
  start
}

reload() {
  if ! [ -s $PIDFILE ]; then
    return 0
  fi

  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi
  $BIN -D -f $CFG -p $PIDFILE -sf $(cat $PIDFILE)
}

check() {
  $BIN -c -q -V -f $CFG
}

quiet_check() {
  $BIN -c -q -f $CFG
}

rhstatus() {
  status $BASENAME
}

condrestart() {
  [ -e $LOCKFILE ] && restart || :
}

# See how we were called.
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    reload
    ;;
  condrestart)
    condrestart
    ;;
  status)
    rhstatus
    ;;
  check)
    check
    ;;
  *)
    echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}"
    exit 1
esac

exit $?

6. 配置日志收集

[root@xuegod63 ~]# vim /etc/rsyslog.conf    #打开以下两行的注释,不打开收不到日志
$ModLoad imudp            #取消注释
$UDPServerRun 514          #取消注释
local3.*          /var/log/haproxy.log
# local7.*          /var/log/boot.log       #下面添加两行
# local0.*          /var/log/haproxy.log
[root@xuegod63 ~]# systemctl  restart  rsyslog

7. 启动停止haproxy服务

特殊启动方法1
[root@xuegod63 etc]# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg
查看状态:
[root@xuegod63 etc]# ps -axu | grep haproxy
haproxy   1735     1  0 17:44 ?        00:00:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg
root      1785  9786  0 17:44 pts/0    00:00:00 grep --color=auto haproxy
 
[root@node203 conf]# netstat -antup | grep 1883
tcp        0      0 0.0.0.0:1883            0.0.0.0:*               LISTEN      1735/haproxy
[root@node203 conf]# netstat -antup | grep 18083
tcp        0      0 0.0.0.0:18083           0.0.0.0:*               LISTEN      1735/haproxy       
 
##停止
[root@xuegod63 etc]# killall haproxy   #没有killall命令?安装yum -y install psmisc
 
HAproxy脚本启动方法2
[root@xuegod63 ~]# /etc/init.d/haproxy start  

HAproxy脚本启动方法3
# 并通过以下命令加载到开机服务启动列表
[root@xuegod63 ~]# chkconfig --add haproxy
[root@xuegod63 ~]# systemctl  start  haproxy
[root@xuegod63 ~]# systemctl  stop  haproxy
[root@xuegod63 ~]# systemctl  restart  haproxy

8.查看HAproxy的监控页面

 http://192.168.3.203:8082/admin_stats,类似如下图

shard的负载均衡 负载均衡 haproxy_HTTP_02