欢迎来到【进击的辣条】的博客

不曾为梦想奋斗,拿什么去燃烧青春。有梦之人亦终将老去,但少年心气如昨。
太阳每一个时刻都同时是夕阳和朝阳,每天她沉入西边,意味着她同时从另一面土地升起。
扩大
缩小

Haproxy安装部署文档及多配置文件管理方案

最近我在负责一个统一接入层的建设项目,涉及到 Haproxy 和 ospf 的运维部署,本文分享一下我在部署 Haproxy 之后整理的运维部署规范,并实现了Haproxy 的多配置文件管理方案Haproxy安装部署文档及多配置文件管理方案

一、部署安装

1、下载源码包

最新 stable 版本下载地址:http://www.haproxy.org/download/1.7/src/haproxy-1.7.9.tar.gz

2、编译安装

tar zxf haproxy-1.7.9.tar.gz
cd haproxy-1.7.9
make TARGET=linux31 prefix=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy

3、创建目录

mkdir-p/usr/local/haproxy/conf/ready/tcp
mkdir-p/usr/local/haproxy/conf/ready/http
mkdir-p/usr/local/haproxy/conf/enabled/tcp
mkdir-p/usr/local/haproxy/conf/enabled/http
mkdir-p/usr/local/haproxy/logs
mkdir-p/data/wwwlogs/logs

二、软件配置

熟悉 Nginx 和 Apache 的朋友都知道,这两个 Webservice 都支持 include 加载多个配置文件的语法,但是 Haproxy 并不支持!如果现网映射规则非常多,那么 haproxy.cfg 这个配置文件就跟臭袜子一样,又臭又长!

因此,我也是翻遍了国外的各种论坛帖子,终于发现一种变相实现 Haproxy 多配置文件的方案。其实,Hparoxy 是支持多配置文件的,但是不是 include 语法,而是在启动的时候多次使用-f 拼接配置文件,比如:

cd/usr/local/haproxy/sbin
./haproxy-f../conf/haproxy.cfg-f../conf/ext1.cfg-f../conf/ext2.cfg

因此,我们可以在配置文件目录以及启动脚本上做点改变,让 Haproxy 支持多配置文件。

1、路径约定:

  • 待上线的 tcp 映射规则存放目录:/usr/local/haproxy/conf/ready/tcp
  • 待上线的 http 映射规则存放目录:/usr/local/haproxy/conf/ready/http
  • 已上线的 tcp 映射规则存放目录:/usr/local/haproxy/conf/enabled/tcp
  • 已上线的 http 映射规则存放目录:/usr/local/haproxy/conf/enabled/http
  • Ps:本文为多配置模式,enabled 里面的配置为软链接形式,软链接至 ready 对应配置文件,方便管理。

2、配置模板

①、主配置:haproxy.cfg

 
#configure haproxy.cfg
global
    log127.0.0.1   local0
    maxconn4096              #最大连接数
    chroot/usr/local/haproxy#安装目录
    uid99                    #用户nobody
    gid99                    #组nobody
    daemon                    #守护进程运行
    nbproc1                  #进程数量
    pidfile/usr/local/haproxy/logs/haproxy.pid#haproxy pid
 
defaults
   log     global
   mode    http               #7层 http;4层tcp  如果要让haproxy支持虚拟主机,mode 必须设为http 
   option  httplog            #http 日志格式
   log127.0.0.1local6
   option  httpclose          #主动关闭http通道
   option  redispatch         #serverId对应的服务器挂掉后,强制定向到其他健康的服务器
   retries1
   option  dontlognull
   maxconn2000                     #最大连接数
   timeout connect      3600000     #连接超时(毫秒)
   timeout client      3600000      #客户端超时(毫秒)
   timeout server      3600000      #服务器超时(毫秒)
 
frontend default  
        option  httplog
        option  httpclose
        bind0.0.0.0:80
        # 状态页面规则
        acl haproxy_stats   path_beg/haproxy
        use_backend haproxy_stats ifhaproxy_stats
        # 其他
        # default_backend default_server
        # 提升失败的时候的用户体验
        #errorfile 502 /usr/local/haproxy/html/maintain.html
        #errorfile 503 /usr/local/haproxy/html/maintain.html
        #errorfile 504 /usr/local/haproxy/html/maintain.html
 
# 状态页面
backend haproxy_stats
    stats uri/haproxy
    stats enable
    stats refresh60s
    #stats auth admin:admin  # 状态页面认证配置
    stats admin ifTRUE

②、http 扩展配置文件模板

