EQVPS
Kontrol paneliHemen başla

VPS'te cron ve systemd zamanlayıcılarıyla görev zamanlama

Yedekleri, temizlikleri ve betikleri bir takvime göre çalıştırın. Beş dakikada cron ve görevleri sessizce bozan üç tuzak, ardından günlükler, kesintiden sonra telafi ve tam zamanlama için systemd zamanlayıcıları. Aşağıdaki her davranış yeni bir Ubuntu 24.04 sunucuda test edildi.

Bir sunucu siz uyurken iş yaparak kendini öder: yedekler, günlük döndürme, sertifika yenileme, saat dokuzda bir rapor. Linux'ta bunun için iki zamanlayıcı var. Cron kırk yaşında ve tek satır alır. systemd zamanlayıcıları iki küçük dosya ister, karşılığında günlükler, kesintiden sonra telafi ve tam zamanlama verir. Bu rehber ikisini de Ubuntu 24.04'te ele alıyor; her davranış imajımızdan kurulan yeni bir sunucuda kontrol edildi, bir cron görevini tek kelime etmeden başarısız kılan üç hata dahil.

sudo yetkili bir kullanıcıya ihtiyacınız var; Ubuntu kurulum rehberi bir tane oluşturur.

1. Beş dakikada cron

Cron, Ubuntu ve Debian imajlarımızda kurulu ve çalışıyor. Her kullanıcının bir görev tablosu var; kendinizinkini şununla düzenleyin:

crontab -e

Her satır beş zaman alanı ve bir komuttan oluşur:

# min hour day month weekday  command
  30  3    *   *     *        /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  */5 *    *   *     *        /usr/local/bin/check.sh
  0   9    *   *     1-5      /usr/local/bin/report.sh
  @reboot                     /usr/local/bin/start-tunnel.sh

Yani: her gece 03:30'da, her 5 dakikada, hafta içi 09:00'da ve her açılıştan sonra bir kez. */5 her beşinci değer, 1-5 bir aralık, 1,15 bir liste demektir. Sunucunun saat dilimi geçerlidir, imajlarımızda UTC; kendinizinkini ana makine adı ve saat dilimi rehberiyle bir kez ayarlayın, cron onu izler.

Neyin çalıştığını journalctl -u cron ile kontrol edin. Her çalıştırma kullanıcıyı ve komutu günlüğe yazar ve üç tuzak tam orada görünür.

Tuzak 1: çıktı kaybolur. Cron bir görevin çıktısını kullanıcıya e-postayla gönderir. İmajımızda e-posta sunucusu yok, bu yüzden journal'da (CRON) info (No MTA installed, discarding output) yazıyordu ve çıktı kaybolmuştu. İlk örnekteki gibi >> /var/log/backup.log 2>&1 ile kendiniz yönlendirin.

Tuzak 2: yüzde işareti. Bir crontab'da % komutu bitirir ve geri kalanı standart girdiye çevirir. date +%F > /tmp/today zamanladık. Journal cron'un gerçekte ne çalıştırdığını gösteriyor: CMD (date +). Hiçbir dosya yazılmadı ve bize hiçbir hata ulaşmadı. \% yazın ya da komutu bir betiğe koyup betiği zamanlayın.

Tuzak 3: farklı bir ortam. Cron görevleri bash ile değil /bin/sh ile, ev dizininizde ve kısıtlı bir ortamla çalıştırır. Ubuntu 24.04'te PATH ününden iyi çıktı: root ve normal kullanıcı için /usr/local/bin ve /snap/bin dahil tam sistem yolu. Hâlâ eksik olan ev dizininizin altındaki her şey: ~/.local/bin, nvm'in node'u, pipx, cargo. Görevde tam yollar kullanın ya da satırı . $HOME/.profile; ile başlatın.

Bir kullanıcıya değil sisteme ait görevler, ek bir alanla (kullanıcı) dosya olarak /etc/cron.d/ içine gider:

30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ubuntu ayrıca /etc/cron.hourly, cron.daily, cron.weekly ve cron.monthly içindeki her şeyi çalıştırır: her saatin 17. dakikasında, 06:25'te, pazar günleri 06:47'de ve ayın 1'inde 06:52'de. Oraya çalıştırılabilir bir betik koyun, diğerleriyle birlikte çalışır.

2. systemd zamanlayıcıları

Bir zamanlayıcı iki birimden oluşur: işi yapan bir servis ve ne zaman olacağını söyleyen bir zamanlayıcı. Önce betiği, sonra birimleri oluşturun.

sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30

