У вас есть три почти идентично настроенных сервера, но вы хотите запустить задания cron
только на одном из них?
Давайте проследим вашу схему именования серверов: web01
], web02
и web03
. Я использую сценарий оболочки, но принцип точно такой же для PHP. (Я могу использовать PHP, но я не считаю себя достаточно сведущим, чтобы писать его публично.)
В верхней части каждого cron
скрипта вы можете сделать что-то вроде этого, что вызовет сценарий для выхода, если имя сервера не web01
.
[ web01 != "$(hostname)" ] && exit
Это не очень устойчиво к сбоям сервера. Если web01
умирает, вы, вероятно, хотите забрать задания cron
на другом сервере. Предполагая, что у вас есть доступ к DNS, вы можете создать CNAME для сервера, отвечающего за запуск cron
. Вот пример записи для bind
; это будет аналогично для других систем:
cron.contoso.com 300 IN CNAME web01.contoso.com
Затем вы можете использовать dig
или nslookup
, чтобы сравнить имя сервера с псевдонимом, и в течение пяти минут (300 секунд) вы могли передать обязанности cron
другому серверу:
myaddr="$(nslookup "$(hostname)" | awk '$1=="Address:"{a=$2} END{print a}')"
cronaddr="$(nslookup "$(hostname)" | awk '$1=="Address:"{a=$2} END{print a}')"
[ "$myaddr" != "$cronaddr" ] && exit
Или:
myaddr="$(dig +short "$(hostname).contoso.com")"
cronaddr="$(dig +short cron.contoso.com)"
[ "$myaddr" != "$cronaddr" ] && exit
Поскольку perl установлен по умолчанию, один из способов — подключиться по ssh к промежуточному хосту и попросить его запустить perl, при этом программа perl представлена здесь -в виде документа:
for host in $(< "$1")
do
ssh "$host" perl << 'EOF'
use IO::Socket;
my $handle = IO::Socket::INET->new(
PeerAddr => '11.22.33.44',
PeerPort => 123,
Proto => 'tcp',
Timeout => 5)
or die "Failed\n";
close $handle;
print "Success\n";
EOF
done
Сценарий пытается подключиться к заданному IP и порту через TCP; если это не удается, вы получите сообщение Failed
, но если это удается, он немедленно закрывает соединение и печатает Success
. При этом используется синтаксис $(<...)
для чтения из имени файла, заданного первым параметром; как и cat
, эта схема предполагает, что ни в одном из имен файлов нет символов из $IFS
в них (пробелов, табуляции или новой строки по умолчанию ). Я также процитировал здесь переменную цикла (, host
), чтобы предотвратить проблемы, если какое-либо содержимое входного файла содержит символы оболочки, такие как *
, ?
или [
.