По моему мнению, вам следует ограничить число одновременных подключений непосредственно на стороне сервера, чтобы вам не приходилось делать что-то экстремальное на стороне клиента:
(1) Если вы запускаете rsync в режиме демона, для rsyncd.conf есть опция max connections
.
(2) В Linux вы можете использовать iptables
и его модуль connlimit
, чтобы ограничить количество одновременных подключений к порту с одного или нескольких удаленных хостов. Возможно, вам придется заставить любые клиенты rsync использовать порт, отличный от обычных пользователей ssh, и экземпляр sshd должен их прослушивать.
(3) Замените ваш двоичный файл rsync на сервере сценарием-оберткой, который перехватит параметр --server, который используется внутри rsync, и остановится, пока не освободится слот. Упомянутый скрипт-обертка должен убедиться, что одновременно выполняется не более 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 "$@"
rm -f /var/lock/rsync/$$
else
rsync.bin "$@"
fi
Обратите внимание, что этот сценарий в основном не проверен и в нем отсутствует необходимый код прерывания для удаления файла блокировки, даже если он прерван. Он также не заботится ни о каких устаревших файлах блокировки и т. Д., Ни о создании каталога блокировки.
Если вы настроены на создание собственной реализации семафора, вас может заинтересовать мьютекс , который я использовал выше, чтобы избежать условия гонки между подсчетом количества файлов блокировки и созданием нового файла блокировки, что может позволить двум (или более) экземплярам работать в одном слоте.
Во всех этих случаях вы должны убедиться, что ваши клиенты могут корректно обрабатывать таймауты или отклоненные соединения.
Если вы действительно хотите использовать систему в стиле семафоров, как вы предложили, приведенный выше скрипт может быть несколько модифицирован.