解决通过目录挂载的项目访问慢的问题
方案一:在生成容器时假如 cached 参数
例如:docker run -d -p 9000:9000 –name php-dubbo-cache -v D:/workspace/www:/data/www:cached php-fpm
经尝试,此方案并没有解决我当前的问题,访问仍然很慢,环境:win10+docker(nginx+php-fpm)
方案二:使用 inotifyWait + rsync 实现监控目录内变化并同步到其他目录
2.1 rsync
rsync可实现本地目录同步、本地+远程服务器内容同步等功能,本次我们使用 Local => Local 模式的目录同步
// 2.1.1 安装 rsync
yum -y install rsync
// 2.1.2 rsync 常用参数
-a,--archive(存档) 归模式,表示以递归的方式传输文件,并且保持文件属性,等同于加了参数-rlptgoD
-r,–recursive 对子目录以递归模式处理
-l,--links 表示拷贝链接文件
-p , --perms 表示保持文件原有权限
-t , --times 表示保持文件原有时间
-g , --group 表示保持文件原有属用户组
-o , --owner 表示保持文件原有属主
-D , --devices 表示块设备文件信息
-z , --compress 表示压缩传输
-H 表示硬连接文件
-A 保留ACL属性信息
-P 显示传输进度
示例
本次使用 rsync 简单的本地目录同步
rsync -a /var/www/test_dir_1 /var/www/test_dir_2
此次命令会带来如下结果
将 /var/www/test_dir_1/ 目录下的所有文件及目录完整同步到 /var/www/test_dir_2/ 目录下
2.2 inotify
inotify-tools 提供两种工具,一个是 inotifywatch,用来统计文件系统访问的次数;另一个就是我们要用的 inotifywait,用来监控文件或目录的变化
// 2.2.1 检查是否支持 inotify
ll /proc/sys/fs/inofity/
[root@6dcde9161cb0 test_dir_1]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Apr 9 01:58 max_queued_events
-rw-r--r-- 1 root root 0 Apr 9 01:58 max_user_instances
-rw-r--r-- 1 root root 0 Apr 9 01:58 max_user_watches
说明:
max_queued_evnets,表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,
超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
max_user_instance,表示示每一个real user ID可创建的inotify instatnces的数量上限。
max_user_watches,表示每个inotify instatnces可监控的最大目录数量。
如果监控的文件数目巨大,需要根据情况,适当增加此值的大小,例如:
echo 30000000 > /proc/sys/fs/inotify/max_user_watches
有如上输出则表示支持,否则需要重新编译 linux 内核,方法请自行百度~
// 2.2.2 检查是否已经安装
rpm -qa inotify-tools
// 2.2.3 安装
// 直接安装 inotify-tools 可能会提示找不到源,需要先安装 epel 源,再安装 inotify-tools
yum -y install epel-release
yum -y install inotify-tools
// 2.2.4 常用参数
–fromfile
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-m, –monitor
接收到一个事情而不退出,无限期地执行。默认的行为是接收到一个事情后立即退出。
-d, –daemon
跟–monitor一样,除了是在后台运行,需要指定–outfile把事情输出到一个文件。也意味着使用了–syslog。
-o, –outfile
输出事情到一个文件而不是标准输出。
-s, –syslog
输出错误信息到系统日志
-r, –recursive
监视一个目录下的所有子目录。
-q, –quiet
指定一次,不会输出详细信息,指定二次,除了致命错误,不会输出任何信息。
–exclude
正则匹配需要排除的文件,大小写敏感。
–excludei
正则匹配需要排除的文件,忽略大小写。
-t , –timeout
设置超时时间,如果为0,则无限期地执行下去。
-e , –event
指定监视的事件。
-c, –csv
输出csv格式。
–timefmt
指定时间格式,用于–format选项中的%T格式。
–format
指定输出格
示例
inotifywait -mrq /var/www/test_dir_1
// 开启监听后,目录内的变化会被 inotifywait 捕获并打印
[root@6dcde9161cb0 www]# inotifywait -mrq ./test_dir_1/
./test_dir_1/ OPEN,ISDIR
./test_dir_1/ ACCESS,ISDIR
./test_dir_1/ CLOSE_NOWRITE,CLOSE,ISDIR
./test_dir_1/ OPEN,ISDIR
./test_dir_1/ ACCESS,ISDIR
./test_dir_1/ CLOSE_NOWRITE,CLOSE,ISDIR
./test_dir_1/ OPEN test2.php
./test_dir_1/ MODIFY test2.php
./test_dir_1/ CLOSE_WRITE,CLOSE test2.php
2.3 实施
// 我们使用 inotifywait + rsync 来实现docker容器挂载的项目目录同步到容器内非挂载目录,
// 以达到容器内的 nginx 服务使用容器本地目录,且 windows 本地修改实时更新容器内本地项目目录的目的
// 最终解决容器内挂载项目目录访问慢的问题
// 2.3.1 先
touch inotifywait_rsync.sh
vim inotifywait_rsync.sh
// 写入如下脚本
#!/bin/bash
inotifywait -mrq -e create,delete,modify,attrib,move,close_write "/sourcecode" | while read event ; do
rsync -a /sourcecode /var/www/
done
注意: inotifywait 监控变化事件后的同步,会在目标目录下创建一个来源目录,跟单独用时不太一样,所以这里我们用 /var/www/ 的写法,最终同步后回事 /var/www/sourcedoe/ 的形式
提醒: 为了不改 nginx 配置文件,可以设置挂载目录为其他目录,如/home/www,然后将 /sourcecode 作为本地目录使用
体会:
inotifywait监听+rsync同步,
rsync功能确实比较强大,可以只同步修改的内容,类型也比较丰富,增删改、改文件/目录权限等都能同步,
但在使用的时候我觉得也有个弊端,就是其实每次修改内容后,rsync是便利了一遍目录下所有内容,然后
把修改时间不一致的做同步,也可能是我的知识储备不足没找到正确的使用方式。
这就导致如果项目很大或文件/目录数很多的话同步会比较慢,
例如,我最初是把整个 www 目录做了监听同步,里边包含了多个项目,同步一次是会把 14万个文件+目录
便利一次,整个同步过程大概3分钟左右,
对策就是进行细粒度的监听,比如一个项目组有10个服务,就建对10个服务的监听,比如我们有个服务是
7700多个文件+1700多个目录,修改一个字符观察同步的时间,大概2-3秒,这就可以接受,因为切换工具
去测试的的时间就可以和这个延迟相抵消了
参考文档-安装:https://blog.csdn.net/leadseczgw01/article/details/106542704
参考文档-rsync参数:https://blog.csdn.net/bodybo/article/details/82746601
参考文档-组合:https://blog.csdn.net/helloxiaozhe/article/details/97038443
参考文档-rsync配置详解:https://blog.csdn.net/weixin_33785972/article/details/92526442
参考文档-rsync --partial 选项说明:https://blog.csdn.net/weixin_34342992/article/details/86060476