Eğitimler

WordPress wp-cron; neden çalışmıyor ve gerçek cron ile nasıl değiştirilir

Yazı yayınlama zamanlaması gecikiyorsa veya eklentiler çalışmıyorsa, sorun wp-cron'dadır. Teşhis ve sunucunun gerçek cron'u ile değiştirme rehberi.

Eğitimler

Bir yazıyı sabah 9 için zamanladınız ve saat 11 oldu, hâlâ yayınlanmadı. Ya da her saat rapor göndermesi gereken bir eklenti, dün bir kez bile göndermedi. Sunucu logunu açıp wp-cron.php ararsanız, ya hiç kayıt olmadığını ya da bir saniye içinde arka arkaya yüzlerce kayıt girildiğini görürsünüz. Bu iki durum, aynı sorunun iki yüzüdür: WordPress wp-cron gerçek bir zamanlayıcı değildir.

WordPress'in sunucuda hiçbir cron daemon'u yoktur. "wp-cron" olarak adlandırılan şey, her sayfa görüntülemesinde çağrılan bir PHP dosyasıdır. Yani görev zamanlamanız sistem saatine değil, site trafiğine bağlıdır. Bu tek cümle, peşinde olduğunuz sorunların çoğunu açıklar.

wp-cron neden düşük trafikli sitede çalışmaz

wp-includes/default-filters.php dosyasında, her sayfa yüklenmesinde wp_cron() fonksiyonunu çağıran bir hook vardır. Bu fonksiyon, süresi gelmiş bir görev olup olmadığını kontrol eder. Siteniz günde 50 görüntüleme alıyorsa ve hepsi de düzensiz aralıklarla geliyorsa, pratikte kimse o hook'u doğru anda çalıştırmaz. Sonuç, zamanlanmış yazının birkaç saat gecikmeyle yayınlanması, işlemsel e-postaların geç gelmesi ve otomatik yedekleme eklentilerinin bazı günler hiç çalışmamasıdır.

Teşhis işareti de basittir. _get_cron_array() okuyan ve her görevin next_run zamanını yazdıran küçük bir betik yazın. Eğer o zaman sürekli geçmişte kalıyor ve ilerlemiyorsa, hiçbir görüntüleme onu tetiklememiş demektir. Bunu dokümantasyon ve bilgi tabanında da başka bir şekilde açıkladık, ama testin kendisi üç satır koddur.

Yüksek trafikli sitede neden yavaşlatır

Şimdi yüksek trafikli siteyi düşünün. Burada sorun tam tersidir. Her sayfa görüntülemesi, wp-cron.php'ye ayrı bir HTTP isteği gönderir. define('DISABLE_WP_CRON', false) ile etkin olan bu dosya, her çalıştırmada tüm cron dizisini okur, kilit alır ve süresi gelmiş bir görev varsa çalıştırır. Dakikada 200 eşzamanlı görüntüleme alan bir sitede bu, her biri bir PHP-FPM bağlantısı ve wp_options tablosuna bir sorgu tüketen 200 ek istek anlamına gelir.

Rakama bakın. Çalıştıracak hiçbir görevi olmayan bir wp-cron.php isteği genellikle 80 ila 150 milisaniye sürer ve yaklaşık 15 ila 30 megabayt PHP belleği alır. Siteniz yoğun trafikte saniyede 50 istek alıyorsa, bu, kullanıcı için hiçbir iş yapmayan saniyede 50 ek bağlantı demektir. pm.max_children = 20 olan bir sunucuda, PHP-FPM havuzu birkaç saniye içinde dolar ve gerçek kullanıcılar kuyruğa girer. TTFB 300 milisaniyeden iki saniyenin üzerine çıkar.

Burada hata yapılıyor: çoğu kişi sorunun WordPress'in kendisinde olduğunu düşünüp önbellek eklentisine yönelir. Önbellek sayfayı hızlandırır, ancak wp-cron.php istekleri önbellek yolundan geçmez çünkü bunlar bağımsız PHP dosyalarıdır. Site ana sayfada hızlı görünür, ama sunucu yükü yüksek kalır ve birkaç saatte bir 502 verir. access.log içinde ararsanız, desen şudur: arka arkaya yüzlerce POST /wp-cron.php?doing_wp_cron satırı, hepsi 200 kodu ve yüksek yanıt süresiyle.

Sunucunun gerçek cron'u ile değiştirme

Standart çözüm, dahili wp-cron'u kapatmak ve işletim sistemi düzeyinde gerçek bir cron job oluşturmaktır. Önce wp-config.php içine şu satırı ekleyin:

define('DISABLE_WP_CRON', true);

Sonra web sunucusu kullanıcısında crontab -e ile şu satırı ekleyin:

*/5 * * * * cd /var/www/html && /usr/bin/php wp-cron.php >/dev/null 2>&1

Bu satırda genellikle yanlış yapılan iki nokta var. Birincisi, cd ile WordPress dizinine gitmek gerekir çünkü wp-cron.php yolları göreli okur. İkincisi, sitenin çalıştığı aynı sürümdeki PHP binary'sini kullanın; sunucuda birden fazla PHP sürümü varsa ve site PHP 8.2'de çalışırken siz /usr/bin/php çağırırsanız, Fatal error: Uncaught Error hatası alabilirsiniz ya da daha kötüsü, sessizce çalışmaz. Doğru yolu aynı ortamda which php ile bulun.

