Ölü Bağlantılar Olmadan Veritabanlarını Uyandırmak
Mythex'te yayınlanmış uygulamalar ve veritabanları, kimse kullanmadığında uykuya geçer. Bir uygulama uyandığında, her şey uyurken ölmüş veritabanı bağlantılarını yeniden kullanmaya çalıştığı için ilk isteği 10-12 saniye tutabiliyordu. Artık Spring Boot uygulamalarına uyku boyunca güvenli olan veritabanı ayarlarını veriyoruz ve agent'a her yığındaki uygulamayı aynı şekilde kurmasını söylüyoruz. Barındırma platformunda, uyandırma sonrası ilk istek 12,7 saniyeden 2,3 saniyeye indi.
Uygulamalar ve veritabanları neden uyur?
Yayınlanmış bir Mythex uygulaması, birkaç dakika boşta kaldıktan sonra askıya alınan bir makinede çalışır. Veritabanı ise beş dakika boşta kaldıktan sonra uyuyan ve bir sonraki istekte uyanan sunucusuz bir Postgres'tir. Sessiz bir uygulamayı ucuz tutan da budur: veritabanının gerçekten kullandığı kadar ücretlendirilirsiniz ve uyuyan bir uygulama işlem gücü için bir şey harcamaz. Faturalandırma tarafını veritabanlarını gerçekten kullandıkları şeye göre faturalandırmak yazısında anlattık.
Tuzak şu: ikisi ayrı ayrı uyur ve bağlantının ne olduğu konusunda anlaşamazlar.
Belirti: yavaş ilk ziyaret
Çoğu sunucu uygulaması bir bağlantı havuzu tutar: her istek yeni bir bağlantı açmanın maliyetini ödemesin diye hazırda bekleyen birkaç açık veritabanı bağlantısı. Sürekli açık olan bir uygulama için bu doğru tasarımdır.
Uykuyla birlikte şöyle olur:
- Uygulama çalışıyor ve havuzunda birkaç boşta bağlantı var.
- Kimse ziyaret etmiyor. Uygulamanın makinesi askıya alınır; havuzu olduğu gibi kalarak donar.
- Veritabanı uyur ve her bağlantının kendi ucunu düşürür.
- Bir ziyaretçi gelir. Uygulama olduğu gibi uyanır, ama veritabanının artık bilmediği bağlantıları hâlâ tutmaktadır.
- Havuz bu bağlantılardan birini verir. Vazgeçmeden önce, bağlantının öldüğünü denemek ve beklemekle anlaması gerekir.
Spring Boot uygulamasında, bu ölü bağlantıları doğrulamak ilk isteği yaklaşık 10 saniye tuttu, ardından "Connection is not available" hatasıyla başarısız oldu. Ziyaretçiye site sadece takılmış gibi göründü ve belki sonunda bir hata gösterdi.
Spring uygulamaları neden en çok etkilendi?
Spring Boot popüler bir Java çatısıdır ve varsayılan olarak HikariCP adlı bir bağlantı havuzu kullanır. Spring bu havuzu ayarlardan yapılandırabilir; boşta kaç bağlantının tutulacağı dahil.
Ama Mythex her uygulamaya veritabanını postgresql://user:pass@host/db biçiminde tek bir DATABASE_URL olarak verir. Spring bu biçimi doğrudan okuyamaz. Bu yüzden Mythex üzerinde kurulan Spring uygulamaları, bu URL'yi ayrıştırarak kendi havuzlarını kodla oluşturuyordu. Elle kurulan bir havuz ise Spring'in tüm spring.datasource.* ayarlarını yok sayar. Doğru havuz ayarlarını bilseler bile bunların uygulanacağı bir yer yoktu.
Düzeltme, 1. kısım: Spring'in kullanabileceği ayarlar
Bir projede veritabanı olduğunda, artık Spring'in doğrudan okuduğu ortam değişkenlerini de veriyoruz:
DATABASE_URL'den dönüştürülenSPRING_DATASOURCE_URL,SPRING_DATASOURCE_USERNAMEveSPRING_DATASOURCE_PASSWORD(URL aksini söylemedikçe SSL zorunlu).- Uykudan sağ çıkan havuz ayarları:
| Ayar | Değer | Neden |
|---|---|---|
| Minimum boşta bağlantı | 0 | İstekler arasında hiçbir şey açık tutulmaz, böylece bayatlayacak bir şey kalmaz |
| Boşta kalma zaman aşımı | 30 saniye | Kullanılmayan bağlantılar hızla kapanır |
| Maksimum ömür | 2 dakika | Her bağlantı, eskiyebileceği andan önce emekliye ayrılır |
| Bağlantı zaman aşımı | 5 saniye | Veritabanı yavaş yanıt verirse bir isteği uzun süre asılı bırakmaz |
Hiç boşta bağlantı tutulmadığında, uyandırılan bir uygulama ölü bağlantılar arasında yürümek yerine yeni bir bağlantı açar.
Bu değişkenler mevcut olduğunda Spring havuzu kendisi yapılandırır ve ayarlar uygulanır. Projenin kendi ayarladığı her şey her zaman kazanır; biz yalnızca eksik olanları doldururuz. Spring olmayan uygulamalar bu değişkenleri yok sayar.
Neredeyse hiçbir şey yapmamasına yol açan ayrıntı
Spring, ortam değişkenlerini ayarlarına, kolayca yanlış yapılabilen bir kuralla eşler. minimum-idle ayarı SPRING_DATASOURCE_HIKARI_MINIMUMIDLE olarak yazılmalıdır: tireler düşürülür, kelimeler bitişik yazılır. Daha doğal görünen SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE ise farklı, var olmayan bir ayara (minimum.idle) eşlenir ve sessizce yok sayılır.
Bu, her incelemeden geçen ama üretimde hiçbir şey yapmayan türden bir hatadır. Bu yüzden bir test, hem değerlerin ayarlandığını hem de hiçbir değişkenin alt çizgiyle ayrılmış biçimi kullanmadığını kontrol eder.
Düzeltme, 2. kısım: diğer tüm yığınlar
Spring, havuzu olan tek çatı değildir ve her dildeki her kütüphaneyi önceden yapılandıramayız. Bu yüzden uygulamanızı yazan Mythex agent'ı artık her yığın için kalıcı bir talimat alıyor: yayınlanmış uygulamalar ve veritabanları boşta kaldıklarında uyur, bu yüzden açık tutulan bir bağlantı bir sonraki istekte ölü olabilir. Agent şunları yapmalı:
- Boşta hiçbir veritabanı bağlantısını açık tutmamak ya da kullanmadan önce her birini kontrol etmek,
- Bir bağlantı hatasında bir kez yeniden denemek,
- Kendi havuzunu
DATABASE_URL'yi ayrıştırarak oluşturmak yerine, platformun ortamda sağladığı veritabanı ayarlarını kullanmak.
Son madde, 1. kısımla döngüyü kapatır: sağlanan ayarlar üzerine kurulmuş bir uygulama, uykuya dayanıklı yapılandırmayı otomatik olarak alır.
Sonuç
Yayınlanmış uygulamaları çalıştırdığımız barındırma platformunda ölçüldüğünde, uyandırma sonrası ilk istek 12,7 saniyeden 2,3 saniyeye düştü.
Bundan çıkardıklarımız
- Uyuyan her katman, neyin hayatta kalacağı konusunda anlaşmalıdır. Donmuş bir uygulama ve uyuyan bir veritabanı, her biri makul bir seçim yaptı. Birlikte ise uygulama, artık doğru olmayan bir durumu tutarak uyandı.
- Sürekli açık sunucular için tasarlanan varsayılanlar, sıfıra ölçeklenen uygulamalara uymaz. Bağlantıları sıcak tutmak, etraflarındaki her şey soğuduğunda iyi bir fikirden çıkar.
- Çatılara verilerini kendi biçiminde verin. Bizim için tek bir URL basitti, ama her Spring uygulamasını kendi yapılandırmasını yok sayan bir havuzu elle yazmaya zorladı.
- Bir ayarın, çatının okuduğu biçimde yazıldığını test edin. Yanlış bir adla doğru bir değer, sessizce hiçbir şey yapmaz.
Mythex'te veritabanlarının nasıl çalıştığını öğrenmek için veritabanı dokümanlarına ve Postgres nedir açıklayıcımıza bakın.