[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target

Servisi değil zamanlayıcıyı etkinleştirin:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

list-timers bir sonraki çalıştırmayı, ne kadar kaldığını ve son çalıştırmayı gösterir. Günlükler ayar gerektirmez: journalctl -u backup.service her başlangıcı, her bitişi ve her çıktı satırını zaman damgasıyla içerir. Görevi hemen çalıştırmak için sudo systemctl start backup.service; takvime güvenmeden önce betiği de böyle test edersiniz.

Takvim sözdizimi. OnCalendar şöyle okunur: haftagünü yıl-ay-gün saat:dakika:saniye, * herhangi bir değer. Kullanmadan önce bir ifadeyi test edin:

systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2

Normalleştirilmiş biçimi ve sonraki tarihleri yazdırır. Kontrol ettiğimiz bazı ifadeler:

OnCalendarAnlamı
*-*-* 03:30Her gün 03:30'da
Mon..Fri *-*-* 09:00Hafta içi 09:00'da
*:0/15Her 15 dakikada
weeklyPazartesi 00:00'da
*-*-01 04:00Her ayın 1'inde 04:00'te
*-*-* 03:00 Europe/KyivKyiv saatiyle 03:00; bizde 01:00 UTC'de çalıştı

Bilmeye değer üç ayar. Persistent=true son çalıştırmayı diske kaydeder ve sunucu kapalıyken ya da zamanlayıcı durdurulmuşken kaçırılan çalıştırmayı telafi eder. İki dakikada bir çalışan zamanlayıcımızı durdurduk, planlı bir çalıştırmanın geçmesini bekledik ve yeniden başlattık: kaçırılan çalıştırma aynı saniye içinde tetiklendi. Persistent olmadan sadece bir sonraki zamanı bekler.

Sürpriz AccuracySec. systemd varsayılan olarak uyanmalardan tasarruf etmek için zamanlayıcıları bir dakikalık pencerede gruplar, bu yüzden ilk çalıştırmamız 07:42:00'da değil 07:42:18'de geldi. AccuracySec=1s ile sonraki çalıştırmalar saniyesi saniyesine 07:46:00 ve 07:48:00'a düştü. Dakika önemliyse ayarlayın; gece yedeği için varsayılanı bırakın.

RandomizedDelaySec=10m bilerek tersini yapar: başlangıcı bir pencereye yayar, böylece on sunucu aynı yedek depolamaya aynı saniyede yüklenmez.

Tek seferlik bir görev için hiç dosya gerekmez:

sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh

Bir kez tetiklenip kaybolan geçici bir zamanlayıcı oluşturur; o zamana kadar systemctl list-timers onu gösterir.

3. Hangisini kullanmalı

Cronsystemd zamanlayıcısı
Kurulum1 satır2 dosya
GünlüklerYalnızca çıktıyı yönlendirirsenizjournalctl -u name.service
Sunucu kapalıyken kaçırılan çalıştırmaKaybolurPersistent=true ile açılışta çalışır
Bir sonraki tetiklemede görev hâlâ çalışıyorİkinci bir kopya başlarİlki bitene kadar atlanır
Kesin zamanDakikasınaAccuracySec=1s ile saniyesine
DurumYoklist-timers, systemctl status

Bir yıl sonra da tanıyacağınız hızlı bir satır için cron kullanın. Başarısızlığını görmeniz gereken, çakışmaması gereken ya da kaçırılmış bir yeniden başlatmadan sonra yine de çalışması gereken her şey için zamanlayıcı kullanın: yedekler, sertifika yenileme, veritabanı temizliği. Bir cron görevi çakışabilecekse sarın: flock -n /tmp/backup.lock /usr/local/bin/backup.sh; ikinci kopya hemen çıkar.

İki zamanlayıcı da bir görevi çalıştırır ve durur. Sürekli çalışması ve çöktükten sonra geri gelmesi gereken bir program için takvim değil servis gerekir; systemd servisi nasıl oluşturulur ve Windows için Windows Server'da bir betiği 7/24 çalıştırma rehberlerine bakın. İyi bir ilk zamanlayıcı restic ile yedekleme rehberimizdeki zamanlayıcıdır; otomatik güvenlik güncellemeleri Ubuntu'nun zaten getirdiği bir zamanlayıcıdır: yeni bir sunucuda çalışan 17 zamanlayıcıdan biri olan apt-daily-upgrade.timer.

SSS

Görevim terminalde çalışıyor ama cron'da çalışmıyor, neden?

Üç yaygın neden. Cron görevi bash ile değil sh ile çalıştırır, bu yüzden yalnızca bash'e özgü sözdizimi başarısız olur. Ev dizininize kurulan nvm, pipx veya cargo gibi araçlar cron'un PATH'inde yoktur, tam yolları kullanın. Ve komut satırındaki her % komutu bitirir: sunucumuzda date +%F, date + oldu. Onu \% olarak yazın ya da komutu bir betiğe taşıyın.

Cron çıktısı nereye gider?

Varsayılan olarak e-postaya. İmajımızda e-posta sunucusu yok, bu yüzden cron günlüğe 'No MTA installed, discarding output' yazar ve çıktı kaybolur. Göreve >> /var/log/myjob.log 2>&1 ekleyin ya da çıktısı kendiliğinden journal'a düşen bir systemd zamanlayıcısına geçin.

systemd zamanlayıcısının cron'a göre avantajı ne?

journalctl'de günlükler, hâlâ çalışan bir görevin ikinci kopyasının başlamaması, Persistent=true ile sunucu kapalıyken kaçırılan çalıştırmaların telafisi ve bir sonraki ile son çalıştırmayı gösteren durum satırı. Cron kısalıkta kazanır: iki dosya yerine tek satır.

Zamanlayıcım 18 saniye geç tetiklendi. Neden?

systemd varsayılan olarak uyanmalardan tasarruf etmek için zamanlayıcıları bir dakikalık pencerede gruplar; bu AccuracySec ayarıdır. İki dakikada bir çalışan zamanlayıcımız 07:42:00 yerine 07:42:18'de tetiklendi. AccuracySec=1s ile tam 07:46:00'da tetiklendi. Dakikanın kesin olması önemliyse bunu ayarlayın.

Cron ve zamanlayıcılar hangi saat dilimini kullanır?

Sunucununkini, imajlarımızda UTC. timedatectl ile bir kez ayarlayın, ana makine adı ve saat dilimi rehberimize bakın; cron da zamanlayıcılar da onu izler. Bir zamanlayıcı kendi dilimini de taşıyabilir: OnCalendar=*-*-* 03:00 Europe/Kyiv testimizde 01:00 UTC'de çalıştı.

Yorumlar

Henüz yorum yok. İlk olun.

Bir yorum bırakın

Yorumlar görünmeden önce denetlenir.