Spring Boot Mikro Servis Mimarisi: Teoriden Pratiğe

Spring Boot Mikro Servis Mimarisi: Teoriden Pratiğe
Zelkulon05 Mart 20251 dk okuma

Spring Boot ile mikro servisleri yapılandırın, iletişim kurun ve güvence altına alın – gerçek kod örnekleri ve mimari diyagramlarla kapsamlı bir pratik kılavuz.

Mikroservisler Nedir?

Bir mikroservis mimarisi, bir uygulamayı küçük, bağımsız olarak dağıtılabilir servislere böler. Her servis, Domain-Driven Design'daki Bounded Context'e karşılık gelen tam olarak bir iş alanından sorumludur.

Mikroservisler Nedir?

Her servisin kendi veritabanı vardır – bu sıkı bağlamayı önler ve her servisin kendi veritabanı türünü seçmesine olanak tanır.

Proje Yapısı

order-service/
├── src/main/java/com/zelkulon/order/
│   ├── OrderServiceApplication.java
│   ├── controller/
│   │   └── OrderController.java
│   ├── service/
│   │   ├── OrderService.java
│   │   └── OrderServiceImpl.java
│   ├── repository/
│   │   └── OrderRepository.java
│   ├── model/
│   │   ├── Order.java
│   │   └── OrderItem.java
│   └── dto/
│       ├── OrderRequest.java
│       └── OrderResponse.java
└── src/main/resources/
    └── application.yml

Domain Modeli

@Entity
@Table(name = "orders")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private String id;

    private String customerId;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<OrderItem> items = new ArrayList<>();

    private BigDecimal totalAmount;

    @PrePersist
    void onCreate() {
        this.createdAt = LocalDateTime.now();
        this.status    = OrderStatus.PENDING;
    }
}

Feign ile Servisler Arası İletişim

Spring Cloud OpenFeign ile başka bir mikroservis, yerel bir servis nesnesi gibi davranır:

@FeignClient(name = "product-service", url = "${services.product.url}")
public interface ProductServiceClient {

    @GetMapping("/api/products/{productId}")
    ProductDto getProduct(@PathVariable String productId);

    @PutMapping("/api/products/{productId}/stock")
    void reduceStock(@PathVariable String productId,
                     @RequestParam int quantity);
}

Resilience4j ile Circuit Breaker

Circuit Breaker'lar, bir servis erişilemez olduğunda zincirleme arızaları önler:

@Service
public class OrderServiceImpl implements OrderService {

    @Override
    public OrderResponse placeOrder(OrderRequest request) {
        CircuitBreaker cb = circuitBreakerFactory.create("product-service");

        boolean available = cb.run(
            () -> checkProductAvailability(request.getItems()),
            throwable -> {
                log.warn("ProductService erişilemiyor – yedek aktif");
                return false;
            }
        );

        if (!available) throw new OrderException("Ürünler kullanılamıyor");
        return processOrder(request);
    }
}

Dağıtık İşlemler için Saga Deseni

Mikroservislerde global veritabanı işlemleri yoktur. Saga Deseni bu sorunu çözer:

Dağıtık İşlemler için Saga Deseni

Özet

  • Bir servis = bir iş alanı – tanrı servisi yok
  • Servis başına ayrı veritabanı, veri bağlamasını önler
  • Circuit Breaker'lar üretime hazır sistemler için zorunludur
  • API Gateway, kimlik doğrulama ve yönlendirmeyi merkezileştirir
  • Saga Deseni, dağıtık işlemler sorununu çözer
Spring Boot Mikro Servis Mimarisi: Teoriden Pratiğe