frontend demo
        option httplog
        option httpclose
        bind192.168.1.10:80# 扩展
        # 域名匹配范例
        acl is_demo hdr_beg(host)-idemo.oa.com
        # 正则范例范例
        acl is_demo_rex hdr_reg(host)-i^demo[0-9].oa.com$
        # 路径匹配范例
        acl is_demo_path path_beg/demo/path
        use_backend demo_oa_com ifis_demo||is_demo_rex||  is_demo_path
 
backend http_demo_ext
        mode http
        # 额外的一些设置,按需使用
        option forwardfor
        option forwardfor header Client-IP
        option http-server-close
        option httpclose
        #balance roundrobin    #负载均衡的方式,轮询方式
        #balance leastconn     #负载均衡的方式,最小连接
        balance source         #负载均衡的方式,根据请求的源IP
        cookie SERVERID insert nocache indirect  # 插入serverid到cookie中,serverid后面可以定义
        # 健康检查
        option httpchk HEAD/index.html HTTP/1.1\r\nHost:\demo.oa.com
        serverx.x.x.xx.x.x.x:80cookie server1 check inter2srise3fall3weight3
        serverx.x.x.xx.x.x.x:80cookie server1 check inter2srise3fall3weight3

③、tcp 扩展配置文件模板

listen tcp_demo_ext
    bind0.0.0.0:3306
    mode tcp
    serverx.x.x.xx.x.x.x:3306weight1check inter1srise2fall2
    serverx.x.x.xx.x.x.x:3306weight1check inter1srise2fall2

Ps:多配置模式中,多个 frontend 必须绑定不同的 IP 或者端口,否则数据会串,导致映射到不同的后端而报错。因此,同一个 IP+端口下的映射务必配置到同一个 frontend 模块内。

三、系统服务

1、服务脚本

对比已有的 Haproxy 脚本,我编写的时候新增了如下实用功能:

  • 支持配置文件语法测试
  • 支持进程的监控(自拉起)功能
  • 重启之前会先检测配置语法,规避因配置错误导致重启后进程挂掉
  • 支持多配置文件模式(按照前文约定目录存放拓展配置,脚本将自动识别)

下面是服务脚本代码:

Shell
#!/bin/bash
###################################################################
#  Haproxy Service Script 1.0.0 Author: Jager <im@zhang.ge>    #
#  Common Operations(start|stop|restart|mon|test)                 #
#-----------------------------------------------------------------#
#  For more information please visit https://zhang.ge/5125.html #
#  Copyright @2017 zhang.ge. All rights reserved.              #
###################################################################
# chkconfig: 35 10 90
export PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:$PATH
PROCESS_NAME=haproxy
BASE_DIR=/usr/local/haproxy
EXEC=$BASE_DIR/sbin/haproxy
PID_FILE=$BASE_DIR/logs/haproxy.pid
DEFAULT_CONF=$BASE_DIR/conf/haproxy.cfg
MONLOG_PATH="$BASE_DIR/logs/${PROCESS_NAME}_mon.log"
 
# COLOR print
COLOR_RED=$(    echo-e"\e[31;49m")
COLOR_GREEN=$(  echo-e"\e[32;49m")
COLOR_RESET=$(  echo-e"\e[0m"     )
info(){echo"${COLOR_GREEN}$*${COLOR_RESET}"   ;}
warn(){echo"${COLOR_RED}$*${COLOR_RESET}"     ;}
 
do_log()
{
    local log_fpath=$1
    local log_content=$2
    echo"$(date '+%F %T') $log_content">>$log_fpath
}
 
print_usage()
{
    echo
    info" Usage: $(basename $0) [start|stop|restart|mon|test]"
    echo
}
 
#get Expanding configuration
ext_configs()
{
    CONFIGS=
    if[[-d$BASE_DIR/conf/enabled]];then
        forFILEin$(find$BASE_DIR/conf/enabled-typel|sort-n)
        do
                CONFIGS="$CONFIGS -f $FILE";
        done
        echo$CONFIGS
    else
        echo
    fi
}
# check process status
check_process()
{
    PID=`get_pid`
    ifpsaux|awk'{print $2}'|grep-qw$PID2>/dev/null;then
        true
    else
        false
    fi
    
}
# check Configuration file
check_conf()
{
    $EXEC-c-f$DEFAULT_CONF`ext_configs`>/dev/null2>&1
    return$?
}
get_pid()
{
    if[[-f$PID_FILE]];then
        cat$PID_FILE
        else
            warn" $PID_FILE not found!"
                exit1
        fi
}
start()
{
    echo
    ifcheck_process;then
        warn" ${PROCESS_NAME} is already running!"
    else
        $EXEC-f$DEFAULT_CONF`ext_configs`&&\
        echo-e" ${PROCESS_NAME} start                        [ `info OK` ]"||\
        echo-e" ${PROCESS_NAME} start                        [ `warn Failed` ]"
    fi
    echo
}
 
