inotify php_socker rsync主动同步文件

流程 inotify 监控目录 -> php socket 全双工通信 -> rsync 客户端同步 -> 调用php 写入数据表中

 

开始inotify 监控目录php socket 全双工通信rsync 客户端同步调用php 写入数据表中End

inotify 监听 ->结果写入socket

因此,典型的监控程序需要进行如下操作:

1.使用 inotify_init 打开一个文件描述符 2.添加一个或者多个监控 3.等待事件 4.处理事件,然后返回并等待更多事件 5.当监控不再活动时,或者接到某个信号之后,关闭文件描述符,清空,然后退出。

可监控的事件

  • IN_ATTRIB 被监控项目或者被监控目录中条目的元数据被修改过。例如,时间戳或者许可被修改。

  • IN_CREATE 在被监控目录中创建了子目录或文件。

  • IN_DELETE 被监控目录中有子目录或文件被删除。

  • IN_ALL_EVENTS 来监控每个对象的所有事件

目前项目是监听所有的事件,发送信息让客户端rsync同步

接收停止信号

1.接收信号 一个标志(keep_running)使应用程序了解终止操作

事件处理循环->一直监听->对有效事件进行排队

处理事件 ->返回信息

下载资源 & 使用

缺点 && 解决

  • 缺点

inotify最麻烦的一点就是不能监控子目录,要自己去弄n多个监控。

  • 安装

yum install inotifywait
  • 解决

inotify 是一个应用程序编程接口 普通用户想使用可以借助inotify-tool这个应用程序
​
其有两个命令行工具
​
​
inotifywait:通过调用inotify 的api等待文件事件的发生并显示
​
inotifywatch:通过调用inotify的api 实现对文件相关事件的收集
​
- inotifywait命令
​
inotifywait -mrq --timefmt '%y-%m-%d %H:%M:%S' --format '%T %w%f %e' -e modify,delete,create,attrib /root/test 
​
- 根据inotifywait返回zhi
​

真实环境调用

/root/test/inotify-sample/inotify_test  your_dir or your_file
/root/test/inotify-sample/inotify_test  /root/test/
  • tmux 分屏查看

php socket 通信

关键函数

1.socket_create(参数,stream参数2,$protocol参数3),socket_create创建并返回一个套接字,也称作一个通讯节点。一个典型的网络连接由 2 个套接字构成,一个运行在客户端,另一个运行在服务器端。

参数1是:网络协议,
    网络协议有哪些?它的选择项就下面这三个:
    AF_INET:     IPv4 网络协议。TCP 和 UDP 都可使用此协议。一般都用这个,你懂的。
    AF_INET6:   IPv6 网络协议。TCP 和 UDP 都可使用此协议。
    AF_UNIX:      本地通讯协议。具有高性能和低成本的 IPC(进程间通讯)。
​
    参数2:套接字流,选项有:
    SOCK_STREAM  SOCK_DGRAM  SOCK_SEQPACKET  SOCK_RAW  SOCK_RDM。
    这里只对前两个进行解释:
    SOCK_STREAM  TCP 协议套接字。
    SOCK_DGRAM   UDP协议套接字。
    欲了解更多请链接这里:http://php.net/manual/zh/function.socket-create.php
​
    参数3:protocol协议,选项有:
    SOL_TCP:  TCP 协议。
    SOL_UDP:  UDP协议。
    从这里可以看出,其实socket_create函数的第二个参数和第三个参数是相关联的。
    比如,假如你第一个参数应用IPv4协议:AF_INET,然后,第二个参数应用的是TCP套接字:SOCK_STREAM,
    那么第三个参数必须要用SOL_TCP,这个应该不难理解。
    TCP 协议套接字嘛,当然只能用TCP协议了,是不是?如果你应用UDP套接字,那么第三个参数该怎么选择我就不说了,呵呵,你懂的。

2.关键函数4:

    socket_listen($socket参数1,$backlog 参数2)
​
    作用:监听一个套接字,返回值为true或者false
​
    参数1:socket_create的函数返回值
​
    参数2:最大监听套接字个数

3.调试用的函数

socket_last_error($socket),参数为socket_create的返回值,作用是获取套接字的最后一条错误码号,返回值套接字code
​
socket_strerror($code),参数为socket_last_error函数的返回值,获取code的字符串信息,返回值也就是套接字的错误信息
​
这两个函数在socket编程中还是很重要的,在写socket编程的时候,我觉得你还是得利用起来,特别是新手

调用 php /php/test/socker/server.php | php /php/test/socker/client.php

inotify 调用 php socket

1.grep -nri handle_event ./ 2.vim inotify_utils.c

调用代码

#include <stdlib.h>
main()
{
system("ls -al /etc/passwd /etc/shadow");
}

rsync 同步

安装

yum install -y rsync xinetd

启动

/etc/init.d/xinetd restart

配置 vim /etc/rsyncd.conf

#Global Settings 全局配置
uid = nobody                         #运行rsync的用户
gid = nobody                         #运行rsync的用户组
use chroot = no                      #是否让进程离开工作目录
max connections = 5                  #最大并发连接数,0为不限制
timeout = 600                        #超时时间
pid file = /var/run/rsyncd.pid       #指定rsync的pid存放路径
lockfile = /var/run/rsyncd.lock      #指定rsync的锁文件存放路径
log file = /var/log/rsyncd.log       #指定rsync的日志存放路径
#模块配置
[web1]
path = /var/www                      #认证的模块名,在client端需要指定
ignore errors = yes                  #忽略一些无关的I/O错误
read only = no                       #客户端是否能拉(PULL)
write only = no                      #客户端是否能推(PUSH)
hosts allow = 172.18.150.150         #白名单,可以访问此模块的主机
hosts deny = *                       #黑名单,*表示任何主机
list = yes                           #客户端请求是否可以列出模块列表
uid = root                           #以root的身份去获取文件
gid = root
auth users = web                     #认证此模块的用户名
secrets file = /etc/web.passwd       #指定存放“用户名:密码”格式的文件

