Monolitten Mikro Hizmetlere
Neleri ayıracağınıza ve hizmet sınırlarını nasıl çizeceğinize karar verin.
Monolitten Mikro Hizmetlere, CoddyKit'te ücretsiz bir PHP Academy dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, PHP Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. PHP Academy kursu toplamda 4 dersten oluşur.
Monolitten Mikroservislere
Mikroservisler varsayılan bir seçenek değil, kurumsal ve operasyonel bir tercihtir. Bir PHP monolitini bölmek, işlem içi basitliğin yerine ağ çağrılarını, dağıtık veriyi ve dağıtım karmaşıklığını getirir. Yanlış gerekçelerle yapıldığında her şeyi yavaşlatır.
Bu ders en zor kısma odaklanır: hizmet sınırlarını çizmek. Sınırları doğru belirlerseniz geriye altyapı işleri kalır; yanlış belirlerseniz dağıtık bir monolit kurarsınız — tüm maliyet, hiçbir fayda yok.
Neden Bölmeli (ve Neden Bölmemeli)
Bölmek için iyi gerekçeler:
- Bağımsız dağıtılabilirlik ve ekip sahipliği.
- Yoğun kullanılan alt sistemleri bağımsız ölçeklendirebilme.
- Teknoloji/çalışma zamanı yalıtımı ve hataların sınırlandırılması.
Kötü gerekçeler: "kod karmaşık" (önce monoliti yeniden düzenleyin) veya bir akımın peşinden gitmek. İki hizmet her zaman birlikte dağıtılmak zorundaysa ya da bir veritabanı tablosunu paylaşıyorsa, bunlar iki şapka takan tek bir hizmettir.
Sınırlı Bağlamlar
Alan Odaklı Tasarım, sınırları belirlemek için en keskin aracı sunar: sınırlı bağlam. Bir bağlam içinde terimlerin tek ve kesin bir anlamı vardır. Faturalama alanındaki "Müşteri" (fatura muhatabı), Destek alanındaki "Müşteri"den (talebi oluşturan kişi) farklıdır.
Her sınırlı bağlam bir hizmet için güçlü bir adaydır. Sınırlar, iş dilini ve kuruluşun gerçekte nasıl iletişim kurduğunu izler — Conway Yasası iş başındadır.
Yüksek Uyum, Düşük Bağımlılık
İyi bir hizmet sınırı, birlikte değişen şeyleri içeride tutar ve bağımsız olarak değişen şeyleri dışarı iter. Önerilen bir bölmeyi şu ölçütlerle değerlendirin:
- Kaç özellik aynı anda iki hizmete birden dokunmayı gerektiriyor? (Az olmalıdır.)
- Aralarındaki çağrı düzeni ne kadar geveze? (Çağrılar kaba taneli olmalıdır.)
Tek bir özelliği uygulamak sürekli olarak bir sınırın iki tarafına taşıyorsa sınır yanlış yerdedir.
<?php
// Chatty boundary smell: N network calls to render one view
foreach ($order->lineItems as $item) {
$product = $catalogApi->get($item->productId); // one call PER item!
$names[] = $product['name'];
}
// Coarse-grained: one batch call across the boundary
$ids = array_map(fn($i) => $i->productId, $order->lineItems);
$names = $catalogApi->getMany($ids); // single round-trip
echo count($names) . " products in one call\n";Hizmet Başına Veritabanı
Tartışmasız kural şudur: her hizmet kendi verisinin sahibidir ve başka hiçbir hizmet onun tablolarına dokunmaz. Paylaşılan veritabanları, kaçmak için ayırdığınız bağımlılığı yeniden oluşturur — bir şema değişikliği ilgisiz hizmetleri bozar.
Bu, monolitte bir SQL JOIN olan hizmetler arası sorguların API çağrılarına veya çoğaltılmış okuma modellerine dönüşmesi anlamına gelir. Bedeli budur ve amaç da budur.
<?php
// In the monolith: one JOIN across domains
$sql = 'SELECT o.id, c.email
FROM orders o JOIN customers c ON c.id = o.customer_id';
// After split: Orders service holds only the foreign id;
// it asks the Customers service for the rest (or keeps a local read model).
$order = $orderRepo->find($id); // local
$customer = $customersApi->get($order->customerId); // network call
echo $order->id . ' / ' . $customer->email . "\n";Boğucu İncir Deseni
Bir monoliti asla tek seferde yeniden yazmayın. Boğucu incir deseni, kademeli olarak çıkarma yapar: trafiğin bir bölümünü bir cephe/vekil sunucu üzerinden yeni bir hizmete yönlendirin, onu büyütün ve eski kod yolunu yalnızca yeni yol tamamen kapsadığında kullanımdan kaldırın.
Bir ters vekil sunucu (veya API ağ geçidi) önde durur ve her rota için eski monolite mi yoksa yeni hizmete mi gidileceğine karar verir. Geçiş, her seferinde bir yetenek olacak şekilde ve her zaman dağıtıma hazır biçimde ilerler.
<?php
// Facade routing: peel off one capability at a time
function route(string $path): string {
$migrated = ['/invoices', '/invoices/pdf']; // moved to billing-svc
foreach ($migrated as $prefix) {
if (str_starts_with($path, $prefix)) {
return 'http://billing-svc' . $path;
}
}
return 'http://legacy-monolith' . $path; // everything else, for now
}
echo route('/invoices/pdf'), "\n";
echo route('/users/42'), "\n";Modül Çıkarma
Uygulanabilir bir çıkarma sırası:
- Gelen bağımlılıkları az ve veri sahipliği net olan bir modül bulun.
- Önce monolitteki işlem içi çağrılarını bir arayüzün arkasına alın.
- Sahip olduğu verileri kendi şemasına/veritabanına taşıyın.
- Arayüz uygulamasını bir ağ istemcisiyle değiştirin.
- Cephe üzerinden trafiği yeni yola geçirin; eski kodu silin.
Önce monolitin içinde arayüz sarmalama işlemini yapmak, ağ adımının riskini azaltır.
<?php
// Step 2: hide the implementation behind a port the monolith calls
interface InvoiceService {
public function generate(string $orderId): string; // returns invoice id
}
// Today: local class. Tomorrow: HTTP client to billing-svc.
// The monolith's calling code never changes.
final class LocalInvoiceService implements InvoiceService {
public function generate(string $orderId): string { return 'inv-1'; }
}Dağıtık Veri Tutarlılığı
Veri bölündüğünde hizmetler arası ACID işlemlerini kaybedersiniz. Nihai tutarlılığı benimseyin: hizmetler kendi verileri hakkında olaylar yayımlar, diğerleri de bu olaylardan yerel okuma modelleri oluşturur.
Siparişler hizmeti her istekte Müşteriler hizmetini sorgulamaz — CustomerUpdated olaylarıyla güncellenen, yalnızca ihtiyaç duyduğu alanları içeren küçük bir yansıtım tutar. Böylece çalışma zamanı bağımlılığı ve bir gecikme adımı ortadan kalkar.
<?php
// Orders service keeps a tiny local projection of customer data
function onCustomerUpdated(PDO $db, array $evt): void {
$db->prepare(
'INSERT INTO customer_read_model (id, email)
VALUES (:id, :email)
ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email'
)->execute(['id' => $evt['id'], 'email' => $evt['email']]);
}Operasyonel Gerçeklik
Mikroservisler karmaşıklığı koddan operasyonlara taşır. Bölmeden önce şunlara ihtiyacınız vardır:
- Merkezi günlükleme ve dağıtık izleme (geçişler boyunca ilişkilendirme kimlikleri).
- Hizmet başına CI/CD ve bağımsız, sürümlü dağıtımlar.
- Her çağrıda sağlık denetimleri, zaman aşımları, yeniden denemeler ve devre kesiciler.
- Bir sağlayıcının tüketiciyi sessizce bozamaması için sözleşme testleri.
Ekip bir hizmeti iyi işletemiyorsa on hizmet bunun on kat daha kötü hâlidir.
Hizmetleri Doğru Boyutlandırma
"Mikro" yanıltıcıdır — hizmetleri kod satırlarına göre değil, iş yetkinliğine ve ekip sahipliğine göre boyutlandırın. Fazla ince taneli olursa (nano hizmetler) tek bir özellik bir ağ çağrıları fırtınasına yayılır; fazla kaba olursa yeniden monolite dönersiniz.
Sağlıklı bir ölçüt şudur: Bir hizmet tek bir ekip tarafından sahiplenilebilmeli, kendi başına dağıtılabilmeli ve birçok eş hizmet üzerinden eşzamanlı bir zincir oluşturmadan temel kullanım senaryolarını karşılayabilmelidir.
Modüler Monolit Alternatifi
Dağıtık yapıya geçmeden önce modüler monoliti değerlendirin: tek bir dağıtılabilir uygulama, ancak içeride açık sınırlara ve kendi şemalarına sahip modüllere ayrılmış; yalnızca yayımlanmış arayüzler üzerinden iletişim kuruyor ve modüller arası tablo erişimine izin vermiyor.
Dağıtık sistem maliyetine katlanmadan temiz sınırlar ve kolay yeniden düzenleme elde edersiniz. Bir modül gerçekten bağımsız ölçeklendirmeye veya sahipliğe ihtiyaç duyduğunda, boğucu incir deseniyle dışarı çıkarılmaya zaten hazırdır. Çoğu ekip için doğru ilk durak budur.
<?php
// Modules talk only through interfaces, never each other's tables.
namespace App\Billing; // owns billing_* tables
interface BillingFacade {
public function invoiceForOrder(string $orderId): string;
}
namespace App\Sales; // owns sales_* tables
final class Checkout {
public function __construct(private \App\Billing\BillingFacade $billing) {}
// Sales never SELECTs from billing_* directly - only via the facade.
}Hızlı Kontrol
Kötü bir bölmeyi tanıma.
Özet
Hizmet sınırlarını iyi çizmek:
- Kodu karmaşık olduğu için değil, dağıtılabilirlik, ölçeklendirme ve sahiplik için bölün.
- Sınırları sınırlı bağlamlarla hizalayın; yüksek uyumu ve düşük bağımlılığı hedefleyin.
- Hizmet başına veritabanı kullanın — paylaşılan tablolar olmasın; JOIN işlemlerini API'lerle veya okuma modelleriyle değiştirin.
- Boğucu incir deseniyle kademeli geçiş yapın.
- Nihai tutarlılığı kabul edin ve dışa doğru ölçeklendirmeden önce operasyonlara yatırım yapın.
Sırada: Bu hizmetlerin gerçekte nasıl iletişim kurduğu — REST ve gRPC.
Sıkça Sorulan Sorular
“Monolitten Mikro Hizmetlere” dersi ücretsiz mi?
Evet — “Monolitten Mikro Hizmetlere” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve PHP Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. PHP Academy kursu toplamda 4 dersten oluşur.
“Monolitten Mikro Hizmetlere” dersinde ne öğreneceğim?
Neleri ayıracağınıza ve hizmet sınırlarını nasıl çizeceğinize karar verin. PHP Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
PHP Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te PHP Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.
“Monolitten Mikro Hizmetlere” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu PHP Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her PHP Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Monolitten Mikro Hizmetlere
- Hizmet İletişimi: REST ve gRPC
- API Ağ Geçitleri ve Hizmet Keşfi
- Dayanıklılık: Devre Kesiciler ve Yeniden Denemeler