2010-11-30 51 views
3

我有一台备份服务器,它每小时接收很多rsync连接。由于打开太多的实例可能会导致崩溃,因此我想使用Semaphore来限制并发实例的数量。我想到的是这样的:Ubuntu中的信号灯和锁

ssh [email protected]_server "get_semaphore"  #Will hold until semaphore released 
rsync -avzrL --super --delete local_directory [email protected]_server:`localhost` 

任何想法?

回答

12

在我看来,你应该看在服务器端直接限制并发连接数,这样你就不必做任何极端的客户端:

(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感兴趣,以避免计算锁文件数量和创建新的锁文件之间的竞争状态,这可能允许两个(或更多)实例在单个插槽中运行。

在所有这些情况下,您应确保您的客户端可以正常处理连接超时或拒绝连接。

如果您确实想按照您的建议使用信号样式系统,则上面的脚本可能会进行一些修改。