服务端

  • 首先要选择服务器启动方式

    • 对于负荷较重的 rsync 服务器应该使用独立运行方式

    • 对于负荷较轻的 rsync 服务器可以使用 xinetd 运行方式

  • 创建配置文件 rsyncd.conf

  • 对于非匿名访问的 rsync 服务器还要创建认证口令文件

启动 1.以 xinetd 运行 rsync 服务 2.独立运行 rsync 服务# /usr/bin/rsync --daemon

编辑配置文件 vi /etc/rsyncd/rsyncd.conf

为了密码的安全性,我们必须把权限设为600 建立/etc/rsyncd/rsyncd.secrets文件

#cat /etc/rsyncd/rsyncd.secrets
    rsync:123456

启动rsync

# /etc/init.d/xinetd restart

容易出现的错误 1.编辑 rsyncd.conf文件 检查确定 hosts allow = 116.xxx.xxx.xxx/255.255.255.255

客户端

通过rsync客户端来同步数据

# rsync -avzP  --delete david@172.16.2.135::davidhome  /tmp/david/

真实服务器操作

密码免输入 和 删除文件同步

/tmp/rsync.password 文件权限 chmod 600

rsync -avzP  --delete --password-file=/tmp/rsync.password  rsync@192.168.31.129::davidhome  /tmp/david/
​
rsync -avzP  --delete --password-file=/tmp/rsync.password  rsync@127.0.0.1::davidhome  /tmp/david/

shell 脚本调用

说明 通过在A上监听文件夹是否改变,发送socket,让客服端 rysnc 同步文件

#!/bin/bash
#des : sync
#os ; linux
​
SRCDIR='/home/david/'
​
#####################SCRIPTS###############
inotifywait -mrq --timefmt '%y-%m-%d %H:%M:%S' --format '%T %w%f %e' -e modify,delete,create,attrib  $SRCDIR | while read FILESTAT 
do 
   #记录日志
   echo "$FILESTAT" >> inotify.log
   #发送socket
   /app/local/php/bin/php /root/test/socket/client.php  dd   1 >> socket.log 2>&1 
   #发送邮箱
   echo "$FILESTAT" | mutt -s "inotify-rsync" 123456@qq.com
done

php

socket/client.php

<?php
/**
 * socket 客户端。
 * @author winerQin
 * @date 2017-05-02
 */
$ip  = '127.0.0.1';
$port = 8394;
// 创建 socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// 连接 socket
socket_connect($socket, $ip, $port);
$in  = "hello server! {$argv[1]} ";
//$in  = "hello server!"."\n";
$out = '';
// 写数据到 socket 缓存
socket_write($socket, $in, strlen($in));
// 读取指定长度的数据
while($out = socket_read($socket, 2048)) {
    //echo "Server response success!\n"; // 接收服务器回传信息成功
    //echo "Receive message:{$out}";      // 服务器返回的信息
    break;
}
socket_close($socket);

socket/server.php

<?php
/**
 * socket 服务端。
 * @author winerQin
 * @date 2017-05-02
 */
$ip   = '127.0.0.1';
$port = 8394;
// 创建 socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// 把 socket 绑定在一个IP地址和端口上
socket_bind($socket, $ip, $port);
// 监听由指定 socket 的所有连接
socket_listen($socket, 4);
do {
    // 接收一个 Socket 连接
    if (($msgsock = socket_accept($socket)) < 0) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
        break;
    } else {
        //socket服务端调用rsync pull,同步rsync服务端的数据
        //$cmd = "rsync -avzP  --delete --password-file=/tmp/rsync.password  rsync@127.0.0.1::davidhome  /tmp/david/";
        // 发送到客户端
        $datetime = date('Y-m-d H:i:s', time());
        echo "Server datetime:{$datetime}\n";
        $msg = "Hello -client!\n";
        socket_write($msgsock, $msg, strlen($msg));
        // 获得客户端的输入
        $buf = socket_read($msgsock, 2048);
        echo "Receive client message: {$buf}\n\n";
        //   /tmp/david/ 是同步到的地方
        $output = shell_exec("rsync -avzP  --delete --password-file=/etc/rsyncd/rsync.passwd rsync@127.0.0.1::davidhome  /tmp/david/ > /dev/null 2>&1");
        echo $output."\n";
    }
    // 关闭socket
    socket_close($msgsock);
} while(true);
socket_close($socket);

注意密码文件权限 -rw-------. 1 root root 7 Dec 13 14:01 rsync.passwd 注意 /tmp/david/ 为需要同步的目录

rsyn 服务端同步的源文件目录

/etc/rsyncd.conf

[davidhome]                               
path = /home/david/                       
list=yes                                   
ignore errors                              
auth users = rsync                         
comment = David home                  
exclude = important/ 

步骤

1.开启 shell 脚本 2.开启socket 服务端

总结

1.在海外远程机器中 做socker服务端,监听
2.文件 /opt/scripts/filesync/socket/server.php
3.常驻进程

37开 (微信公众号)- 原创文章(已经在多平台发表),转载请标明出处

原文地址-99get81.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值