Beş dakikalık aralık çoğu site için doğrudur. Daha hassas çalışması gereken bir göreviniz varsa, aralığı bir dakikaya düşürün, ancak her çalıştırmanın tam bir PHP süreci başlattığını unutmayın. Zayıf bir sunucuda, günde 1440 çalıştırmanın kendi maliyeti vardır.

Daha iyi alternatif: WP-CLI

WP-CLI kuruluysa, cron satırını şöyle yazın:

*/5 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now --quiet

Bu sürüm daha iyidir çünkü yalnızca süresi gelmiş görevleri çalıştırır, temiz çıktı verir ve --quiet ile logu kirletmez. Pratik farkını, belirli bir görevi elle test etmek istediğinizde görürsünüz: wp cron event list ve wp cron event run woocommerce_scheduled_sales tam olarak hata ayıklama için ihtiyacınız olan şeydir.

İki yöntemin karşılaştırması

ÖlçütVarsayılan wp-cronGerçek sunucu cron'u
Trafiğe bağımlılıkVarYok
Zamanlama hassasiyetiDüzensiz, birkaç saate kadar gecikmeCron aralığı kadar hassas
Yüksek trafikte maliyetYüksek, her görüntülemede ek istekSabit, görüntülemeden bağımsız
SSH erişimi gereksinimiYokVar
Uygun olduğu durumYeni site, düşük trafik, SSH yokHer ciddi site

SSH erişimi olmayan paylaşımlı hostingdeyseniz, hosting paneli Cron Job tanımlama imkânı vermediği sürece varsayılan wp-cron'dan başka seçeneğiniz yoktur. O durumda aralığı 15 dakikaya ayarlayın ve DISABLE_WP_CRON'u true yapın. Sunucunun tam kontrolüne sahipseniz, dahili wp-cron'u tutmak için hiçbir neden yoktur. Kendi kurduğum her sunucuda bunu ilk günden kapatırım. SSH erişimli Linux hostingde bu iş iki dakika sürer.

Geçişten sonra bozulan şeyler

wp-cron'u kapattıktan sonra iki şeyi kontrol edin. Birincisi, bazı eklentiler doğrudan wp-cron.php'yi çağırır ya da wp_loaded hook'una güvenir; değişiklikten sonra bir eklentinin artık çalışmadığını görürseniz, PHP logunda Undefined index arayın. İkincisi, site load balancer arkasında birden fazla sunucuda çalışıyorsa, cron'u yalnızca bir sunucuda tanımlayın. Aksi halde her sunucu görevleri ayrı ayrı çalıştırır ve örneğin bir e-postayı dört kez gönderirsiniz.

Bir not daha: geçişten sonra wp_options tablosunu cron ve doing_cron kayıtları açısından inceleyin. Bir çalıştırma iş ortasında çökmüşse, doing_cron kilidi kalır ve başka hiçbir görev çalışmaz. O kaydı elle silmek sorunu çözer. Bu durumu, üç hafta boyunca hiç yedek almayan ve kimsenin fark etmediği bir sitede gördüm.

Bu değişikliklerden sonra sunucuda gerçekte ne olduğunu anlamak için, site uptime izlemeyi de kurmaya değer; PHP-FPM havuzunun dolmasından kaynaklanan kısa düşüşleri yalnızca sürekli izleme ile görürsünüz, siteyi elle açarak değil.

Sık sorulan sorular

wp-cron'u kapatmak siteye zarar verir mi?

Hayır, kapatmadan önce gerçek cron'u ayarlamış olmanız koşuluyla. DISABLE_WP_CRON'u true yapıp hiçbir cron job oluşturmazsanız, hiçbir görev çalışmaz ve zamanlanmış yazılar asla yayınlanmaz. Doğru sıra şudur: önce cron satırını ekleyin, çalıştığını test edin, sonra dahili wp-cron'u kapatın.

Gerçek cron job'un doğru çalıştığını nasıl anlarım?

Loga bir kayıt yazan bir test görevi oluşturun ya da wp cron event list kullanın ve her çalıştırmadan sonra next_run zamanının ilerleyip ilerlemediğine bakın. Zaman sabit kalmışsa, cron çalışmıyor demektir. Sistem cron logunu da grep CRON /var/log/syslog ile kontrol edin.

Cron job için uygun aralık kaç dakikadır?

Çoğu site için beş dakika yeterlidir. Bekleyen siparişleri sona erdiren bir mağaza eklentiniz veya kuyruklanmış e-posta gönderme sisteminiz varsa, bir dakika daha mantıklıdır. Standart cron'da bir dakikadan kısa mümkün değildir ve WordPress'in desteklemediği saniye düzeyinde cron'lar gerektirir.

SSH'siz paylaşımlı hostingde ne yapmalıyım?

Hosting panelinde Cron Jobs bölümünü arayın; çoğu panel bu imkânı verir. Yoksa, varsayılan wp-cron'u koruyun ama yedekleme gibi ağır görevlerin çalıştırma aralığını kısaltmayın. Düşük trafikli siteler bu durumda zamanlamalarının hassas olmayacağını bilmeli ve ona güvenmemelidir.

ServerNet Destek

ServerNet mühendislik ve yayın ekibi — altyapı, ağ ve web barındırma uzmanları.

WordPress Hosting
Paylaş:

Yorumlar 0

Henüz yorum yok — ilk siz olun!

Yorum bırakın

İlgili hizmet

WordPress Hosting

LiteSpeed Enterprise ve NVMe üzerinde WordPress'e özel altyapı — otomatik kurulum, güvenli güncelleme, staging ve sizi Google'da üstte tutan önbellek.