[关闭]
@octopus 2019-11-21T05:59:07.000000Z 字数 2987 阅读 928

rsync + inotify实时同步

php


环境搭建

0. 环境介绍

  1. 服务器:
  2. 主:172.30.157.53
  3. 从:172.30.157.52
  4. ...
  5. (其他从服务器暂无配置,以一个举例)

将主服务器 /data/dyn 目录作为源地址,各个从服务器的 /data/dyn 为目标地址,源地址的文件有添加或更新,实时自动更新到目标地址的相应文件。

rsync 可以实现远程数据同步,借助rcp,ssh等通道来通过推或拉取的方式,实现数据同步。

inotify 监控目录的实时变化,然后通知调用rsync执行rsync命令同步数据

1. ssh免密登录配置

主到从的更新需要ssh连接,配置主从之间可以免密码登录

  1. // 主
  2. cd /root/
  3. ssh-keygen -t rsa
  4. cat /root/.ssh/id_rsa.pub // 复制
  5. // 从
  6. cd /root/.ssh // 没有就创建
  7. vi id_rsa.pub // 粘贴主服务器的公钥
  8. cat id_rsa.pub >> /root/.ssh/authorized_keys
  9. chmod 600 /root/.ssh/authorized_keys
  10. vi /etc/ssh/sshd_config
  11. > 把#AuthorizedKeysFile .ssh/authorized_keys前面的#去掉
  12. service sshd restart
  13. // 主
  14. ssh root@172.30.157.52 // 测试是否可以免密登录

2. 配置主服务器rsync

  1. yum install rsync -y
  2. systemctl enable rsyncd.service
  3. systemctl restart rsyncd.service

3. 配置从服务器rsync

  1. yum install rsync -y
  2. systemctl enable rsyncd.service
  3. systemctl restart rsyncd.service
  4. mkdir -p /data/dyn

4. inotify 配置

编译安装(需要安装 gcc 库)

  1. wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
  2. tar xf inotify-tools-3.14.tar.gz
  3. cd inotify-tools-3.14
  4. ./configure --prefix=/usr/local/inotify
  5. make && make install
  6. echo "PATH=$PATH:/usr/local/inotify/bin/" >>/etc/profile && source /etc/profile

编写脚本, inotify 发现有文件变动后,执行 rsync 命令

  1. #!/bin/bash
  2. src=/data/dyn/
  3. dst=/data/dyn/
  4. host=172.30.157.52
  5. notifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w %f %e' -e modify,delete,create,attrib,move $src | while read file
  6. do
  7. rsync -az --delete -e 'ssh' $src root@$host:$dst
  8. done

后台运行,并设置开机执行

  1. bash inotify.sh
  2. echo "bash /.../inotify.sh &" >>/etc/rc.local

优化

  1. echo 50000000 >/proc/sys/fs/inotify/max_user_watches
  2. echo 327679 >/proc/sys/fs/inotify/max_queued_events

5. 测试

  1. //主
  2. echo "a">/data/dyn/1.txt
  3. //从
  4. ls /data/dyn/

6. 编写杀死进程脚本

测试发现,通过 bash xx.sh启动的进程,会起两个子进程,只获取父进程号并杀死,是不能停止监控服务的。所以要杀死脚本启动后生成的所有进程包括子进程,要通过脚本实现。

kill.sh

  1. #! /bin/bash
  2. pname=$1
  3. for pid in $(ps aux|grep $pname |grep -v 'grep' | awk '{print $2}')
  4. do
  5. kill -9 $pid
  6. done
> bash kill.sh xxx.sh  即可杀死 xxx.sh 起的进程以及子进程

php 接口实现多台web服务器一键配置

场景

有4台+前端服务器,和1台管理服务器,要实现增加前端服务器搭建好lnmp环境后,无需拷贝前端业务代码,管理服务器后台增加一条记录,即可自动同步到指定目录。前端代码也会常常更新,在更新后,自动同步到所有前端服务器中。

新增一台前端服务器

  1. 为该服务器搭建lnmp+网站环境,安装 rsync 服务。
  2. 管理服务器调用接口增加一条记录:
  1. POST save.php
  2. params:
  3. {
  4. "src_dir" : "/data/dyn/", // 源地址
  5. "dst_dir" : "/www/html", // 目标服务器的同步目录
  6. "dst_ip" : "172.xx.xx.xx" // 目标服务器地址
  7. }

3.即可生成一个监测并可实时同步的shell脚本接口实现

  1. public function create($src_dir, $dst_ip, $dst_dir){
  2. $shell = <<<EOT
  3. #!/bin/bash
  4. src={$src_dir}
  5. dst={$dst_dir}
  6. inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w %f %e' -e modify,delete,create,attrib,move {$src_dir} | while read file
  7. do
  8. rsync -az --delete -e 'ssh' {$src_dir} root@{$dst_ip}:{$dst_dir}
  9. done
  10. EOT;
  11. $path = Config::get("rsync_shell_path")."rsync_".$this->id.".sh";
  12. file_put_contents($path,$shell);
  13. }

即可生成一个监测并可实时同步的shell脚本

4.执行脚本

exec 命令需要在php.ini配置文件中的禁用函数中去掉,以及配置linux用户权限,这里不做过多记录。
  1. $path = Config::get("rsync_shell_path")."rsync_".$this->id.".sh";
  2. exec("bash {$path}>/dev/null &",$res,$status);
  3. if(!$status){
  4. return true;
  5. }
  6. return false;

删除一台前端服务器

  1. // 杀死监控进程
  2. $path = Config::get("kill_rsync_shell_path");
  3. $shell = Config::get("rsync_shell_path")."rsync_".$this->id.".sh";
  4. exec("bash {$path} $shell",$res,$status);
  5. // 删除shell脚本
  6. unlink($shell);
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注