@octopus
2019-11-21T13:59:07.000000Z
字数 2987
阅读 1011
php
服务器:
主:172.30.157.53
从:172.30.157.52
...
(其他从服务器暂无配置,以一个举例)
将主服务器 /data/dyn 目录作为源地址,各个从服务器的 /data/dyn 为目标地址,源地址的文件有添加或更新,实时自动更新到目标地址的相应文件。
rsync 可以实现远程数据同步,借助rcp,ssh等通道来通过推或拉取的方式,实现数据同步。
inotify 监控目录的实时变化,然后通知调用rsync执行rsync命令同步数据
主到从的更新需要ssh连接,配置主从之间可以免密码登录
// 主
cd /root/
ssh-keygen -t rsa
cat /root/.ssh/id_rsa.pub // 复制
// 从
cd /root/.ssh // 没有就创建
vi id_rsa.pub // 粘贴主服务器的公钥
cat id_rsa.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
vi /etc/ssh/sshd_config
> 把#AuthorizedKeysFile .ssh/authorized_keys前面的#去掉
service sshd restart
// 主
ssh root@172.30.157.52 // 测试是否可以免密登录
yum install rsync -y
systemctl enable rsyncd.service
systemctl restart rsyncd.service
yum install rsync -y
systemctl enable rsyncd.service
systemctl restart rsyncd.service
mkdir -p /data/dyn
编译安装(需要安装 gcc 库)
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar xf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify
make && make install
echo "PATH=$PATH:/usr/local/inotify/bin/" >>/etc/profile && source /etc/profile
编写脚本, inotify 发现有文件变动后,执行 rsync 命令
#!/bin/bash
src=/data/dyn/
dst=/data/dyn/
host=172.30.157.52
notifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w %f %e' -e modify,delete,create,attrib,move $src | while read file
do
rsync -az --delete -e 'ssh' $src root@$host:$dst
done
后台运行,并设置开机执行
bash inotify.sh
echo "bash /.../inotify.sh &" >>/etc/rc.local
优化
echo 50000000 >/proc/sys/fs/inotify/max_user_watches
echo 327679 >/proc/sys/fs/inotify/max_queued_events
//主
echo "a">/data/dyn/1.txt
//从
ls /data/dyn/
测试发现,通过 bash xx.sh启动的进程,会起两个子进程,只获取父进程号并杀死,是不能停止监控服务的。所以要杀死脚本启动后生成的所有进程包括子进程,要通过脚本实现。
kill.sh
#! /bin/bash
pname=$1
for pid in $(ps aux|grep $pname |grep -v 'grep' | awk '{print $2}')
do
kill -9 $pid
done
> bash kill.sh xxx.sh 即可杀死 xxx.sh 起的进程以及子进程
有4台+前端服务器,和1台管理服务器,要实现增加前端服务器搭建好lnmp环境后,无需拷贝前端业务代码,管理服务器后台增加一条记录,即可自动同步到指定目录。前端代码也会常常更新,在更新后,自动同步到所有前端服务器中。
POST save.php
params:
{
"src_dir" : "/data/dyn/", // 源地址
"dst_dir" : "/www/html", // 目标服务器的同步目录
"dst_ip" : "172.xx.xx.xx" // 目标服务器地址
}
3.即可生成一个监测并可实时同步的shell脚本接口实现
public function create($src_dir, $dst_ip, $dst_dir){
$shell = <<<EOT
#!/bin/bash
src={$src_dir}
dst={$dst_dir}
inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w %f %e' -e modify,delete,create,attrib,move {$src_dir} | while read file
do
rsync -az --delete -e 'ssh' {$src_dir} root@{$dst_ip}:{$dst_dir}
done
EOT;
$path = Config::get("rsync_shell_path")."rsync_".$this->id.".sh";
file_put_contents($path,$shell);
}
即可生成一个监测并可实时同步的shell脚本
4.执行脚本
exec 命令需要在php.ini配置文件中的禁用函数中去掉,以及配置linux用户权限,这里不做过多记录。
$path = Config::get("rsync_shell_path")."rsync_".$this->id.".sh";
exec("bash {$path}>/dev/null &",$res,$status);
if(!$status){
return true;
}
return false;
// 杀死监控进程
$path = Config::get("kill_rsync_shell_path");
$shell = Config::get("rsync_shell_path")."rsync_".$this->id.".sh";
exec("bash {$path} $shell",$res,$status);
// 删除shell脚本
unlink($shell);