haproxy 的启停管理脚本

这个脚本本质是一个 haproxy 的启停管理脚本,核心功能:

  1. mkcfSTR 函数:动态生成 haproxy 配置文件(/app/haproxy/conf/ha.cf),包含全局配置、默认配置、监控页面配置和 TCP 反向代理(10051 端口转发到两个后端节点)。
  2. start 函数:强制杀死现有 haproxy 进程 → 重新生成配置文件 → 启动 haproxy → 启动成功后清空配置文件。
  3. stop 函数:强制杀死所有 haproxy 进程。
  4. listenXI 函数:检查 haproxy 是否运行,未运行则执行 start。
  5. case 分支:支持start/stop/restart/listen四种执行参数。
#!/bin/bash
##############################################################################
# 脚本名称: haproxy_manager.sh
# 脚本功能: 管理haproxy服务(启动/停止/重启/监听检查)
# 配置路径: /app/haproxy/conf/ha.cf
# 运行用户: 建议root用户执行(需创建进程、绑定端口)
# 功能说明:
#   1. 启动:强制停止现有haproxy → 生成配置文件 → 启动haproxy
#   2. 停止:强制停止所有haproxy进程
#   3. 重启:先停止再启动
#   4. 监听:检查haproxy是否运行,未运行则启动
# 注意事项:
#   1. 需确保/app/haproxy/sbin/haproxy可执行
#   2. 需确保7001用户/组存在(haproxy运行用户)
#   3. 绑定8080/10051端口需root权限
##############################################################################

# ======================== 配置项定义 ========================
haproxy_cf="/app/haproxy/conf/ha.cf"  # haproxy配置文件路径
haproxy_bin="/app/haproxy/sbin/haproxy"  # haproxy可执行文件路径
haproxy_pid="/var/run/haproxy-private.pid"  # haproxy PID文件
log_file="/var/log/haproxy_manager.log"  # 脚本运行日志

# ======================== 日志函数 ========================
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> $log_file
}

# ======================== 生成haproxy配置文件 ========================
mkcfSTR() {
    # 检查配置目录是否存在,不存在则创建
    if [[ ! -d $(dirname $haproxy_cf) ]]; then
        mkdir -p $(dirname $haproxy_cf)
        chmod 755 $(dirname $haproxy_cf)
        log "创建haproxy配置目录: $(dirname $haproxy_cf)"
    fi

    # 生成haproxy配置文件
    cat >$haproxy_cf <<EOF
global
    maxconn 65535                # 最大并发连接数
    chroot /app/haproxy          # 切换根目录,增强安全性
    uid 7001                     # haproxy运行用户ID
    gid 7001                     # haproxy运行组ID
    daemon                       # 以守护进程运行
    stats socket /var/lib/haproxy/stats  # 统计信息套接字
    quiet                        # 静默模式,减少日志输出
    nbproc 1                     # 启动1个进程
    pidfile $haproxy_pid         # PID文件路径

defaults
    log global                   # 使用global段的日志配置
    mode tcp                     # 默认工作模式为TCP(四层代理)
    option httplog               # 记录HTTP日志
    option dontlognull           # 不记录空连接日志
    option redispatch            # 连接失败时重新分发到其他服务器
    option abortonclose          # 客户端连接关闭时终止会话
    log 127.0.0.1 local0 err     # 错误日志发送到本地syslog
    retries 4                    # 连接重试次数
    maxconn 65535                # 每个进程最大并发连接数
    contimeout 5000              # 连接超时时间(ms)
    clitimeout 50000             # 客户端超时时间(ms)
    srvtimeout 50000             # 服务器超时时间(ms)

# 管理监控页面配置
listen admin_stats
    stats enable                 # 启用统计功能
    bind *:8080                  # 监控页面绑定8080端口
    mode http                    # 监控页面工作模式为HTTP
    option httplog               # 记录HTTP日志
    log global                   # 使用global段日志配置
    maxconn 10                   # 监控页面最大并发数
    stats refresh 30s            # 监控页面自动刷新时间
    stats uri /admin?stats=bqezYrdtotiq6bajrvzqpbcTe4&key=auGj2cnxdunljsm4batxqqxphQ  # 监控页面访问路径
    stats realm haproxy          # 认证提示信息
    stats auth admin:sM9we6Idyf  # 监控页面认证账号密码
    stats hide-version           # 隐藏haproxy版本信息
    stats admin if TRUE          # 启用监控页面管理功能

# ZBXXISRT业务代理配置(10051端口转发)
listen ZBXXISRT
    bind 0.0.0.0:10051           # 绑定10051端口
    mode tcp                     # TCP模式
    option redispatch            # 连接失败重分发
    option abortonclose          # 关闭连接时终止会话
    retries 4                    # 重试次数
    maxconn 64000                # 最大并发连接数
    contimeout 5000              # 连接超时
    clitimeout 50000             # 客户端超时
    srvtimeout 50000             # 服务器超时
    balance roundrobin           # 负载均衡算法:轮询
    # 后端服务器配置(权重1,最大连接40000,5秒检查一次状态)
    server 172.16.12.242:20051 172.16.12.242:20051 weight 1 maxconn 40000 check inter 5s
    server 172.16.12.220:20051 172.16.12.220:20051 weight 1 maxconn 40000 check inter 5s
EOF

    # 检查配置文件生成结果
    if [[ $? -eq 0 ]]; then
        log "haproxy配置文件生成成功: $haproxy_cf"
        chmod 644 $haproxy_cf  # 设置配置文件权限
        return 0
    else
        log "haproxy配置文件生成失败"
        echo -e "\e[1;31mhaproxy配置文件生成失败!\e[0;m"
        return 1
    fi
}

