Bu ders için video bulunmamaktadır.
Ders İçeriği
Giriş: Mikroservis Mimarisi ve Ölçeklenebilirlik
Modern yazılım geliştirme dünyasında, uygulamaların karmaşıklığı ve kullanıcı beklentileri sürekli artmaktadır. Bu durum, geleneksel monolitik mimarilerin yerini daha esnek, ölçeklenebilir ve yönetilebilir mimarilere bırakmasına neden olmuştur. Mikroservis Mimarisi, bu yeni yaklaşımlardan biridir. Uygulamayı küçük, bağımsız servisler halinde bölerek geliştirme, dağıtım ve ölçekleme süreçlerini kolaylaştırır. Ölçeklenebilirlik (Scalability) ise, bir sistemin artan iş yükünü veya kullanıcı sayısını sorunsuz bir şekilde kaldırabilme yeteneğidir.
Mikroservis Mimarisi Nedir?
Mikroservis mimarisi, bir uygulamanın tek bir büyük, monolitik birim yerine, küçük, bağımsız ve gevşek bağlı servisler koleksiyonu olarak geliştirildiği bir yaklaşımdır. Her servis, belirli bir iş alanına odaklanır ve kendi veritabanına sahip olabilir. Servisler genellikle hafif iletişim mekanizmaları (HTTP/REST, gRPC, mesaj kuyrukları) aracılığıyla birbirleriyle iletişim kurar.
Monolitik vs Mikroservisler
Aşağıdaki tablo, monolitik ve mikroservis mimarilerinin temel karşılaştırmasını sunmaktadır:
Özellik | Monolitik Mimari | Mikroservis Mimarisi |
---|---|---|
Yapı | Tek, büyük, sıkı bağlı birim | Küçük, bağımsız, gevşek bağlı servisler |
Geliştirme | Tek bir kod tabanı, tüm ekip üzerinde çalışır | Küçük, bağımsız ekipler, kendi servisleri üzerinde çalışır |
Dağıtım | Tüm uygulamanın yeniden dağıtılması gerekir | Bağımsız servisler ayrı ayrı dağıtılabilir |
Ölçekleme | Tüm uygulamanın ölçeklenmesi gerekir | Servisler bağımsız olarak ölçeklenebilir |
Teknoloji Seçimi | Genellikle tek bir teknoloji yığını | Her servis için farklı teknolojiler kullanılabilir |
Hata Yalıtımı | Bir bileşendeki hata tüm uygulamayı etkileyebilir | Bir servisteki hata diğer servisleri etkilemez |
Servisler Arası İletişim
Mikroservisler, birbirleriyle iletişim kurmak zorundadır. Bu iletişim için çeşitli yöntemler kullanılabilir:
REST (Representational State Transfer)
En yaygın iletişim yöntemidir. HTTP protokolü üzerinden JSON veya XML formatında veri alışverişi yapılır. Basit ve anlaşılırdır.
// Kullanıcı Servisi (User Service)
const express = require("express");
const app = express();
app.use(express.json());
const users = [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }];
app.get("/users/:id", (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (user) {
res.json(user);
} else {
res.status(404).send("Kullanıcı bulunamadı");
}
});
app.listen(3001, () => console.log("Kullanıcı Servisi 3001 portunda çalışıyor"));
// Sipariş Servisi (Order Service) - Kullanıcı Servisi ile iletişim kuruyor
const express = require("express");
const axios = require("axios");
const app = express();
app.use(express.json());
app.get("/orders/:userId", async (req, res) => {
try {
const userId = req.params.userId;
const userResponse = await axios.get(`http://localhost:3001/users/${userId}`);
const user = userResponse.data;
// Örnek sipariş verisi
const orders = [
{ id: 101, userId: 1, item: "Laptop" },
{ id: 102, userId: 2, item: "Mouse" }
];
const userOrders = orders.filter(order => order.userId === parseInt(userId));
res.json({ user, orders: userOrders });
} catch (error) {
res.status(500).send("Sipariş alınamadı: " + error.message);
}
});
app.listen(3002, () => console.log("Sipariş Servisi 3002 portunda çalışıyor"));
gRPC
gRPC, Google tarafından geliştirilen, yüksek performanslı, açık kaynaklı bir RPC (Remote Procedure Call) frameworküdür. Protocol Buffers kullanarak veri serileştirmesi yapar ve HTTP/2 üzerinde çalışır. REST API'lere göre daha hızlı ve daha verimli olabilir.
Mesaj Kuyrukları (Message Queues)
Asenkron iletişim için kullanılır. Servisler doğrudan birbirleriyle iletişim kurmak yerine, mesajları bir kuyruğa gönderir ve diğer servisler bu kuyruktan mesajları tüketir. RabbitMQ, Kafka gibi araçlar kullanılır. Bu, servisler arasında gevşek bağlılık sağlar ve hata toleransını artırır.
API Gateway
API Gateway, istemcilerden gelen tüm API isteklerini tek bir giriş noktasından yöneten bir servistir. İstekleri uygun mikroservislere yönlendirir, kimlik doğrulama, yetkilendirme, hız sınırlama, önbellekleme gibi çapraz kesen endişeleri (cross-cutting concerns) ele alır.
Veri Tutarlılığı ve Saga Pattern
Mikroservis mimarisinde, her servisin kendi veritabanına sahip olması, dağıtık işlemlerin veri tutarlılığını sağlamayı zorlaştırır. Saga Pattern, dağıtık işlemlerde veri tutarlılığını sağlamak için kullanılan bir modeldir. Bir işlemi, her biri kendi yerel veritabanı işlemini gerçekleştiren ve bir sonraki adımı tetikleyen bir dizi yerel işlem olarak böler. Bir adım başarısız olursa, telafi edici işlemler (compensating transactions) önceki adımları geri alır.
Ölçeklenebilirlik Stratejileri
Uygulamanızın artan yüke dayanabilmesi için çeşitli ölçeklenebilirlik stratejileri vardır:
Yatay Ölçekleme (Horizontal Scaling)
Uygulamanın birden fazla sunucuya veya örneğe dağıtılmasıdır. Yük dengeleyici (Load Balancer) ile gelen istekler bu örneklere dağıtılır. Node.js, tek iş parçacıklı yapısı nedeniyle yatay ölçekleme için idealdir. PM2 gibi araçlar, aynı sunucu üzerinde birden fazla Node.js örneği çalıştırmanıza olanak tanır.
pm2 start app.js -i max # CPU çekirdeği sayısı kadar örnek başlatır
Dikey Ölçekleme (Vertical Scaling)
Mevcut sunucunun kaynaklarını (CPU, RAM) artırarak uygulamanın performansını iyileştirmektir. Genellikle daha pahalıdır ve bir sınıra sahiptir.
Yük Dengeleme (Load Balancing)
Yük dengeleme, gelen ağ trafiğini birden fazla sunucuya veya kaynağa dağıtma işlemidir. Bu, uygulamanın performansını, güvenilirliğini ve kullanılabilirliğini artırır. Nginx, HAProxy, AWS ELB gibi araçlar kullanılır.
Pratik Alıştırma: Basit Bir Mikroservis Uygulaması Taslağı
Basit bir mikroservis uygulaması taslağı oluşturun. İki farklı Node.js servisi (örneğin, bir Kullanıcı Servisi ve bir Ürün Servisi) tanımlayın ve bu servislerin HTTP/REST üzerinden birbirleriyle iletişim kurmasını sağlayın.
- `user-service.js` adında bir dosya oluşturun. Bu servis, kullanıcı bilgilerini (örneğin, ID ve isim) tutacak ve GET isteğiyle kullanıcı ID'sine göre bilgi döndürecektir.
- `product-service.js` adında bir dosya oluşturun. Bu servis, ürün bilgilerini (örneğin, ID, isim ve fiyat) tutacak ve GET isteğiyle ürün ID'sine göre bilgi döndürecektir.
- `product-service.js` içinde, bir ürün isteği geldiğinde, ilgili kullanıcının bilgilerini almak için `user-service.js`'e HTTP isteği gönderin.
- Her iki servisi de farklı portlarda çalıştırın (örneğin, 3001 ve 3002).