Microservices Mimarisi: Modern Uygulama Geliştirme
Microservices mimarisi, büyük ve karmaşık uygulamaları küçük, bağımsız servislere bölerek yönetmeyi sağlayan modern bir yaklaşımdır.
Microservices Nedir?
Microservices, tek bir uygulamayı küçük, bağımsız servislere bölen bir mimari yaklaşımdır. Her servis kendi iş mantığını yürütür ve diğer servislerle API'lar aracılığıyla iletişim kurar.
Temel Özellikler
- Bağımsızlık: Her servis bağımsız olarak geliştirilebilir ve deploy edilebilir
- Tek Sorumluluk: Her servis belirli bir iş fonksiyonuna odaklanır
- Teknoloji Çeşitliliği: Farklı servisler farklı teknolojiler kullanabilir
- Ölçeklenebilirlik: Servisler bağımsız olarak ölçeklendirilebilir
Monolith vs Microservices
Monolith Avantajları
- Basit geliştirme ve deployment
- Düşük network overhead
- Kolay debugging
Monolith Dezavantajları
- Tek nokta arızası
- Teknoloji kilidi
- Ölçeklendirme zorluğu
Microservices Avantajları
- Yüksek erişilebilirlik
- Teknoloji esnekliği
- Bağımsız ölçeklendirme
Microservices Dezavantajları
- Karmaşık network yapısı
- Distributed system zorlukları
- Operational overhead
Microservices Tasarım Prensipleri
1. Domain-Driven Design (DDD)
// User Service - Domain Model
@Entity
public class User {
@Id
private String id;
private String email;
private String name;
// Domain logic
public boolean isActive() {
return status == UserStatus.ACTIVE;
}
}
2. API Gateway Pattern
# API Gateway Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-gateway
spec:
rules:
- host: api.example.com
http:
paths:
- path: /users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 80
3. Service Discovery
# Service Discovery with Consul
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: user-service
instance-id: ${spring.application.name}:${random.value}
Communication Patterns
Synchronous Communication
// REST API Client
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate;
public User getUser(String userId) {
return restTemplate.getForObject(
"http://user-service/users/" + userId,
User.class
);
}
}
Asynchronous Communication
// Event-Driven Communication
@Component
public class OrderEventHandler {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
// Process order creation
notificationService.sendNotification(event.getUserId());
}
}
Data Management
Database per Service
-- User Service Database
CREATE TABLE users (
id VARCHAR(36) PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Order Service Database
CREATE TABLE orders (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(50) NOT NULL
);
Saga Pattern
// Saga Coordinator
@Component
public class OrderSaga {
public void createOrder(OrderRequest request) {
// Step 1: Create Order
Order order = orderService.createOrder(request);
// Step 2: Reserve Inventory
inventoryService.reserveInventory(order.getItems());
// Step 3: Process Payment
paymentService.processPayment(order.getPaymentInfo());
// Step 4: Confirm Order
orderService.confirmOrder(order.getId());
}
}
Deployment Strategies
Blue-Green Deployment
# Blue-Green Deployment with Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service-blue
spec:
replicas: 3
selector:
matchLabels:
app: user-service
version: blue
template:
metadata:
labels:
app: user-service
version: blue
spec:
containers:
- name: user-service
image: user-service:v1.0
Canary Deployment
# Canary Deployment
apiVersion: networking.k8s.io/v1
kind: VirtualService
metadata:
name: user-service
spec:
hosts:
- user-service
http:
- route:
- destination:
host: user-service
subset: v1
weight: 90
- destination:
host: user-service
subset: v2
weight: 10
Monitoring ve Observability
Distributed Tracing
// Jaeger Integration
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
@Bean
public Sampler defaultSampler() {
return Sampler.ALWAYS_SAMPLE;
}
}
Health Checks
@Component
public class UserServiceHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
// Check database connection
userRepository.count();
return Health.up().build();
} catch (Exception e) {
return Health.down()
.withException(e)
.build();
}
}
}
Best Practices
1. Service Granularity
- Çok küçük servislerden kaçının
- Domain sınırlarına göre bölün
- İş mantığına odaklanın
2. API Design
- RESTful API standartlarını takip edin
- Versioning stratejisi belirleyin
- Documentation'ı güncel tutun
3. Security
- Service-to-service authentication
- API Gateway'de rate limiting
- Input validation ve sanitization
4. Testing
- Unit tests for each service
- Integration tests for service interactions
- End-to-end tests for complete workflows
Sonuç
Microservices mimarisi, modern uygulama geliştirme için güçlü bir yaklaşımdır. Ancak doğru tasarım, implementasyon ve operasyonel süreçler gerektirir. Başarılı bir microservices implementasyonu için domain-driven design, service discovery, monitoring ve testing stratejilerine odaklanın.
Önerilen Araçlar
- API Gateway: Kong, AWS API Gateway, Azure API Management
- Service Discovery: Consul, Eureka, etcd
- Monitoring: Prometheus, Grafana, Jaeger
- Message Broker: RabbitMQ, Apache Kafka, Redis
- Container Orchestration: Kubernetes, Docker Swarm