在我看来,你应该看在服务器端直接限制并发连接数,这样你就不必做任何极端的客户端:
(1)如果您在守护进程模式下运行rsync,rsyncd.conf有一个max connections
选项。 (2)在Linux上,可以使用iptables
及其connlimit
模块至limit从一个或多个远程主机到端口的并发连接数。您可能必须强制任何rsync客户端使用与普通ssh用户不同的端口,并让sshd实例也可以监听。 (3)用包装脚本替换服务器上的rsync二进制文件,该脚本将捕获rsync内部使用的--server参数,并停止运行,直到有可用的插槽为止。所述包装脚本应该确保同时执行不超过N个本身的实例。例如。
#!/bin/bash
N=5
mutex_hold() {
while ! mkdir /var/lock/rsync/mutex 2>/dev/null; do
sleep 1
done
}
mutex_release() {
rmdir /var/lock/rsync/mutex
}
if [[ "$1" = "--server" ]]; then
shopt -s nullglob
while mutex_hold && A=(/var/lock/rsync/[0-9]*) && [[ "${#A[@]}" -ge "$N" ]] && mutex_release; do
sleep 1
done
touch /var/lock/rsync/$$
mutex_release
rsync.bin "[email protected]"
rm -f /var/lock/rsync/$$
else
rsync.bin "[email protected]"
fi
请注意,这个脚本主要是未经测试并缺乏必要的陷阱代码,如果中断,甚至删除锁文件。它也不会处理任何陈旧的锁定文件等或创建锁定目录。
如果您对制定自己的信号量有所建议,您可能会对我上面使用的mutex感兴趣,以避免计算锁文件数量和创建新的锁文件之间的竞争状态,这可能允许两个(或更多)实例在单个插槽中运行。
在所有这些情况下,您应确保您的客户端可以正常处理连接超时或拒绝连接。
如果您确实想按照您的建议使用信号样式系统,则上面的脚本可能会进行一些修改。