Pazar Sabahı Beklenmedik Bir Hata
Bu pazar sabahı bilgisayarımın başına oturduğumda, hafta içi kurduğum bir AI pipeline’ının beklenmedik bir şekilde çökmesiyle karşılaştım. Normalde sorunsuz çalışan bu pipeline, veri çekme ve işleme adımlarını otomatikleştiriyordu. Ancak o sabah aldığım hata mesajı oldukça garipti. Sistemin temelini oluşturan veri çekme modülü, her zamanki gibi çalışması gerekirken, anlık olarak veriyi işleyemiyordu. Bu durum, günlerdir üzerinde çalıştığım bir otomasyon projesinin ilerlemesini durdurdu ve hafta sonu olmasına rağmen beni bir debugging seansına zorladı.
Normalde bu tür haftalık işlerimi tamamladıktan sonra sistemin gece saatlerinde batch işlerini halletmesini beklerim. Ancak bu sefer durum farklıydı. Pipeline, pazar sabahı 08:17’de başladı ve hemen ardından ilk veri çekme adımında hata verdi. Hata loglarına baktığımda, connection refused gibi genel bir hata yerine, daha spesifik bir timeout hatası görüyordum. Bu, ağ bağlantısında bir sorun olduğunu düşündürse de, aynı ağ üzerinde çalışan diğer servislerimde hiçbir sıkıntı yoktu. Bu durum, sorunun sadece bu pipeline’a özgü olduğunu ve daha derin bir kökeni olabileceğini işaret ediyordu.
İlk Adım: Temel Kontroller ve Log Analizi
Her debugging seansının ilk adımı, her zaman en basit şeylerden başlamaktır. Pipeline’ı çalıştıran script’in çalıştığı ortamın (bu durumda bir Docker container içinde çalışan bir sanal ortam) sağlıklı olduğundan emin oldum. Ardından, ilgili servisin log dosyalarını daha detaylı incelemeye başladım. journald çıktısı, hatanın tam olarak hangi noktada oluştuğunu gösteriyordu:
May 12 08:17:01 ai-worker-1 python[1234]: INFO: Starting data ingestion process...
May 12 08:17:05 ai-worker-1 python[1234]: ERROR: Failed to connect to data source: Timeout occurred after 30 seconds.
May 12 08:17:05 ai-worker-1 python[1234]: Traceback (most recent call last):
File "/app/ingestion.py", line 55, in ingest_data
response = requests.get(DATA_SOURCE_URL, timeout=30)
File "/usr/local/lib/python3.10/site-packages/requests/api.py", line 117, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 555, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 668, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.10/site-packages/requests/adapters.py", line 519, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: Timeout occurred after 30 seconds.
Bu loglar, requests kütüphanesinin DATA_SOURCE_URL’e yaptığı GET isteğinin 30 saniyelik timeout süresine rağmen yanıt alamadığını gösteriyor. Ancak bu URL, haftalardır stabil bir şekilde çalışıyordu. Bu, sorunun ağ yapılandırmasında veya hedef serviste olabileceğini düşündürdü.
Hemen hedef servisin (bu bir harici API’ydi ve ismini vermeyeceğim, ancak genellikle büyük veri sağlayıcıları bu tür hizmetler sunar) durum sayfasını kontrol ettim. Orada herhangi bir kesinti veya bakım bilgisi yoktu. Bu, sorunun daha çok benim altyapım veya API’nin benim IP adresime uyguladığı bir kısıtlama olabileceğini akla getiriyordu.
İkinci Aşama: Ağ ve Güvenlik Duvarı Yapılandırması
Hedef API’nin kendisinde bir sorun olmadığını varsayarak, sorunun benim tarafımdaki ağ ve güvenlik yapılandırmasında olabileceğini düşünmeye başladım. Pipeline’ım bir Docker container içinde çalışıyordu ve bu container’ın dış dünyaya erişimi bir proxy üzerinden sağlanıyordu. Normalde bu proxy ayarları doğru yapılmıştı. Ancak pazar sabahı olması, hafta sonu rutin bakım çalışmaları veya otomatik güncellemelerin bir etkisinin olup olmadığını düşündürdü.
Sistemimde kullandığım ufw (Uncomplicated Firewall) kurallarını ve Docker’ın ağ köprülerini (network bridges) kontrol ettim. Herhangi bir kuralın yanlışlıkla bu spesifik trafiği engellemediğinden emin olmak için ufw status verbose komutunu çalıştırdım. Çıktı temizdi, herhangi bir engelleme görünmüyordu. Ardından, container’ın ağ yapılandırmasını inceledim. Docker’ın iptables kurallarının karmaşıklığı bazen beklenmedik sorunlara yol açabiliyor. Bu sebeple, container’ın doğrudan dışarıya erişimini test etmek için geçici olarak bir docker exec komutu ile container içine girip ping ve curl komutlarını denedim.
# Container ID'sini alıyorum
docker ps
# Container içine giriyorum
docker exec -it <container_id> /bin/bash
# Ping testi yapıyorum
ping google.com
# Ping çalışıyor, temel ağ bağlantısı var.
# Curl testi yapıyorum
curl -v -m 30 $DATA_SOURCE_URL
# Curl ile de aynı timeout hatasını aldım.
Bu testler, temel ağ bağlantısının var olduğunu ancak belirli bir URL’ye yapılan isteğin neden 30 saniyede kesildiğini anlamama yardımcı olmadı. Sorun hala gizemini koruyordu. Bu noktada, sorunun basit bir yapılandırma hatası değil, daha ince bir detayla ilgili olabileceğini düşünmeye başladım.
Üçüncü Adım: MTU ve MSS Mismatch Şüphesi
Ağ bağlantısı temel olarak çalışıyor ancak belirli bir isteğin timeout’a uğraması, özellikle de zaman zaman karşıma çıkan MTU (Maximum Transmission Unit) veya MSS (Maximum Segment Size) uyumsuzluklarını akla getirdi. Bu tür uyumsuzluklar, ağ cihazları arasında veri paketlerinin parçalanmasına veya tamamen düşmesine neden olabilir. Özellikle farklı ağ segmentleri arasında veya VPN tünelleri üzerinden yapılan bağlantılarda bu tür sorunlar yaşanabilir. Benim pipeline’ım bir proxy sunucusu üzerinden dışarıya bağlanıyordu ve bu proxy sunucusunun kendisi de bir sanal özel ağ (VPN) üzerinden ana ağımıza bağlıydı.
İlk olarak, proxy sunucusunun MTU değerini kontrol ettim. Genellikle 1500 olarak ayarlanır, ancak bazı VPN çözümleri veya ağ kartı sürücüleri farklı değerler kullanabilir.
# Proxy sunucusunda MTU'yu kontrol et
ip addr show eth0 | grep mtu
# Çıktı: mtu 1500
MTU değeri normal görünüyordu. Bir sonraki adım, MSS clamping’i kontrol etmekti. MSS clamping, TCP bağlantılarının başlangıcında gönderilen MSS değerini belirli bir limite sabitleyerek paket parçalanmasını önlemeye çalışır. Eğer bu özellik doğru yapılandırılmamışsa veya bir ağ cihazında yanlış ayarlanmışsa, sorunlara yol açabilir.
Ancak bu aşamada, doğrudan bir iptables komutu çalıştırmak yerine, daha kolay bir yaklaşım denedim. Kendi sunucumdan hedef API’ye traceroute ile bir trace atmaya çalıştım. Bu, paketlerin hangi yönlendiricilerden geçtiğini ve her bir adımda ne kadar sürdüğünü görmemi sağlardı.
traceroute -m 30 $DATA_SOURCE_URL
traceroute çıktısı, trafiğin beklediğimden farklı bir yoldan gittiğini gösteriyordu. Normalde doğrudan çıkış ağ geçidimizden çıkması gereken trafik, ara bir noktada farklı bir rotaya sapıyordu. Bu, hafta sonu yapılan bir ağ rotası güncellemesinin veya bir yönlendiricinin beklenmedik davranışının eseri olabilirdi. Bu durum, sorunun kaynağını artık daha spesifik bir ağ cihazına veya rotaya odaklamama yardımcı oldu.
Dördüncü Aşama: Gerçek Sebep ve Çözüm
Traceroute çıktısındaki anormalliği fark ettikten sonra, ağ altyapımızın sorumlusu olan ekiple iletişime geçtim. Onlar da hafta sonu yapmış oldukları bir yönlendirici konfigürasyon güncellemesinin, bazı eski protokollerle iletişim kuran servislerde beklenmedik yan etkilere neden olduğunu belirttiler. Özellikle, benim kullandığım API’nin iletişim kurduğu sunucunun bir tür NAT (Network Address Translation) cihazı arkasında olması ve bu cihazın belirli TCP flag’lerini doğru işleyememesi soruna yol açıyordu.
Sorunun kökeni şuydu: Güncellenen yönlendirici konfigürasyonu, bazı TCP paketlerini varsayılan olarak daha agresif bir şekilde filtrelemeye başlamıştı. Benim AI pipeline’ımın veri çekme isteği, bu filtrelemeye takılan belirli TCP paketleri içeriyordu. Bu paketler düşürüldüğü için, hedef sunucu yanıt veremiyor ve benim tarafımdaki requests kütüphanesi de 30 saniyelik timeout süresi dolunca hatayı fırlatıyordu. Kısacası, “timeout” aslında bir paket kaybı sorunuydu.
Çözüm olarak, ağ ekibi yönlendiricideki ilgili kuralı güncelledi ve benim IP adresimden gelen trafiğin bu agresif filtrelemeden muaf tutulmasını sağladı. Bu değişiklik yapıldıktan sonra, pipeline’ımı tekrar başlattım ve bu sefer sorunsuz bir şekilde çalışmaya başladı. Veri çekme modülü başarıyla veri alabildi ve pipeline’ın geri kalanı da normal işleyişine devam etti. Pazar sabahı saat 11:30 civarında sorun çözülmüştü.
Bu deneyim, altyapının ne kadar karmaşık ve birbirine bağlı olabileceğini bir kez daha gösterdi. Bazen en basit görünen hata mesajları, altta yatan derin ve karmaşık sorunların bir göstergesi olabilir. Bu tür durumlarda, sorunu daraltmak için sistematik bir yaklaşım izlemek hayati önem taşır.
Çıkarılan Dersler ve Gelecek Adımlar
Bu pazar sabahı yaşananlar bana birkaç önemli dersi pekiştirdi. Birincisi, otomasyon sistemlerinin beklenmedik anlarda devreye girebileceği ve hafta sonu bile olsa müdahale gerektirebileceğidir. İkincisi ise, MTU ve MSS uyumsuzluklarının hala geçerli ve potansiyel olarak ciddi ağ sorunlarına yol açabilen bir konu olduğudur. Üçüncüsü ve en önemlisi, altyapıdaki değişikliklerin etkilerini dikkatle izlemek ve olası yan etkileri öngörmeye çalışmaktır.
Gelecekteki adımlarım şunları içerecek:
- Daha Detaylı Monitoring: Pipeline’ın ağ bağlantılarını ve veri akışını daha anlık ve detaylı izlemek için yeni metrikler ekleyeceğim. Özellikle TCP bağlantı durumları, paket kayıpları ve
timeoutsüreleri gibi metrikleri izleyeceğim. Bu, sorunları kullanıcılar etkilenmeden önce tespit etmeme yardımcı olacaktır. - Ağ Yapılandırması Takibi: Ağ ekibinin yapacağı tüm değişikliklerden haberdar olmak ve bu değişikliklerin pipeline’ım üzerindeki potansiyel etkilerini önceden değerlendirmek için düzenli iletişim kuracağım. Belki de bir “change management” sürecine dahil olmam gerekecek.
- Hata Yönetimi Optimizasyonu: Pipeline’ımda hata oluştuğunda daha akıllıca hareket eden bir hata yönetimi mekanizması geliştireceğim. Örneğin, belirli bir tür
timeouthatası aldığımda otomatik olarak alternatif bir veri kaynağına yönelme veya farklı bir ağ rotası deneme gibi stratejiler uygulayabilirim.
Bu tür sorunlar, teknoloji dünyasının sürekli değişen ve gelişen doğasının bir parçası. Önemli olan, bu sorunlarla karşılaştığımızda sakin kalıp, sistematik bir şekilde çözüme ulaşmaktır. Bu pazar sabahı yaşananlar, bir kez daha gösterdi ki, debugging sadece bir teknik beceri değil, aynı zamanda bir sabır ve problem çözme sanatıdır.