Sunucuyu yeniden başlattınız ve şimdi site açılmıyor. systemctl status nginx active (running) diyor, ama tarayıcı 502 Bad Gateway veriyor. Sorun genellikle yeniden başlatmanın kendisi değildir; servislerin durdurulup yeniden başlatılma sırasıdır. Bu makale, reboot ile servisin gerçekten sağlıklı döndüğü an arasında olan şey hakkındadır.
Sunucuyu yeniden başlatmadan önce servis listesine değil, bağımlılıklara bakın
Çoğu yönetici systemctl list-units --type=service ile başlar ve içinde hiçbir sıra olmayan bir liste görür. Önemli olan bağımlılık grafiğidir. Şu komutu çalıştırın:
systemctl list-dependencies --reverse --before nginx.service
Çıktı, nginx'ten önce hangi servislerin başlatılması gerektiğini gösterir. PHP-FPM veya veritabanı servisi bu listede yoksa, her yeniden başlatmadan sonra bir hata aralığı yaşarsınız. Gerçek önyükleme sırasını görmek için systemd-analyze critical-chain nginx.service her tahminden daha kesindir ve her düğümün süresini milisaniye biriminde gösterir.
Az görülen bir nokta: After= yalnızca sırayı belirler, bağımlılığı değil. Veritabanı servisi başlamazsa, nginx After=mysql.service ile yine de çalışır ve aynı 502 geri döner. Gerçek zorlama için Requires= veya Wants= de eklenmelidir. Bu bölümlerin ayrıntıları systemd'de unit dosyası: bölümler, yeniden başlatma ve bağımlılık içinde verilmiştir.
Sunucuyu yeniden başlatmadan önce servisleri durdurmanın doğru sırası
Temiz bir reboot, servisleri bağımlılığın ters sırasına göre durdurur. Kendiniz manuel olarak durduruyorsanız, bu sıraya uyun:
- Giriş katmanı: nginx veya Apache
- Uygulama katmanı: PHP-FPM, Node, Gunicorn
- Kuyruk ve önbellek: Redis, RabbitMQ
- Veritabanı: MySQL veya PostgreSQL
Neden bu sıra? Çünkü veritabanı önce durursa, hâlâ istek alan uygulamalar bağlantı hatası üretir ve loglarda sonradan gerçek nedeni teşhis etmeyi zorlaştıran bir iz bırakır. Redis uygulamadan önce durursa, kullanıcıların session'ı silinir ve herkes hesaptan çıkar.
Veritabanı için systemctl stop mysql yeterli değildir. Önce şunu çalıştırın:
mysqladmin -u root -p shutdown
Bu komut son flush'ı yapar ve InnoDB'yi temiz kapatır. Sürecin kill edilmesiyle farkı, bir sonraki önyüklemede kendini gösterir: daha uzun crash recovery ve en kötü durumda tutarsız tablolar.
Burada hata yapıyorlar
Çok gördüğüm yaygın hata: Sunucu yöneticisi systemctl restart nginx ile başlar, sonra restart php-fpm yapar ve son olarak veritabanına dokunmaz. Sonuç, nginx'in birkaç saniye backend'siz aktif kalması ve o aralıkta kullanıcıların 502 hatası almasıdır. Belirtisi de tam olarak budur: access.log içinde iki üç saniyelik bir aralıkta 502 kodlu birkaç istek ve sonra her şey normal. Yalnızca hata loguna bakan kişi, uygulama bug'ı arar.
İkinci hata daha pahalıdır: backup cron'un çalıştığı saatte sunucuyu yeniden başlatmak. Veritabanı dump'ı yarıda kalırsa, backup dosyası sağlıklı görünür ama geri yüklenemez. Her yeniden başlatmadan önce crontab -l ve systemctl list-timers kontrol edin.
Açılıştan sonra: Gerçekten kazayı önleyen kontrol listesi
uptime'ın küçük bir sayı göstermesi, sunucunun önyüklendiği anlamına gelir. Servisler sağlıklı mı? Hayır. Şu beş maddeyi sırayla uygulayın:
systemctl --failed— burada görünen her unit, önyüklemede başarısız olmuştur. Boş çıktı, hiçbir servisin failed durumunda olmadığı anlamına gelir.ss -tlnp— beklenen portların gerçekten listen yapıp yapmadığına bakın. Yaygın portların listesi ve açık olmaması gerekenler Yaygın servis portları referansı içinde verilmiştir.df -hvefree -m— bir bölümün mount'u önyüklemeden sonra başarısız olduysa, servis boş bir yol üzerinde çalışır ve eski veriyi görmez.- Gerçek bir istek:
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' https://example.com— 200 kodu ve birkaç yüz milisaniyenin altında süre. journalctl -b -p err --no-pager— eski loglar olmadan, bu önyüklemeye ait hatalar.
Dördüncü maddeyi ciddiye alın. active (running) olan bir servis pratikte yanıt vermeyebilir; örneğin PHP-FPM çalışıyor olabilir ama pool boş kalmış olabilir. Tek ölçüt, soket üzerindeki gerçek yanıttır.
Sunucu yeniden başlatma mı, servis yeniden başlatma mı: Hangisini seçelim
Sorun bir servisteyse, o servisi yeniden başlatmayı seçin. Tam sunucu reboot'u, kernel değişikliği, sistem kütüphanelerinin güncellenmesi veya servisin kurtarılamaz bir durumda takılması durumunda gereklidir. Pratik farkları downtime'dadır: nginx yeniden başlatma genellikle bir saniyenin altında sürer, tam reboot servis sayısına ve disk hızına bağlı olarak 30 ila 90 saniye arasında.
| Yöntem | Yaklaşık downtime süresi | Ne zaman doğrudur |
|---|---|---|
systemctl reload nginx | Sıfıra yakın | Bağlantı kesmeden konfigürasyon değişikliği |
systemctl restart nginx | 1 saniyeden az | Modül değişikliği veya worker'ın takılması |
reboot | 30 ila 90 saniye | Kernel güncellemesi, bozuk durumdan kurtarma |
Sunucu bulut altyapısındaysa ve reboot'tan önce snapshot alabiliyorsanız, bunu yapın. Bulut sunucu üzerinde bu snapshot alma birkaç saniyedir ve bir sonraki önyükleme herhangi bir nedenle başarısız olursa geri döndürülebilir. KVM veya rescue erişimi olmayan Özel sunucu üzerinde aynı işlem bir saatlik downtime'a dönüşür.
Otomatik yeniden başlatmada bir tuzak
Unit dosyasında Restart=always cezbedicidir. Ama servis konfigürasyon hatası nedeniyle sürekli crash olursa, systemd onu sonsuz döngüde yeniden başlatır ve sunucu logunu doldurur. Doğru kombinasyon şudur:
Restart=on-failure
RestartSec=5
StartLimitBurst=5
StartLimitIntervalSec=60
Yani dakikada en fazla beş deneme. Bundan sonra systemd pes eder ve siz onu loglarda kaybolmak yerine systemctl --failed içinde görürsünüz. Servisiniz sunucu yeniden başlatıldıktan sonra açılmıyor ve failed durumunda kalıyorsa, başka bir şey yapmadan önce journalctl -u service-name -n 50 okuyun; vakaların yüzde doksanında gerçek hata tam orada yazılıdır.
Sunucu yeniden başlatmadan sonra açılmadığında
SSH yanıt vermiyorsa ve konsol da bir şey göstermiyorsa, sorun muhtemelen mount veya fsck aşamasındadır. Bu durumda diski mount etmek ve önceki önyükleme loglarını okumak için rescue moduna ihtiyacınız vardır. Süreç Sunucu yeniden kurulumu ve rescue moduyla çalışma içinde adım adım açıklanmıştır. Sunucu açılıyor ama yavaşsa, sorun başka bir yerdedir ve Sunucu yüksek yükünün nedenini teşhis etme yolunu izlemelisiniz.
SSH hakkında bir not: Yeniden başlatmadan sonra bağlanamıyorsanız ama ping yanıt veriyorsa, önce sshd'yi kontrol edin, sonra konfigürasyonu. sshd_config içindeki hatalı değişiklikler, sunucunun dışında kilitlenmenin yaygın nedenlerinden biridir; önemli seçenekler SSH yapılandırması: Önemli güvenlik seçenekleri içinde listelenmiştir. Yeniden başlatmadan önce her zaman başka bir SSH oturumu açık tutun.
Sık sorulan sorular
systemd'de reload ile restart arasındaki fark nedir?
reload sürece, aktif bağlantıları kesmeden konfigürasyonu yeniden okuması için sinyal gönderir. restart süreci tamamen öldürür ve sıfırdan çalıştırır. nginx konfigürasyon değişikliği için her zaman reload yeterlidir; restart yalnızca yeni bir modül eklediyseniz veya worker anormal bir durumda takıldıysa gerekli olur.
Sunucu yeniden başlatıldıktan sonra servisim neden açılmıyor?
Üç yaygın neden: unit dosyasında Wants= veya Requires= eksikliği, bir bölümün mount'unun başarısız olması veya önceki önyüklemede de olan ama servisin manuel olarak başlatıldığı bir konfigürasyon hatası. systemctl --failed ve journalctl -b -p err ile üçü de birkaç dakika içinde teşhis edilebilir.
Sunucu yeniden başlatma verileri siler mi?
Hayır, bölümler doğru mount edilirse. Veri yalnızca veritabanı servisi ani kill ile kapatıldığında veya bölüm fsck hatası nedeniyle salt okunur olarak açıldığında risk altındadır. Bu nedenle reboot'tan önce veritabanını mysqladmin shutdown ile temiz kapatın.
Servislerin önyüklemeden sonra gerçekten sağlıklı döndüğünü nasıl anlarım?
systemctl --failed çıktısı boş olmalı, portlar ss -tlnp ile listen yapmalı ve curl ile gerçek bir istek 200 kodu döndürmelidir. active (running) durumu tek başına hiçbir şeyi garanti etmez.
Bir sonraki yeniden başlatmadan önce, ana servisiniz üzerinde bir kez systemd-analyze critical-chain çalıştırın ve gerçekte ondan önce neyin başlatıldığını görün. O tek çıktı, bir sonraki 502'yi herhangi bir kontrol listesinden daha fazla önler.