stop()
{
    echo
    ifcheck_process;then
        PID=`get_pid`
        kill-9$PID>/dev/null2>&1
        echo-e" ${PROCESS_NAME} stop                         [ `info OK` ]"
    else
        warn" ${PROCESS_NAME} is not running!"
    fi
    echo
}
 
restart()
{
    echo
    ifcheck_process;then
        :
    else
        warn" ${PROCESS_NAME} is not running! Starting Now..."
    fi
    if`check_conf`;then
        PID=`get_pid`
        $EXEC-f$DEFAULT_CONF`ext_configs`-st$PID&&\
        echo-e" ${PROCESS_NAME} restart                      [ `info OK` ]"||\
        echo-e" ${PROCESS_NAME} restart                      [ `warn Failed` ]"
    else
        warn" ${PROCESS_NAME} Configuration file is not valid, plz check!"
        echo-e" ${PROCESS_NAME} restart                      [ `warn Failed` ]"
    fi
    echo
}
 
mon()
{
    ifcheck_process;then
        info"${PROCESS_NAME} is running OK!"
        do_log$MONLOG_PATH"${PROCESS_NAME} is running OK!"
    else
        start
        warn" ${PROCESS_NAME} not running, start it!"
        do_log$MONLOG_PATH"${PROCESS_NAME} not running, plz check"
    fi
}
 
if[[$# != 1 ]]; then
    print_usage
    exit1
else
    case$1in
        "start"|"START")
            start
        ;;
        "stop"|"STOP")
            stop
        ;;
        "restart"|"RESTART"|"-r")
            restart
        ;;
        "status"|"STATUS")
            ifcheck_process;then
                info"${PROCESS_NAME} is running OK!"
            else
                warn" ${PROCESS_NAME} not running, plz check"
            fi
        ;;
        "test"|"TEST"|"-t")
            echo
            ifcheck_conf;then
                info" Configuration file test Successfully."
            else
                warn" Configuration file test failed."
            fi
            echo
        ;;
        "mon"|"MON"|"-m")
            mon
        ;;
        *)
        print_usage
        exit1
    esac
fi

保存为 /usr/local/haproxy/sbin/ctrl.sh,赋可执行权限,如下注册系统服务:

chmod+x/usr/local/haproxy/sbin/ctrl.sh
ln-sf/usr/local/haproxy/sbin/ctrl.sh  /etc/init.d/haproxy
chkconfig haproxy on

服务控制:

启动:service haproxy start
停止:service haproxy stop
重载:service haproxy restart
状态:service haproxy status
检查:service haproxy test
监控:service haproxy mon  # 进程自拉起,如有告警通道可自行加入

2、配置自拉起

*****bash/usr/local/haproxy/ctrl.sh mon>/dev/null2>&1

全部完成后,最终目录结构如下:

[root@locahost:/usr/local/haproxy]# tree
.
├──conf
│   ├──enabled  # 正式使用的拓展配置
│   │   ├──http  
│   │   │   └──demo.cfg->/usr/local/haproxy/conf/ready/http/demo.cfg# 此处软链到可以上线的配置
│   │   └──tcp
│   │       └──demo.cfg->/usr/local/haproxy/conf/ready/tcp/demo.cfg
│   ├──haproxy.cfg
│   └──ready     # 存在预发布的拓展配置
│       ├──http
│       │   └──demo.cfg
│       │   └──other.cfg
│       └──tcp
│           └──demo.cfg
│           └──other.cfg
├──doc
│    .....
├──logs
│   └──haproxy.pid
├──sbin
│   ├──ctrl.sh
│   └──haproxy
└──share
    └─...
14directories,24files

四、日志配置

配置 rsyslog

mkdir-p/data/wwwlogs
vim/etc/rsyslog.conf  或/etc/syslog.conf
 
#新增配置
local6.*/data/wwwlogs/haproxy.log
 
#取消如下2行注释
$ModLoad imudp
$UDPServerRun514
 
#重启syslog服务
service rsyslog restart

五、小结

以上内容就是我对 Haproxy 部署规范的整理,并通过拼接方式变相实现了 Haproxy 的多配置文件管理。当然,略遗憾的是未能实现 Haproxy 的 WEB 管理方案,这个有待继续研究实现,敬请期待!

转自:https://zhang.ge/5125.html

posted on 2019-05-08 00:35 进击的辣条 阅读(...) 评论(...) 编辑 收藏

导航