# ======================== 启动haproxy ========================
start() {
    log "开始启动haproxy服务"
    
    # 1. 停止现有haproxy进程
    if [[ -f $haproxy_pid ]] && ps -p $(cat $haproxy_pid) >/dev/null 2>&1; then
        log "检测到haproxy已运行(PID: $(cat $haproxy_pid)),先停止"
        kill -9 $(cat $haproxy_pid) >/dev/null 2>&1
        rm -f $haproxy_pid
    elif [[ $(pgrep haproxy 2>/dev/null | wc -l) -gt 0 ]]; then
        log "检测到haproxy进程存在,强制停止所有进程"
        pgrep haproxy | xargs kill -9 >/dev/null 2>&1
    fi

    # 2. 验证haproxy可执行文件
    if [[ ! -x $haproxy_bin ]]; then
        log "haproxy可执行文件不存在或无执行权限: $haproxy_bin"
        echo -e "\e[1;31mhaproxy可执行文件不存在或无执行权限!\e[0;m"
        return 1
    fi

    # 3. 生成配置文件
    mkcfSTR
    if [[ $? -ne 0 ]]; then
        return 1
    fi

    # 4. 启动haproxy
    $haproxy_bin -f $haproxy_cf
    if [[ $? -eq 0 ]]; then
        # 等待1秒确保进程启动
        sleep 1
        if [[ $(pgrep haproxy 2>/dev/null | wc -l) -gt 0 ]]; then
            log "haproxy启动成功"
            echo -e "\e[1;32mhaproxy启动成功.\e[0;m"
            return 0
        else
            log "haproxy启动命令执行成功,但未检测到进程"
            echo -e "\e[1;31mhaproxy启动失败:未检测到运行进程!\e[0;m"
            return 1
        fi
    else
        log "haproxy启动命令执行失败"
        echo -e "\e[1;31mhaproxy启动失败:执行命令返回错误!\e[0;m"
        return 1
    fi
}

# ======================== 停止haproxy ========================
stop() {
    log "开始停止haproxy服务"
    
    # 优雅停止(优先使用PID文件)
    if [[ -f $haproxy_pid ]] && ps -p $(cat $haproxy_pid) >/dev/null 2>&1; then
        kill $(cat $haproxy_pid) >/dev/null 2>&1
        sleep 2
        # 检查是否停止成功,未成功则强制杀死
        if ps -p $(cat $haproxy_pid) >/dev/null 2>&1; then
            kill -9 $(cat $haproxy_pid) >/dev/null 2>&1
            log "强制停止haproxy(PID: $(cat $haproxy_pid))"
        fi
        rm -f $haproxy_pid
    # 无PID文件则查找进程并停止
    elif [[ $(pgrep haproxy 2>/dev/null | wc -l) -gt 0 ]]; then
        pgrep haproxy | xargs kill >/dev/null 2>&1
        sleep 2
        # 强制杀死剩余进程
        pgrep haproxy | xargs kill -9 >/dev/null 2>&1
        log "强制停止所有haproxy进程"
    fi

    # 验证停止结果
    if [[ $(pgrep haproxy 2>/dev/null | wc -l) -eq 0 ]]; then
        log "haproxy停止成功"
        echo -e "\e[1;32mhaproxy关闭成功.\e[0;m"
        return 0
    else
        log "haproxy停止失败:仍有进程运行"
        echo -e "\e[1;31mhaproxy关闭失败:仍有进程运行!\e[0;m"
        return 1
    fi
}

# ======================== 监听检查(进程保活) ========================
listenXI() {
    log "检查haproxy运行状态"
    
    if [[ $(pgrep haproxy 2>/dev/null | wc -l) -eq 0 ]]; then
        log "haproxy未运行,启动haproxy"
        start
    else
        log "haproxy已运行(PID: $(pgrep haproxy))"
        echo -e "\e[1;32mhaproxy已在运行.\e[0;m"
    fi
}

# ======================== 主逻辑分支 ========================
case $1 in
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    log "开始重启haproxy服务"
    stop
    sleep 1
    start
    ;;
listen)
    listenXI
    ;;
*)
    echo "用法: $0 {start|stop|restart|listen}"
    log "无效参数: $1,使用默认用法提示"
    exit 1
    ;;
esac

exit $?

先创建日志文件:touch /var/log/haproxy_manager.log && chmod 644 /var/log/haproxy_manager.log

验证 7001 用户 / 组存在:id 7001(不存在则创建:useradd -u 7001 -s /sbin/nologin -M yewu

赋予脚本执行权限:chmod +x haproxy_manager.sh

测试运行:./haproxy_manager.sh start

Categories: 系统运维