3步构建稳定自动化测试环境:Chrome for Testing终极解决方案
2026/5/15 13:10:04
| 角色 | CPU | 内存 | 磁盘 | 网卡 | 系统版本 |
|---|---|---|---|---|---|
| 备份服务器 | 8核+ | 16G+ | 10TB+(SSD/企业级SATA,RAID5) | 千兆双网卡(绑定) | CentOS7.9 x86_64 |
| 客户端 | 2核+ | 4G+ | 按需配置(备份数据本地暂存100G+) | 千兆网卡 | CentOS7.9 x86_64 |
| 环境 | 备份目录/文件 | 说明 |
|---|---|---|
| 通用配置 | /etc/hosts、/etc/resolv.conf、/etc/sysconfig/network-scripts | 系统网络配置 |
| Apache | /etc/httpd/、/var/www/html/、/var/log/httpd/ | 配置文件、网站根目录、访问日志 |
| Nginx | /etc/nginx/、/usr/share/nginx/html/、/var/log/nginx/ | 配置文件、网站根目录、访问日志 |
| MySQL | /etc/my.cnf、/var/lib/mysql/(或自定义数据目录)、MySQL备份文件 | 配置文件、数据目录、逻辑备份(mysqldump) |
| PHP | /etc/php.ini、/etc/php.d/ | PHP配置文件 |
| 应用数据 | 自定义网站数据目录(如/data/www/)、上传文件目录 | 需客户端提前确认路径 |
| 系统关键 | /etc/crontab、/root/.ssh/(可选) | 定时任务、SSH密钥(按需备份) |
# rsync配置目录/etc/rsyncd/# 认证文件(权限600,仅root可读)/etc/rsyncd/rsyncd.secrets# 配置文件/etc/rsyncd/rsyncd.conf# 备份数据存储目录(按客户端IP/主机名分类)/data/rsync_backup/ ├─192.168.1.101/# 客户端IP作为目录名│ ├─full_20251207/# 全量备份(日期后缀)│ └─inc_20251208/# 增量备份(日期后缀)├─192.168.1.102/ └─...# 日志目录/var/log/rsyncd/# rsync认证文件(权限600)/etc/rsyncd/rsyncd.secrets# 备份脚本目录/usr/local/backup/scripts/# 本地暂存目录(备份包生成后推送服务端,推送完成删除)/tmp/backup_temp/# 日志目录/var/log/backup/# 关闭防火墙(永久)systemctl stop firewalld&&systemctl disable firewalld# 关闭SELINUX(永久,需重启生效)sed-i's/SELINUX=enforcing/SELINUX=disabled/'/etc/selinux/config setenforce0# 临时关闭yuminstall-yrsync# 创建配置目录、数据目录、日志目录mkdir-p /etc/rsyncd /data/rsync_backup /var/log/rsyncd# 创建认证文件(格式:用户名:密码)echo"backup_user:Rsync@123456">/etc/rsyncd/rsyncd.secrets# 设置权限(必须600,否则rsync服务启动失败)chmod600/etc/rsyncd/rsyncd.secrets# 创建授权用户列表文件(可选,限制允许访问的用户)echo"backup_user">/etc/rsyncd/rsyncd.allowcat>/etc/rsyncd/rsyncd.conf<<EOF # 全局配置 uid = root gid = root use chroot = no max connections = 50 # 最大并发连接(100台客户端,建议50-100) timeout = 300 # 超时时间(秒) pid file = /var/run/rsyncd.pid lock file = /var/run/rsyncd.lock log file = /var/log/rsyncd/rsyncd.log ignore errors = yes # 忽略传输错误 read only = no # 允许客户端写入(推送备份) list = no # 不允许列出模块 hosts allow = 192.168.1.0/24 # 允许访问的客户端网段(按需修改) hosts deny = * # 拒绝其他所有网段 # 备份模块(名称自定义,客户端需对应) [backup_module] path = /data/rsync_backup # 备份数据存储路径 comment = LAMP/LNMP Backup Module auth users = backup_user # 认证用户(与secrets文件一致) secrets file = /etc/rsyncd/rsyncd.secrets # 认证文件路径 EOF# 启动rsync服务(--daemon后台模式)rsync--daemon --config=/etc/rsyncd/rsyncd.conf# 验证端口(默认873)netstat-tulnp|grep873# 设置开机自启(添加到rc.local)echo"rsync --daemon --config=/etc/rsyncd/rsyncd.conf">>/etc/rc.d/rc.localchmod+x /etc/rc.d/rc.local# 创建配置目录、脚本目录、暂存目录、日志目录mkdir-p /etc/rsyncd /usr/local/backup/scripts /tmp/backup_temp /var/log/backup# 创建认证文件(仅需密码,与服务端一致)echo"Rsync@123456">/etc/rsyncd/rsyncd.secrets# 设置权限(必须600)chmod600/etc/rsyncd/rsyncd.secrets创建全量备份脚本/usr/local/backup/scripts/full_backup.sh:
#!/bin/bash# 配置参数BACKUP_USER="backup_user"BACKUP_SERVER="192.168.1.200"# 备份服务器IPBACKUP_MODULE="backup_module"LOCAL_TEMP="/tmp/backup_temp"LOG_FILE="/var/log/backup/full_backup_$(date+%Y%m%d).log"CLIENT_IP=$(hostname-I|awk'{print$1}')# 客户端IP(作为服务端目录名)BACKUP_DATE=$(date+%Y%m%d)FULL_BACKUP_DIR="full_${BACKUP_DATE}"# 定义备份目录(LAMP/LNMP通用,根据实际环境调整)BACKUP_PATHS=("/etc/hosts""/etc/resolv.conf""/etc/sysconfig/network-scripts""/etc/httpd""/etc/nginx""/var/www/html""/usr/share/nginx/html""/var/log/httpd""/var/log/nginx""/etc/my.cnf""/var/lib/mysql""/etc/php.ini""/etc/php.d""/data/www"# 自定义网站目录)# 日志函数log(){echo"[$(date+%Y-%m-%d %H:%M:%S)]$1">>${LOG_FILE}}log"=== 开始全量备份 ==="# 检查本地暂存目录if[!-d${LOCAL_TEMP}];thenmkdir-p${LOCAL_TEMP}log"创建本地暂存目录:${LOCAL_TEMP}"fi# 生成MySQL逻辑备份(避免直接拷贝数据目录锁冲突)MYSQL_BACKUP="${LOCAL_TEMP}/mysql_full_${BACKUP_DATE}.sql.gz"log"开始MySQL逻辑备份..."mysqldump -u root -p"MySQL_ROOT_PWD"--all-databases --single-transaction --quick --lock-tables=false|gzip>${MYSQL_BACKUP}2>>${LOG_FILE}if[$?-eq0];thenlog"MySQL备份成功:${MYSQL_BACKUP}"elselog"MySQL备份失败!"fi# 打包备份文件(按IP+日期命名)BACKUP_PACKAGE="${LOCAL_TEMP}/${CLIENT_IP}_${FULL_BACKUP_DIR}.tar.gz"log"开始打包备份文件..."tar-zcf${BACKUP_PACKAGE}${BACKUP_PATHS[@]}${MYSQL_BACKUP}2>>${LOG_FILE}if[$?-eq0];thenlog"打包成功:${BACKUP_PACKAGE}"elselog"打包失败!"exit1fi# 推送至备份服务器(rsync增量传输,--delete仅删除服务端对应目录旧文件)log"开始推送备份至服务端..."rsync-avz --password-file=/etc/rsyncd/rsyncd.secrets\${BACKUP_PACKAGE}\${BACKUP_USER}@${BACKUP_SERVER}::${BACKUP_MODULE}/${CLIENT_IP}/${FULL_BACKUP_DIR}/2>>${LOG_FILE}if[$?-eq0];thenlog"推送成功!服务端路径:${BACKUP_SERVER}::${BACKUP_MODULE}/${CLIENT_IP}/${FULL_BACKUP_DIR}/"# 删除本地暂存文件(节省空间)rm-rf${LOCAL_TEMP}/* log"删除本地暂存文件"elselog"推送失败!"exit1filog"=== 全量备份完成 ==="创建增量备份脚本/usr/local/backup/scripts/inc_backup.sh(基于全量备份的差异):
#!/bin/bash# 配置参数(与全量脚本一致)BACKUP_USER="backup_user"BACKUP_SERVER="192.168.1.200"BACKUP_MODULE="backup_module"LOCAL_TEMP="/tmp/backup_temp"LOG_FILE="/var/log/backup/inc_backup_$(date+%Y%m%d).log"CLIENT_IP=$(hostname-I|awk'{print$1}')BACKUP_DATE=$(date+%Y%m%d)INC_BACKUP_DIR="inc_${BACKUP_DATE}"# 查找最近的全量备份目录(服务端)LATEST_FULL=$(ssh${BACKUP_USER}@${BACKUP_SERVER}"ls -d /data/rsync_backup/${CLIENT_IP}/full_* | sort -r | head -1"2>>${LOG_FILE})LATEST_FULL_NAME=$(basename${LATEST_FULL})# 日志函数log(){echo"[$(date+%Y-%m-%d %H:%M:%S)]$1">>${LOG_FILE}}log"=== 开始增量备份(基于全量备份:${LATEST_FULL_NAME}) ==="# 检查最近全量备份是否存在if[-z"${LATEST_FULL}"];thenlog"未找到全量备份,终止增量备份!"exit1fi# 本地暂存目录if[!-d${LOCAL_TEMP}];thenmkdir-p${LOCAL_TEMP}fi# MySQL增量备份(仅备份变更数据库,或使用binlog,此处简化为差异备份)MYSQL_BACKUP="${LOCAL_TEMP}/mysql_inc_${BACKUP_DATE}.sql.gz"log"开始MySQL增量备份..."mysqldump -u root -p"MySQL_ROOT_PWD"--databases db1 db2 db3 --single-transaction --quick|gzip>${MYSQL_BACKUP}2>>${LOG_FILE}# 按需指定数据库# 打包增量变更文件(基于全量备份的差异,使用tar --diff)BACKUP_PACKAGE="${LOCAL_TEMP}/${CLIENT_IP}_${INC_BACKUP_DIR}.tar.gz"log"开始打包增量变更文件..."tar-zcf${BACKUP_PACKAGE}--diff -f${LATEST_FULL}/${CLIENT_IP}_${LATEST_FULL_NAME}.tar.gz${BACKUP_PATHS[@]}${MYSQL_BACKUP}2>>${LOG_FILE}# 推送至服务端log"开始推送增量备份至服务端..."rsync-avz --password-file=/etc/rsyncd/rsyncd.secrets\${BACKUP_PACKAGE}\${BACKUP_USER}@${BACKUP_SERVER}::${BACKUP_MODULE}/${CLIENT_IP}/${INC_BACKUP_DIR}/2>>${LOG_FILE}if[$?-eq0];thenlog"推送成功!服务端路径:${BACKUP_SERVER}::${BACKUP_MODULE}/${CLIENT_IP}/${INC_BACKUP_DIR}/"rm-rf${LOCAL_TEMP}/*elselog"推送失败!"exit1filog"=== 增量备份完成 ==="# 添加执行权限chmod+x /usr/local/backup/scripts/*.sh# 替换MySQL密码(批量执行时可使用sed)sed-i's/MySQL_ROOT_PWD/实际MySQL根密码/'/usr/local/backup/scripts/*.sh# 编辑定时任务crontab-e# 添加以下内容(全量:每周日00:00;增量:周一至周六00:00)00* *0/usr/local/backup/scripts/full_backup.sh00* *1-6 /usr/local/backup/scripts/inc_backup.sh# 重启crond服务systemctl restart crond&&systemctlenablecrond使用Ansible批量执行客户端部署步骤(高效替代手动操作):
# 安装Ansibleyuminstall-y ansible# 配置客户端清单(/etc/ansible/hosts)cat>>/etc/ansible/hosts<<EOF [backup_clients] 192.168.1.101 192.168.1.102 ... # 追加所有100台客户端IP EOF# 配置免密登录(控制机免密访问客户端)ssh-keygen -t rsa# 生成密钥ansible backup_clients -m authorized_key -a"user=root key='{{ lookup('file', '/root/.ssh/id_rsa.pub') }}'"-k创建deploy_client.yml:
-hosts:backup_clientsremote_user:roottasks:-name:创建目录file:path={{item}}state=directory mode=0755with_items:-/etc/rsyncd-/usr/local/backup/scripts-/tmp/backup_temp-/var/log/backup-name:创建认证文件copy:content="Rsync@123456" dest=/etc/rsyncd/rsyncd.secrets mode=0600-name:拷贝全量备份脚本copy:src=/usr/local/backup/scripts/full_backup.sh dest=/usr/local/backup/scripts/full_backup.sh mode=0755-name:拷贝增量备份脚本copy:src=/usr/local/backup/scripts/inc_backup.sh dest=/usr/local/backup/scripts/inc_backup.sh mode=0755-name:替换MySQL密码replace:path=/usr/local/backup/scripts/{{item}}regexp='MySQL_ROOT_PWD' replace='实际MySQL根密码'with_items:-full_backup.sh-inc_backup.sh-name:添加crontab任务cron:name:"full backup"minute:"0"hour:"0"weekday:"0"job:"/usr/local/backup/scripts/full_backup.sh"-cron:name:"inc backup"minute:"0"hour:"0"weekday:"1-6"job:"/usr/local/backup/scripts/inc_backup.sh"ansible-playbook deploy_client.yml# 服务端本地测试模块是否可用rsync-avz /etc/hosts backup_user@127.0.0.1::backup_module/test/ --password-file=/etc/rsyncd/rsyncd.secrets# 检查服务端日志tail-f /var/log/rsyncd/rsyncd.log# 客户端执行全量备份脚本(测试)/usr/local/backup/scripts/full_backup.sh# 检查客户端日志tail-f /var/log/backup/full_backup_20251207.log# 服务端检查备份文件是否存在ls/data/rsync_backup/客户端IP/full_20251207/# 客户端修改一个测试文件(如/var/www/html/test.txt)echo"test">/var/www/html/test.txt# 执行增量备份脚本/usr/local/backup/scripts/inc_backup.sh# 服务端检查增量备份文件ls/data/rsync_backup/客户端IP/inc_20251208/# 模拟数据丢失(客户端)rm-rf /var/www/html/test.txt# 从服务端拉取备份文件(客户端)rsync-avz --password-file=/etc/rsyncd/rsyncd.secrets\backup_user@192.168.1.200::backup_module/客户端IP/full_20251207/客户端IP_full_20251207.tar.gz\/tmp/# 解压恢复tar-zxf /tmp/客户端IP_full_20251207.tar.gz -C /# 验证文件是否恢复ls/var/www/html/test.txt使用xargs或Ansible批量触发客户端备份,检查服务端负载和日志:
# Ansible批量执行全量备份测试(非生产时段)ansible backup_clients -m shell -a"/usr/local/backup/scripts/full_backup.sh"# 服务端查看并发连接netstat-tulnp|grep873|wc-l# 查看服务端磁盘IO和CPU负载iostat -x1top# 查看备份请求日志tail-f /var/log/rsyncd/rsyncd.log# 统计每日备份客户端数量grep"$(date+%Y/%m/%d)"/var/log/rsyncd/rsyncd.log|grep"connect from"|awk'{print$5}'|sort-u|wc-l# 检查备份是否成功(客户端)grep"备份完成"/var/log/backup/full_backup_$(date+%Y%m%d).log# 批量检查所有客户端备份状态(Ansible)ansible backup_clients -m shell -a"grep '备份完成' /var/log/backup/full_backup_$(date+%Y%m%d).log"创建定时清理脚本/usr/local/backup/scripts/clean_backup.sh,删除过期备份:
#!/bin/bash# 保留4周全量备份,7天增量备份BACKUP_DIR="/data/rsync_backup"LOG_FILE="/var/log/rsyncd/clean_backup_$(date+%Y%m%d).log"# 清理过期全量备份(>28天)find${BACKUP_DIR}-type d -name"full_*"-mtime +28 -execrm-rf{}\;>>${LOG_FILE}2>&1# 清理过期增量备份(>7天)find${BACKUP_DIR}-type d -name"inc_*"-mtime +7 -execrm-rf{}\;>>${LOG_FILE}2>&1echo"[$(date+%Y-%m-%d %H:%M:%S)] 清理完成">>${LOG_FILE}添加crontab(每周一03:00执行):
03* *1/usr/local/backup/scripts/clean_backup.shrsync --daemon --config=/etc/rsyncd/rsyncd.conf --verbose调试)netstat -tulnp | grep 873,修改配置文件port参数换端口)ping 备份服务器IP+telnet 备份服务器IP 873/data/rsync_backup需root可写(uid/gid配置为root)/var/log/backup/和服务端/var/log/rsyncd/日志tar -tf 备份包.tar.gzmax connections(根据CPU/内存调整),使用SSD磁盘,开启文件系统缓存-z参数)hosts allow)# 客户端推送(ssh模式,无需secrets文件)rsync-avz -essh/tmp/backup_temp/ root@192.168.1.200:/data/rsync_backup/客户端IP/openssl加密备份包(如tar -zcf - 目录 | openssl enc -e -aes256 -k 密码 > 备份包.tar.gz.enc)本方案基于rsync实现100台LAMP/LNMP机器的全网备份,通过“全量+增量”策略平衡备份效率和存储成本,支持批量部署和自动化运维。核心关键点:权限严格控制(600权限)、日志监控、定期恢复测试、过期备份清理,确保备份数据的可用性和安全性。后期可扩展监控告警(如Zabbix监控备份日志关键词)、异地备份(服务端数据同步至异地机房)等功能。