Bağlam
Bağlam
Bir SaaS uygulaması yönetiyorum. TikTok reklam kampanyalarını ajanslar için otomatikleştiriyor. Her müşteri, N İş Merkezi → N Reklam Hesapları → N Kampanyalar → N Reklam Grupları → N Reklamlar hiyerarşisine sahip.
Bugünün rakamları:
- 87K R$ MRR
- 1M R$ ARR
- TikTok API’sine karşı günde 7 milyondan fazla istek
- 600+ endpoint haritalandı
- Her şey bir Laravel 12 monolitinde
Ben tek başıma bir geliştiriciyim.
Kural 1: Daha az, daha çoktur
Kural 1: Daha az, daha çoktur
Aşağıda anlatacağım her seçim, tek bir kısıtlamadan gelmektedir: Bir ekibim yok. Bu her şeyi değiştirir. Bir araç daha, yapılandıracak, izleme yapacak, güncelleyecek ve sabah 3’te hataları giderecek bir araç demektir. Bu yüzden kriterlerim her zaman:
- Aracın bugün sahip olduğum bir gerçek problemi çözüp çözmediği?
- Karmaşıklığı artırıyor mu yoksa acıyı mı azaltıyor?
- Yarın bozulursa, kendim düzeltebilir miyim?
Bu sorulardan herhangi birinin yanıtı “hayır” ise, dışarda kalır.
TikTok API’si ile entegrasyon oluşturmanın zorlukları
TikTok API’si ile entegrasyon oluşturmanın zorlukları
İnşaat mühendisliğinden bahsetmeden önce ortamı açıklamam lazım. TikTok API ile entegrasyon, her kararı şekillendiren bazı gariplikleri içeriyor:
1. API güncellemeleri yalnızca Cuma günleri yapılır
- TikTok, genellikle Cuma günleri sözleşme değişiklikleri, yeni endpoint’ler veya düzeltmeler sürer.
- Eğer mevcut bir dağıtımda bir şey kırılırsa, hasar hafta sonu olur ve destek en yavaş halindedir.
- Cuma öğleden sonraları, parmakları çapraz tutmak için geçer; Pazartesi sabahları yangın söndürme zamanı.
- Kendi sürümümü Cuma günü planlayamam — tepkime gösterecek bir alan bırakmalıyım.
2. TikTok’a ulaşmak zordur
- Resmi destek, günler ölçüsünde bir SLA’ya sahip.
- Yaygın bilet yanıtı: “biraz sonra tekrar deneyin” veya “hesap yöneticinize ulaşın”.
- Özel bir Partner Yöneticisi yoksa, kamu forumu ve kanal ile sıkışıp kalıyorsunuz.
- Onaylanan bir hatanın düzeltmesi üretime girmesi haftalar alıyor.
- Çoğu zaman, çözüm destek cevap vermeden önce bir iş çevresi bulmaktır.
3. Eksik ve tutarsız dokümanlar
- Resmi belgeler “mutlu yol” üzerindedir — uygulamada keşfettiğiniz kenar durumlarıyla karşılaşacaksınız.
- Bir endpoint, belgede yer alan yapıdan farklı bir yapı döndürüyor ve değiştirilmeden yeni bir duruma geçebiliyor.
- Endpoint başına hız sınırlamaları her zaman yayımlanmaz — 429 ile karşılaşana kadar öğrenmezsiniz.
- Üretimde gözüken durum kodları belgelerde yok.
- Aynı aile içinde endpoint isimlendirmeleri farklı olabilir.
4. Sandbox ≠ üretim
- Sandbox ve prod arasında farklı davranışlar vardır.
- Sandbox kabul eder, prod reddeder — veya tersi.
- Bir alanda birinin zorunlu olduğu diğerinde isteğe bağlı olabilir.
- Test ediyorsunuz, onaylıyorsunuz, dağıtıyorsunuz ve ancak o zaman gerçek sözleşmenin başka bir şey olduğunu keşfediyorsunuz.
- Sonuç: nihai testlerin bir kısmı gerçek bir hesapta, gerçek bir müşteri ile yapılmalıdır.
5. Yenileme jetonu olmaksızın OAuth
- Erişim jetonu “uzun vadeli”dir (belirtilen bir son tarih yok).
- Yenileme akışı yoktur — eğer jeton iptal edilirse, müşteri manuel olarak yeniden kimlik doğrulaması yapmalıdır.
- Güvenli bir şekilde saklamak sizin sorununuzdur (ben Laravel Crypt ile şifreliyorum).
- Bir jetonun kaybı, bir müşterinin hesabına erişimi kaybetmek anlamına gelir.
6. 600+ endpoint haritalandı
- Kampanya, reklam grubu, reklam, yaratıcı, piksel, rapor, itiraz, iş merkezi, ortak — her biri kendi endpoint setine sahip.
- Her bir endpoint’in kendine özgü gariplikleri vardır (farklı sayfalama, farklı isimlendirme, farklı hız limiti havuzu).
- Bunların tümünü tutarlı tutmak güçlü bir soyutlama katmanı ve dahili sürümleme gerektirir.
7. Hız limiti her havuz için, uygulama başına değil
- TikTok, hız limitlerini endpoint ailesi ile ayırır — “raporlar” kotaları, “kampanyalardan” farklıdır, bu da “yaratıcılardan” farklıdır.
- Toplam istekleri saymak yeterli değildir; her havuz başına saymam gerekir.
- Bu durumu Redis Lua ile ($sliding window per bucket) uyguladım çünkü basit bir sayıcı yetmez.
Bu kısıtlamalar her şeyi şekillendirir:
- Bu yüzden 3 katmanlı hız limiti var (middleware’de pre-flight, Redis’te $sliding window, gerçek 429 geri Basıncı).
- Bu yüzden her işte idempotans zorunludur — eğer bir oluşturma tekrar denemesinde başarısız olursa, iki kampanya oluşturmak istemiyorum.
- Bu yüzden API ile detailed request/response logging vardır — bir şey patladığında ve bir bilet açmam gerektiğinde, zaten elimde kanıt var.
- Bu yüzden hata çeviri katmanı (
TikTokErrorTranslator) var — ham kodları son kullanıcıya göstermek uygun değil. - Bu yüzden OAuth jetonu veritabanında şifreli olarak depolanır — eğer sızarsa, üretim müşterinize erişimi kaybedersiniz.
Bu kısıtlamaları ortadan kaldırırsanız, mimari fazlasıyla aşırı görünür. Bunlarla, en azını oluşturmaya çalışıyorum.
Harici entegrasyon işinin anatomisi
Harici entegrasyon işinin anatomisi
Dış API ile konuşan her işlem bir işte çalışır. Asla kullanıcının HTTP isteği içinde senkron olmaz. Bu kalıp, her kritik entegrasyona uygulanır:
class SyncExternalResourceJob implements ShouldQueue
{
use Queueable, ExternalApiRateLimit;
public int $maxExceptions = 3;
public int $timeout = 120;
public array $backoff = [10, 30, 60];
public function retryUntil(): \DateTime
{
return now()->addMinutes(30);
}
public function handle(): void
{
// 1. Yerel durumu doğrula (varlık var, hesap aktif, jeton geçerli)
// 2. İdempotans: kaynak zaten senkronlanmışsa, iptal et
if ($this->resource->external_id !== null) {
return;
}
// 3. Dış API'yi çağır
// 4. Hatanın sınıflandırması: geçici (tekrar dene), kalıcı (başarısız), faturalama (duraklat)
// 5. Dış_id ile dönen yerel durumu güncelle
// 6. Zincirdeki bir sonraki işi, varsa, yolla
}
public function failed(\Throwable $e): void
{
// Cascade: bekleyen çocukları Başarısız olarak işaretle, sağlayıcının
// teknik mesajını son kullanıcıların anlayabileceği bir şeye çevir
}
}
Her seçim bir amaç taşır:
maxExceptionsyerinetries→ hız sınırlaması nedeniyle bir serbest bırakma, bir denemeyi tüketmemelidir. Sadece gerçek hatalar sayılır.retryUntil30 dakikadır → kaydırma penceresine açılmak için alan tanır.- Üstel
backoff→ eğer sağlayıcı bir sorun yaşıyorsa, sürekli tekrar yapmıyorum. - Hız limiti özellik → handle öncesinde çalışan middleware’i enjekte eder.
external_idkontrolü → idempotans. Eğer tekrar deneme, oluşturma başarılı ama yerel güncelleme öncesinde gerçekleşirse, bir sonraki döngü iptal edilir. Sağlayıcıda hiç bir kopya kaynak oluşturmaz.- Karmaşık
failed()→ kalıcı bir ebeveyn hatası, bekleyen çocukları işaretler; teknik hatayı dostça bir mesaja çevirir.
Bu atomdur. Platformdaki her dış operasyon bunun üzerine inşa edilmiştir.
İş zincirleme: atomları bir iş akışına eklemek
İş zincirleme: atomları bir iş akışına eklemek
Platformun büyük bir kısmı hiyerarşik bir iş akışıdır — önce bir üst kaynak oluştur, sonra N çocuğu, sonrada N torunu. Müşterinin formu her şeyi bir arada toplar, ama uygulama aşamaları olarak gerçekleşir:
- Kontrolcü, her şeyi yerel veritabanında Taslak olarak kaydeder — atomik şekilde, sağlayıcıyla konuşmadan.
- Ebeveyn işini
chainToChild = trueile gönderir. - Ebeveyn iş, API’yi çağırır,
external_idkaydeder ve her bekleyen çocuk için çocuk işini yollar. - Çocuk işi API’yi çağırır,
external_idkaydeder ve her torun için torun işini yollar. - Torun işi zinciri sona erdirir.
Neden bu şekilde ve tek bir devasa işlem yerine?
- Her adım dış API’ye hitap eder → 3 HTTP çağrısı arasında kilitli bir işlem, intihar gibidir.
- Her adım bağımsız olarak başarısız olur → Ebeveyn başarılı olursa ama çocuk hatalı olursa, ebeveyn sağlayıcıda geçerli kalır, çocuk veritabanında
Failedolarak kalır ve müşteri sadece eksik olanı yeniden işler. - Yeniden deneme ayrıntısı → üçüncü torun işinde hız sınırına mı takıldınız? Sadece o kuyruğa geri döner, diğerleri devam eder.
- Her seviyede idempotans → iki kez çalıştırırsanız? İkinci geçiş,
external_idzaten doldurulmuş olarak gördüğünde atlar.
Zincirleme ile iyileştirme örneği:
// Eğer ebeveyn kaynak zaten senkronlanmışsa ama zincirleme istediysem,
// yalnızca henüz yapılmayan çocukları göndermem yeterlidir.
if ($this->parent->external_id && $this->chainToChild) {
$pendingChildren = $this->parent->children()
->whereIn('status', [Status::Draft, Status::Failed])
->whereNull('external_id')
->get();
foreach ($pendingChildren as $index => $child) {
SyncChildJob::dispatch($child)
->delay(now()->addSeconds(* 2));
}
return;
}
Yavaş yavaş dağıtım sürelerini yaymak için delay(index * 2) kullanarak gecikmeleri yaymak, hız sınırını patlatmaktan kaçınır.
Bütün bunlar bir monolit içerisinde, hiç Temporal, Step Functions, ya da dış bir düzenleyici yok. Kuyruklar + iş başına idempotans, karmaşık bir iş akışını çözer.
Üç katmanlı hız sınırlaması ile atomik Lua
Üç katmanlı hız sınırlaması ile atomik Lua
Burada mühendislik devreye girer. Dış sağlayıcının her endpoint havuzu başına kısıtlamaları ve üç seviyenin olduğunu hatırlayın (QPS, QPM, QPD)? Ve bazı havuzların geçtiğinizde gerekli ‘soğuma’ süreleri vardır?
Bunu raflarda bulunan bir hız sınırlayıcı ile çözemezsiniz. Kendi hız sınırlayıcımı 3 katmanlı olarak oluşturdum:
Katman 1 — Ön uç iş middleware’inde
Handle() çalışmadan önce, middleware rateLimiter->check(bucket) çağrısını yapar. Eğer havuz doluysa, iş ileri doğru bir gecikme ile kuyruğa bırakılır — bu bir tüketilen giriş olarak sayılmaz.
Katman 2 — Redis Lua içinde atomik kontrol ve tüketim
Sistemin kalbi. Redis içinde atomik olarak (duruma göre N çalışanı arasında yarış durumu olmadan) çalışan bir Lua betiği:
-- Her iki pencereden de süresi dolmuş girişleri temizle
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[2]) -- kısa pencere (1s)
redis.call('ZREMRANGEBYSCORE', KEYS[2], '-inf', ARGV[3]) -- uzun pencere (60s)
-- Penceredeki mevcut sayımı elde et
local short_count = redis.call('ZCARD', KEYS[1])
local long_count = redis.call('ZCARD', KEYS[2])
local max_short = tonumber(ARGV[4])
local max_long = tonumber(ARGV[5])
-- Eğer limit aşıldıysa, reddet
if short_count>=max_short or long_count>= max_long then
return {0, max_short -short_count, max_long -long_count}
end
-- Tüket: her iki pencereye de bir zaman damgası ekle
redis.call('ZADD', KEYS[1], ARGV[1], ARGV[6])
redis.call('ZADD', KEYS[2], ARGV[1], ARGV[6])
redis.call('EXPIRE', KEYS[1], 2);
redis.call('EXPIRE', KEYS[2], 62);
return {1, max_short -short_count -1, max_long -long_count -1}
Lua’nın Redis’inde neden?
- Doğası gereği atomik → Redis, betiği tek iş parçacıklı çalıştırır. Benim
checkveconsumearasındaki bir iş parçacığı başka bir slot alamaz. - Kaydırma penceresi ile Sıralı Set → her istek bir giriş olur ve süresi dolmuş olanlar sayım yapmadan önce temizlenir. Kesin, hiçbir “pencere sıfıra sıfırlanmaz” durumu yoktur.
- İki eşzamanlı pencere → kısa (saniye başına) ve uzun (dakika başına), aynı işlemde kontrol edilir.
Katman 3 — Geri Basınç üzerinde 429
Bir 429 dönerse (başka bir işlem slotu tüketti ya da limit bildirilmeden değişti), bu durumu redis anahtarında TTL ile kaydederim. O anahtar aktif olduğu sürece, katman 1 bu havuz için her şeyi reddeder.
Soğuma gerektiren havuzlar için, anahtar tüm soğuma süreleri boyunca kalır. Hiç kimse geçemez. Hürmet etmek zorundalar ya da yasaklanırsınız.
Neden 3 katman ve sadece biri değil?
- Katman 1 (ön uç) → ucuz. Boş yere bir slot yakmamak.
- Katman 2 (kontrol-tüketim) → doğru. Atomik, yarışı yok.
- Katman 3 (geri basınç) → dayanıklı. Sağlayıcı, limitleri arka planda değiştirdiğinde, 429 nihai otoritedir.
Basit bir sayıcı durumu karşılayamaz. Bu kurulum, tavanla çarpmadan ölçeği yönetir.
Özelleşmiş kuyruklar, 1 düzenleyici
Özelleşmiş kuyruklar, 1 düzenleyici
Domain’e göre kuyruk kullanırım, tek bir devasa kuyruk yerine. Her birinin belirgin bir amacı vardır:
| Kategori | Amacı | Neden ayrı? |
|---|---|---|
| İnteraktif | Gerçek zamanlı kullanıcı eylemleri (bir sihirbazla bir şey oluşturma vb.) | Senkron backlog’un arkasında bekleyemez. |
| Toplu oluşturma | Toplu işlemler (N’yi içe aktarma, bir seferde N oluşturma) | İnteraktif ile rekabet etmemesi için ayrıdır. |
| Senkran düzenleyici | Ne zaman senkronlanması gerektiğini kararlaştırır. | Senkron detay işçilerini koordine eder. |
| Senkran yapı | Hafif yapı (kök varlıkları) çeker. | Hafif, sıkça. |
| Senkran detay | Ağır detaylar (metrikler, bağımlılıklar) çeker. | Ağır, daha az sık. |
| Ağır senkran | Tarihsel sıfırlama, uzun işlemler. | Normal senkronu bloke edemez. |
| Otomasyon | Müşteri kurallarını periyodik olarak değerlendirir. | Yüksek gecikme, diğerlerini kilitlemez. |
| İzleme | Sağlık kontrolü, dış olay tespiti. | Pasif, paralel çalışır. |
| Yükleme | Sağlayıcıya dosya aktarımı. | Kısa API çağrılarıyla rekabet etmez. |
| Bürokratik akışlar | Sağlayıcıyla uzun işlemler (örneğin, itirazlar). | Acelesi yok, kendine ait bir zaman dilimi var. |
Neden tek bir dev kuyruk yerine ayırmak?
- Gecikme yalıtımı → uzun bir senkron, bir etkileşimli eylemi tutamaz.
- Doğal öncelik → etkileşimli kuyruk işçisi, işini önce alır.
- Bağımsız ölçekleme → senkron yavaşlarsa, yalnızca senkron kuyruğu için daha fazla işlem başlatırım, oluşturmayı etkilemeden.
- Doğrudan hata ayıklama → gösterge tablosu belirli bir kuyruktaki backlog’u gösterir, neyi araştıracağımı biliyorum.
Ve kuyruk yöneticisi (bu durumda Horizon) tek bir yapılandırma dosyası ile bunu yapar. Çalışanları düzenlemek için Kubernetes’e ihtiyacım yok. Redis + supervisor bunu hallediyor.
Görünürlük yığını: Laravel-first
Görünürlük yığını: Laravel-first
Zorunlu uyarı: evet, PHP. Evet, Laravel. Evet, PHP yaklaşık 20 yıldır ölü. Ne komik ki, ceset kirasını, aidatımı ve 87K R$ MRR’yi ödüyor. Devam edelim.
Grup içinde birçok kişinin Prometheus + Grafana kullandığını gördüm. Harika bir yığın, ama ben farklı bir yol seçtim:
- Laravel Pulse → uygulama metrikleri (yavaş sorgular, işler, önbellek, CPU, istekler)
- Laravel Horizon → kuyruk panosu (işlem hızı, başarısız işler, yeniden denemeler)
- Laravel Telescope → geliştirme ve test aşamasında istek/sorgu hata ayıklama.
- PostHog → ürün analitiği (funnel, özellik kullanımı)
php artisan pail→ hata ayıklarken canlı günlük izleme.
Neden Prometheus + Grafana değil?
Kötü oldukları için değil — çünkü Pulse ve Horizon, zaten çalışan aynı Redis’i kullanıyorlar. Yeni bir altyapıya ihtiyacım yok. Yeni ikili dosya yok. Yeni kurulum yapmam gereken bir ajan yok. .env dosyasında bir bayrağı açtım ve bir gösterge panelim oldu.
Bir gün, Laravel’in göremediği bir altyapı metriğine ihtiyaç duyarsam (örneğin, dış bir proxy üzerindeki ağ doygunluğu), o zaman Prometheus eklerim. Pulse, sistemin %95’ini yönettiği sürece, neden tekrar etmek zorundayım ki?
Güvenlik yığını: üç katman
Güvenlik yığını: üç katman
Güvenliği üç düzeye ayırdım: kenar, sunucu, uygulama.
Kenar (Cloudflare)
- WAF öncü (genel saldırıları kökenine ulaşmadan engeller).
- Kenar hız limiti
- Bot Savaş Modu
Sunucu (bare metal)
- UFW güvenlik duvarı — yalnızca 22/80/443 açık; MySQL dışarıdan engelli.
- Fail2ban — SSH/nginx brute force saldırılarına otomatik yasaklama.
- Nginx’de güvenlik başlıkları (HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy)
-
server_tokens off— nginx, tarayıcılara bir sürüm sunmaz. - Yalnızca TLS 1.2+, Let’s Encrypt sertifikaları.
- Kaydedilen günlüklerde bir tarayıcı belirdiğinde manuel IP yasaklama.
Uygulama (Laravel)
- Kendi hız limiti (Redis kaydırma penceresi, 3 katman).
- OAuth jetonları veritabanında şifrelenmiştir (Laravel Crypt).
- Her modelde küresel kapsam ile çoklu kiralama — bir arasındaki verileri unutma sonucu veri sızması imkansızdır.
- Dağıtımlar, hazırlanan Docker imajı ile yapılır (prod’da kod montajı yok).
Her katman, farklı türde bir saldırıyı filtreler. Cloudflare internetin gürültüsünü yakalar. UFW/Fail2ban ise geçeni yakalar. Laravel ise kimliği doğrulanmış olanların erişmeye çalıştığı şeyleri filtreler.
Ölçekleme sorunu: dış API hız limiti
Ölçekleme sorunu: dış API hız limiti
Platform büyüdükçe, darboğazımın CPU değil, veritabanı değil, bellek de olmadığını fark ettim. Sunucu her şeyi geniş marjla halletti. Darboğaz, kontrol edemediğim bir şey: TikTok’un geliştirici uygulaması başına verdiği istek kotası.
SaaS’lar, TikTok API ile entegre olurken portalında bir “uygulama” kaydettirirler. O uygulamanın saniye, dakika ve günde istek sınırı vardır. 7M/gün ve giderek büyüyor. Tavanımı çizmeye hazırdım — ve bunu yaptığınızda TikTok, 429 döner, suçsuz müşteriler dahil.
Doğru soru: veri yoğun, işlem yoğun, yoksa I/O yoğun mu?
Doğru soru: veri yoğun, işlem yoğun, yoksa I/O yoğun mu?
Mimariyi seçmeden önce doğru problemi sınıflandırmam gerekiyordu. Üç model vardır:
- İşlem yoğun → CPU/GPU bağlı (ML, kodlama, görüntü işleme). Çözüm: daha fazla makine, paralellik, GPU.
- Veri yoğun → TB’lerce veri hareket ettirme/i̇şleme (ETL, veri göleti). Çözüm: parçalama, akış, katmanlı depolama.
- I/O yoğun / ağ bağımlı → bir ağın veya dış API yanıtının beklenmesi. Çözüm: eşzamanlılık, güç değil.
Durumum I/O yoğunudur. İşçiler zamanlarının %90’ını TikTok’un yanıtını bekleyerek geçiriyorlar. Tüm sunucular birleştiğinde, nadiren %30 CPU’nun üzerine çıkıyorum. Bir veri katmanı (yapı senkronizasyonu, performans metrikleri, yaratıcılar) var ama MySQL + Redis bunu halleder.
Eğer yanlış sınıflandırsaydım ve CPU’yu büyütmem gerektiğini söyleseydim, cevabı Kubernetes olurdu. Ama sorun dış kota olduğu için, cevabım başka bir şeydir.
Neden Kubernetes değil?
Neden Kubernetes değil?
Grup sohbetinde, bana direkt “Neden k8s, pod otomatik ölçeklendirme ve monolit yedekliliği yok?” diye sordular.
Kısa cevap: K8s kaynakları benim altyapımda ölçeklendirir. Sorunum, altyapımda bir kaynak değil.
Büyüme hızına ulaşmanın yolu, yük dengeci arkasında 10 monolit pod’u çalıştırarak, tek bir TikTok uygulamasına ait limitlerin hepsiyle çerçevelenmesidir. Hız sınırım aynıdır. 429’lar da aynı olacak. K8s kurulumuna harcayacağım zaman, burada çözmediği bir sorun için açıkçası harcamış olacağım.
Üstüne, k8s başka bir araç olarak bakım konusunda en karmaşık olanıdır. Tek başıma. SRE yok. Platform ekibi yok. K8s’in işletim karmaşıklığı, burada çözeceği sorundan daha fazla.
Karar: monoliti parçala, ama yalnızca doğru kısım
Karar: monoliti parçala, ama yalnızca doğru kısım
Gerçekte ihtiyacım olan şey, TikTok API’si ile birden fazla kimlik idi. Portalda kayıtlı iki uygulama = iki bağımsız kota = tavanımı iki katına çıkarmak.
Bunun için plana, TikTok API istemcisini kendi hizmetinde izole etmek; bir uygulama kaydolduktan sonra çok fazla yük dengelemek için bir mikro hizmet olarak çalışmak var.
Planım:
- Laravel monolitini UI, kuyruklar, çoklu kiralama, faturalama, gösterge tablosu, onboarding için koruyun.
- TikTok API istemcisini özel bir mikro hizmete çıkarın.
- O mikro hizmet, TikTok ile iş için kayıtlı N uygulama arasında istekleri, mevcut kota esasına göre yönlendirir.
- Monolit o mikro hizmete, herhangi başka bir bağımlılık gibi çağırır.
Acılı kazanç: Kota tavanımı iki katına çıkarıyorum. Daha fazlasına ihtiyacım olursa, üçüncü bir uygulama kaydediyorum ve mikro hizmet şimdi 3 arka uç arasında yönlendirme yapıyor.
Neden bu görünürlüğü koruyor
Neden bu görünürlüğü koruyor
Konu hakkında önemli bulduğum bir nokta: Önceden iyi çalışan şeyleri kaybetmek istemiyorum.
- Kuyruklar Horizon’da kalıyor.
- Uygulama metrikleri Pulse’da kalıyor.
- Debugging Telescope’da kalıyor.
- Çoklu kiralama global kapsam ile kalıyor.
Mikro hizmet yalnızca TikTok API’sine akıllı bir geçit işlevi görür. Görünürlüğümü kırmaz, operasyonel acıyı çoğaltmaz, başka bir yığın öğrenmeyi zorlamaz.
Bunu yavaş yavaş parçala, hepsini bir anda değil
Bunu yavaş yavaş parçala, hepsini bir anda değil
“Monoliti mikro hizmetlere yeniden yazmak” başlangıç için en kötü kararlardan biri olabilir. Gördüğüm hemen hemen her durumda sonuçlar kötü oldu.
Yaptığım şey farklı: bir servis çıkarmak, fayda kendini ödüllendiriyorsa. Öncelikle TikTok API istemcisi, çünkü dış kota sorunu bunu haklı çıkarır. Yol boyunca başka özel bir darboğaz çıkarsa, başka birini çıkaracağım. Ama yalnızca faydası belirgin ve ölçülebilir olduğunda.
Dağıtık sistemler üzerinde çalıştım (RD’deki iş dönemim sırasında) ve öğrendiğim en pahalı ders: kendi kendini haklı çıkarmayan bir mikro hizmet, sadece bir isim etiketi olan teknik borçtur.
Sonuç
Sonuç
Kararların özeti:
- Dış kısıtlamalar mimariyi tanımlar — Cuma dağıtımları, yavaş destek, eksik belgeler ve havuz başına hız limitleri beni, idempotans, detaylı kayıtlar ve 3 katmanlı koruma için zorlar.
- Önceden sahip olduğum şeylerle görünürlük (Pulse/Horizon/Telescope) çünkü mevcut altyapıyı yeniden kullanır.
- Güvenlik üç katmanda (Cloudflare → sunucu → uygulama) çünkü her biri farklı türde bir saldırıyı filtreler.
- Monolit, mikro hizmetlerden önce çünkü tek başına bir geliştirici dağıtık sistemler işletmek için kapasiteye sahip değildir.
- Mikro hizmetler, kazanç dışarıdaysa, içeriye değil. — benim durumumda API kotaları, değil altyapı kaynakları.
- K8s yok çünkü sorun denetimimde olmayan bir kaynağı ölçeklendirmek değil.
Bu trend olan yığın değil. Platform büyürken kendi başıma sürdürebileceğim yığın. Bazen doğru çağrı sıkıcı olandır.
Her Cuma, diğer Twitter kullanıcıları tekrar PHP’nin öldüğünü ilan ederken, ben burada TikTok API’sinin bir gün ölmeyeceğini umarak oturuyorum. Şimdiye kadar, ceset galip geliyor.
Kaynak: Orijinal Makale


