背景介绍
最近,我们部署了Oceanbase数据库(以下简称OB),并将部分业务迁移至OB中运行。在部署过程中,我们虽然配置了3个OBProxy,但没有为它们设置高可用配置,应用被固定到某一个OBProxy 上,这使我们在实际的运维工作中遇到了诸多不便。例如,当需要对OB集群中的某个主机进行维护时,我们必须提前与业务部门沟通,协商停机时间,并要求业务方配合关停服务,这样的流程不仅繁琐,而且给业务方带来了不佳的体验。
由于在网上没有看到如何利用开源组件,实现OBProxy的高可用的内容,以提高OB集群对于故障、停机等服务不可用情况的容忍度,所以,我们尝试用HAproxy作为HA组件来反代OBProxy,并将其记录与分享给大家参考。如有更好的建议,欢迎随时留言沟通。
拓扑介绍
准备工作
主机配置:
系统:https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso内核:3.10.0-1160.el7.x86_64
$ grubby --update-kernel=ALL --args="numa=off"
$ grubby --update-kernel=ALL --args="transparent_hugepage=never"$ systemctl stop postfix.service
$ systemctl disable postfix
$ systemctl disable auditd
$ systemctl disable kdump$ systemctl stop firewalld.service
$ systemctl disable firewalld.service
$ sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config
$ setenforce 0$ sed -i "s/\#UseDNS yes/UseDNS no/g" /etc/ssh/sshd_config
$ sed -i "s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g" /etc/ssh/sshd_config
YUM源准备:
# 备份
$ mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
$ mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
$ mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup# 下载Base源
$ curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
$ sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
# 下载epel源
$ curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
$ yum clean all
$ yum makecache
内核参数
$ cat >> /etc/sysctl.conf << EOF
# for oceanbase
## 修改内核异步 I/O 限制
fs.aio-max-nr=1048576## 网络优化
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 10000
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216net.ipv4.ip_local_port_range = 3500 65535
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_slow_start_after_idle=0vm.swappiness = 0
vm.min_free_kbytes = 2097152
fs.file-max = 6573688# 修改进程可以拥有的虚拟内存区域数量
vm.max_map_count = 655360# 此处为 OceanBase 数据库的 data 目录
kernel.core_pattern = /data/core-%e-%p-%t
EOF
$ sysctl -p
$ cat >>/etc/security/limits.conf <<EOF
* soft nproc 655300
* hard nproc 655300
* soft nofile 655300
* hard nofile 655300
* soft core unlimited
* hard core unlimited
* soft stack unlimited
* hard stack unlimited
admin soft nofile 655350
admin hard nofile 655350
admin soft stack unlimited
admin hard stack unlimited
admin soft nproc 655360
admin hard nproc 655360
EOF$ cat >>/etc/security/limits.d/20-nproc.conf <<EOF
* soft nproc 655300
* soft nofile 655300
* soft core unlimited
* soft stack unlimited
root soft nproc unlimited
EOF
基础软件包安装
$ yum install -y tree nmap dos2unix lrzsz nv lsof wget tcpdump htop iftop iotop sysstat nethogs
$ yum install -y psmisc net-tools bash-completion vim-enhanced
# 安装bash命令tab自动补全组件
$
# 安装vim编辑器
$ yum -y install vim screen lrzsz tree psmisc
# 安装压缩解压工具
$ yum -y install zip unzip bzip2 gdisk
# 安装网络及性能监控工具
$ yum -y install telnet net-tools sysstat iftop lsof iotop htop dstat
到这一步,最好重启一下机器。
安装HAproxy
安装HAproxy
两台机器都采用相同的操作
$ yum install -y haproxy
验证软件包是否被正确安装
$ rpm -qa | grep haproxy
haproxy-1.5.18-9.el7_9.1.x86_64
版本可能与本文存在差异,但一定要高于1.4.9
准备一个数据目录,如果有条件,可以把数据目录单独mount
到一个磁盘上面
$ mkdir -p /data/haproxy
$ chown -R haproxy:haproxy /data/haproxy
准备HAproxy的配置文件
备份原始的配置文件(两个节点都需要操作)
mv /etc/haproxy/haproxy.cfg{,.bak}
节点OBHA-T1
的配置文件(/etc/haproxy/haproxy.cfg
):
## https://cloud.tencent.com/developer/article/2046159
# 全局配置主要用于设定义全局参数,属于进程级的配置,通常和操作系统配置有关
global# 定义全局的syslog服务器,接收haproxy启动和停止的日志。最多可以定义两个;# log <address> <facility> [max level [min level]] log 127.0.0.1 local0 err# 设定每haproxy进程所接受的最大并发连接数,当达到此限定连接数后将不再接受新的连接。该参数特指和客户端的连接数,不包括和服务端的连接。等同于命令行选项"-n";"ulimit -n"就是根据此值进行自动调整的;maxconn 8000# 设定每进程能够打开的最大文件描述符数量,默认haproxy会自动进行计算,因此不推荐修改此选项;(不建议设置项)#ulimit-n 16384# 和多进程haproxy有关,由于不建议使用多进程,所以也不建议设置此项。但建议设置为"stats socket"将套接字和本地文件进行绑定,如"stats socket /var/lib/haproxy/stats"。#stats timeout 30s# 修改haproxy工作目录至指定目录,可提升haproxy安全级别,但要确保必须为空且任何用户均不能有写权限;chroot /data/haproxy# 以指定的UID或用户名身份运行haproxy进程;user haproxy# 以指定的GID或组名运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;group haproxy# 让haproxy以守护进程的方式工作于后台,等同于命令行的"-D"选项,当然,也可以在命令行中以"-db"选项将其禁用;(建议设置项)daemon# (配置默认参数,这些参数可以被用到frontend,backend,Listen组件)
# 在此部分中设置的参数值,默认会自动引用到下面的frontend、backend、listen部分中,
# 因引,某些参数属于公用的配置,只需要在defaults部分添加一次即可。
# 而如果frontend、backend、listen部分也配置了与defaults部分一样的参数,Defaults部分参数对应的值自动被覆盖。
defaults# 所处理的类别(7层代理http,4层代理tcp) mode tcp# 最大连接数maxconn 6000log global# 日志类别为http日志格式 option httplog# 不记录健康检查日志信息 option dontlognull# 3次连接失败就认为服务器不可用,也可以通过后面设置 retries 3# 设置连接超时时间timeout connect 10s# 设置连接超时时间timeout client 1m# 设置服务器超时时间 timeout server 1m# 默认队列超时时间timeout queue 1m# 设置心跳检查超时时间timeout check 10s# 默认持久连接超时时间# timeout http-keep-alive 15s# 默认http请求超时时间# timeout http-request 10s# ( 接收请求的前端虚拟节点,Frontend可以更加规则直接指定具体使用后端的backend)
# frontend是在haproxy 1.3版本以后才引入的一个组件,同时引入的还有backend组件。
# 通过引入这些组件,在很大程度上简化了haproxy配置文件的复杂性。
# forntend可以根据ACL规则直接指定要使用的后端backend。
frontend obrsproxybind 0.0.0.0:2883bind 127.0.0.1:2883mode tcpoption tcplogdefault_backend obrsproxy# (后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器)
# 在HAProxy1.3版本之前,HAProxy的所有配置选项都在这个部分中设置。
# 为了保持兼容性,haproxy新的版本依然保留了listen组件配置试。两种配置方式任选一中。
backend obrsproxymode tcpoption tcplogoption tcp-checkbalance roundrobindefault-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100server OBC-T1 192.168.1.36:2883 checkserver OBC-T2 192.168.1.37:2883 checkserver OBC-T3 192.168.1.38:2883 check# (Fronted和backend的组合体) 比如haproxy实例状态监控部分配置
# 定义一个监控页面,监听在18080端口,并启用了验证机制
Listen stats# 设置模式为httpmode http# haroxy的ip地址和端口bind 192.168.1.33:18080 # 错误日志记录log 127.0.0.1 local3 err# 设置监控页面刷新时间:30s stats refresh 30sstats enable# 隐藏统计页面的HAproxy版本信息 stats hide-version# 设置监控页面的urlstats uri /haproxyadmin?stats #开启网页访问# 设置页面提示信息 stats realm Haproxy\ Statistics# 用户名和密码stats auth admin:admin# 设置手工启动/禁用,后端服务器(haproxy-1.4.9以后版本)stats admin if TRUE
节点OBHA-T2
的配置文件(/etc/haproxy/haproxy.cfg
):
globallog 127.0.0.1 local0 errmaxconn 8000chroot /data/haproxyuser haproxygroup haproxydaemondefaultsmode tcpmaxconn 6000log globaloption httplogoption dontlognullretries 3timeout connect 10stimeout client 1m timeout server 1mtimeout queue 1mtimeout check 10sfrontend obrsproxybind 0.0.0.0:2883bind 127.0.0.1:2883mode tcpoption tcplogdefault_backend obrsproxybackend obrsproxymode tcpoption tcplogoption tcp-checkbalance roundrobindefault-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100server OBC-T1 192.168.1.36:2883 checkserver OBC-T2 192.168.1.37:2883 checkserver OBC-T3 192.168.1.38:2883 checkListen statsmode httpbind 192.168.1.34:18080 log 127.0.0.1 local3 errstats refresh 30sstats enablestats hide-versionstats uri /haproxyadmin?stats #开启网页访问stats realm Haproxy\ Statisticsstats auth admin:adminstats admin if TRUE
启动服务
$ systemctl enable --now haproxy.service
$ systemctl status haproxy.service
● haproxy.service - HAProxy Load BalancerLoaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)Active: active (running) since Fri 2024-06-21 12:00:15 CST; 1min 13s agoMain PID: 18700 (haproxy-systemd)CGroup: /system.slice/haproxy.service├─18700 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid├─18701 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds└─18702 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -DsJun 21 12:00:15 OBHA-T2 systemd[1]: Stopped HAProxy Load Balancer.
Jun 21 12:00:15 OBHA-T2 systemd[1]: Started HAProxy Load Balancer.
Jun 21 12:00:15 OBHA-T2 haproxy-systemd-wrapper[18700]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
安装keepalived
安装keepalived
两台机器都采用相同的操作
$ yum install -y keepalived
验证软件包是否被正确安装
$ rpm -qa | grep keepalived
keepalived-1.3.5-19.el7.x86_64
版本可以与本文不一致
准备keepalived的配置文件
备份2部机器上的keepalived的配置文件:
$ mv /etc/keepalived/keepalived.conf{,.bak}
创建OBHA-T1
上的keepalived
配置文件/etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {router_id OBHA-T1
}
vrrp_script chk_haproxy {script "/etc/keepalived/check_haproxy.sh"interval 5 weight -5fall 2rise 1
}
vrrp_instance VI_1 {state MASTERinterface ens192mcast_src_ip 192.168.1.33virtual_router_id 35priority 101nopreemptadvert_int 2authentication {auth_type PASSauth_pass OB_HA_AUTH}virtual_ipaddress {192.168.1.35}track_script {chk_haproxy
} }
创建OBHA-T2
上的keepalived
配置文件/etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {router_id OBHA-T1
}
vrrp_script chk_haproxy {script "/etc/keepalived/check_haproxy.sh"interval 5 weight -5fall 2rise 1
}
vrrp_instance VI_1 {state MASTERinterface ens192mcast_src_ip 192.168.1.34virtual_router_id 35priority 100nopreemptadvert_int 2authentication {auth_type PASSauth_pass OB_HA_AUTH}virtual_ipaddress {192.168.1.35}track_script {chk_haproxy
} }
注意: 本节所述的配置文件中的interface指的是服务器的网卡名称,实际环境可能与本文有差异,以实际环境配置为准。 两部服务器上的keepalived的配置文件中virtual_router_id 的值必须相同。
准备keepalived的检测脚本
三台上的脚本一样,文件路径为/etc/keepalived/check_haproxy.sh
#!/bin/basherr=0
for k in $(seq 1 3)
docheck_code=$(pgrep haproxy)if [[ $check_code == "" ]]; thenerr=$(expr $err + 1)sleep 1continueelseerr=0breakfi
doneif [[ $err != "0" ]]; thenecho "systemctl stop keepalived"/usr/bin/systemctl stop keepalivedexit 1
elseexit 0
fi
为检测脚本添加执行权限
$ chmod +x /etc/keepalived/check_haproxy.sh
启动服务
两台机器上的操作相同
$ systemctl daemon-reload
$ systemctl enable --now keepalived
检查服务
$ systemctl status keepalived.service
● keepalived.service - LVS and VRRP High Availability MonitorLoaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)Active: active (running) since Fri 2024-06-21 13:54:54 CST; 40s agoProcess: 22784 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)Main PID: 22785 (keepalived)CGroup: /system.slice/keepalived.service├─22785 /usr/sbin/keepalived -D├─22786 /usr/sbin/keepalived -D└─22787 /usr/sbin/keepalived -D
$ ping -c 4 192.168.1.35
PING 192.168.1.35 (192.168.1.35) 56(84) bytes of data.
64 bytes from 192.168.1.35: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 192.168.1.35: icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from 192.168.1.35: icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from 192.168.1.35: icmp_seq=4 ttl=64 time=0.034 ms--- 192.168.1.35 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.027/0.041/0.058/0.012 ms
$ telnet 192.168.1.35 2883
Trying 192.168.1.35...
Connected to 192.168.1.35.
Escape character is '^]'.
J
5.6.25AKE=@js'b=��.�E%(9%L3U5HIwmysql_native_password