EYDefterEmre Yakut
← tüm yazılar
Sunucu · Hata avı · derin

“Site açılmıyor” ve “ödeme görünmüyor”: iki kök neden

Aynı hafta iki şikâyet geldi. Biri “site hiç açılmıyor ama ben girebiliyorum”, diğeri “müşteri ödedi, sistemde görünmüyor”. İkisinin de sebebi, hata mesajı vermeyen bir yerdeydi.

“ödeme görünmüyor”bildirim ulaştı✓bildirim işlendi✓sipariş durumu yazıldı✓muhasebe kaydı yazıldı✗tablo yoktu — hata yakalandı, AKIŞ DEVAM ETTİ“site açılmıyor ama ben girebiliyorum”pm.max_children = 4 → dört işçi dolugerisi soket kuyruğunda bekliyor → zaman aşımıerişim logunda yok · hata logunda yokhavuzu dolduran kişi girebiliyor — imza buiki ayrı katman, tek ortak nokta: ikisi de hata mesajı üretmiyordubir sistemin sessiz kalması, iyi çalıştığı anlamına gelmiyor

Bir e-ticaret sitesi yayına girdi. Aynı hafta iki şikâyet geldi ve ikisi de klasik “şu bozuk” değildi.

Birinci: “müşteri ödedi, sistemde görünmüyor”

Bir sipariş ödendi ama panelde hâlâ “ödeme bekleniyor” yazıyordu. Tek bir sipariş olsa elle düzeltirsin. Ama yayılıyordu.

Ödeme akışını takip ettim:

ödeme sağlayıcısı → bildirim ulaştı        ✓
uygulama          → bildirimi aldı         ✓
uygulama          → sipariş durumunu yazdı ✓
uygulama          → muhasebe kaydını yazdı  ✗

Son adım bir tabloya yazıyordu. O tablo yoktu.

Kurulum sırasında bir veritabanı göçü çalıştırılmamıştı. Tablo eksik olunca o adım hata veriyor, hata yakalanıyor ve loglanıyor — ama akış devam ediyordu. Yani sipariş “ödendi” oluyor, muhasebe tarafı hiç oluşmuyordu.

buradaki asıl hata eksik tablo değil

Eksik tablo bir kaza. Asıl hata, başarısız bir adımın akışı durdurmaması.

Ödeme muhasebesi gibi bir adım başarısız olduğunda sistem “devam et” dememeli. Ya işlemin tamamı geri alınmalı, ya da sipariş açıkça “eksik” olarak işaretlenip birinin önüne düşmeli.

Sessizce devam etmek, hatayı bir kayıt hatasına dönüştürüyor — ve kayıt hataları ancak aylar sonra fark ediliyor.

Tabloyu oluşturdum, geçmişe dönük kayıtları tamamladım, ve akışa şunu ekledim: muhasebe adımı başarısız olursa sipariş “inceleme gerekiyor” kuyruğuna düşüyor.

İkinci: “site hiç açılmıyor ama ben girebiliyorum”

Bu, cümlesiyle kendini ele veren bir hata.

Site dışarıdan açılmıyordu. Ama panel sahibi giriyordu. Erişim logunda hata yok, hata logunda hiçbir şey yok, sunucu yükü normal.

Sebep PHP-FPM havuzuydu.

sunucunun sessiz darboğazı
pm.max_children = 4

Panel her hesap için ayrı bir havuz dosyası üretiyor ve hepsine aynı varsayılanı yazıyor: aynı anda en fazla dört istek. Yoğun bir hesap için bu çok düşük.

Havuz dolduğunda istekler reddedilmiyor — soket kuyruğunda bekliyor ve zaman aşımına düşüyor. Dışarıdan görünüşü “site açılmıyor”, ama istek web sunucusuna hiç ulaşmadığı için hiçbir logda görünmüyor.

Ve şu asimetri: havuzu dolduran kişi işçileri elinde tuttuğu için kendisi girebiliyor, sıraya giren başkası giremiyor.

“Ben girebiliyorum ama başkası giremiyor” cümlesi, bu hatanın imzası.

Nasıl doğrulandı

Kesin kanıt havuzun kendi logunda:

# önce hangi PHP sürümünde çalışıyor, onu bul
grep SetHandler /…/vhosts/<alan>.conf

# sonra o sürümün havuz loguna bak
WARNING: [pool <hesap>] server reached pm.max_children setting (4),
         consider raising it

Havuz sınırı yükseltildi ve site normale döndü.

İkisinin ortak yanı

İki hata tamamen farklı katmanlarda. Ortak yanları şu: ikisi de hata mesajı üretmiyordu.

ne oldune görünüyordu
Eksik tablobir adım başarısız, akış devam ettisipariş başarılı
Havuz doluistek kuyrukta zaman aşımına uğradıhiçbir log kaydı

Sessiz başarısızlık, bu yılın en çok karşıma çıkan hata sınıfı oldu. Komut satırı bayraklarında, mail gözcüsünde, CSS sınıf adında — hepsi aynı desen.

Aynı hafta yapılan temizlik

Bu iki kök nedenin dışında, aynı turda ufak ama can sıkıcı şeyler de düzeldi:

  • Panelde barkod üretilirken çıktıya altmıştan fazla uyarı satırı basılıyordu — eski bir kütüphanenin yeni PHP’de ürettiği kullanımdan kaldırma uyarıları. Çıktıyı bozmadan bastırıldı.
  • Yönetim panosu her 15 saniyede bir yoklama yapıyordu. 60 saniyeye çekildi; kimse fark etmedi, sunucu rahatladı.
  • Hesap formlarında bazı seçim kutuları görünmüyordu — tema geçişinden kalan bir stil çakışması.
  • Canlıda hata ayıklama çubuğu açık kalmıştı. Kapatıldı; artıklar temizlendi.

Ne öğrendim

“Site açılmıyor” bir semptom. İlk refleks koda bakmak oluyor; oysa bu vakada kodda hiçbir sorun yoktu.

Ve “ödeme görünmüyor” bir semptom. Kodda sorun vardı ama kod doğru çalışıyordu — yanlış olan, başarısızlığın nasıl ele alındığıydı.

İkisinin dersi aynı: bir sistemin sessiz kalması, iyi çalıştığı anlamına gelmiyor.

SunucuHata avı