Spring boot microservices + SAGA + RabbitMQ (2024)

Blogumda bundan yıllar önce mikroservisler üzerine bir spring cloud uygulaması geliştirip detaylıca anlatmıştım. O yazı serisine bakarak, içerisinde spring cloud eureka, gateway, resilience, jwt ve mysql bulunan bir mikroservis yapısına SAGA mantığı ile bir MVC uygulamasından erişen bir yapıyı ayağa kaldırabilirsiniz. Sonrasında bu sistemin üzerine RabbitMQ entegrasyonu yapıp arka planda mail servislerini simule eden bir yapı da eklemiştim. O yazı serisine de buradan erişebilirsiniz.

Bu yazıda ise RabbitMQ ile çalışan SAGA mikroservisini 2024 yılında spring framework 'ün yeni özellikleri ile düzenledim ve detayları yazdım. Burada yazılanları anlamanız için öncelikle eski yazı serilerinde neler yaptığıma göz atmanız gerekiyor. Oradaki yapılar hala birebir geçerli. Ancak kendinize güveniyorsanız github 'dan kodları indirip bu yazıyı referans alarak çalıştırmaya çalışabilirsiniz. Güncel kodların tamamına buradan erişebilirsniz. Seçim sizin :)

Özetle mikroservis yapısı

Bu resimde de görebileceğiniz üzere bütün sistemi bir MVC uygulaması kullanıyor. Sistemin amacı bir biletleme uygulamasını servislere bölmekti. Bu yüzden adını hayali bir aldimbilet.com gibi bir domain ile düşündüm. Burada MVC uygulaması direkt olarak gateway 'in adresine gidiyor ve istekler gateway tarafından load balancer ve service registry olarak kullanılan eureka 'ya gidiyor. Eureka ise istekleri 3 farklı servise ve bunların failover 'larına yönlendiriyor. Bunlar kullanıcı servisleri, event servisleri ve ödeme servisleri. Her servis birden fazla kere ayağa kaldırılarak load balancing yapılabiliyor. Ayrıca her servis kendi veritabanına da ayrı ayrı bağlanabiliyor, farklı teknolojiler kullanabiliyor. Bu 3 servisin erişilemez olması durumunda gateway 'de resiilience4j yardımı ile failover servislerine yönlendirme yapılıyor. Daha doğrusu Eureka 'ya request 'lerin failover 'lara gitmesi gerektiği belirtiliyor. Bu sayede 404 'ler verilmek veya connection refused hatası almak yerine servis durumu ekranda yazdırılabiliyor. Config server ise bütün spring boot uygulamalarının belli property 'lerini merkezi bir yerden almasını sağlıyor. Zorunlu bir özellik değildi fakat mikroservislerde bunu da bilmekte fayda var.

Sistemin rabbitmq kısmı ise mail gönderimleri için kullanılabiliyor. Bir bilet satın alındığında veya bir event iptal edildiğinde kullanıcılara mailler gitmesi gerekiyor. Bu işlemler asenkron şekilde yapılabileceği için rabbitmq kuyruğuna atılıyor ve mailservice tarafından dinlenip işleniyor. İşlenirken hata alan mesajlar ise rabbitmq tarafında deadletter kuyruğuna atılıyor. Bu kısım zorunlu olmamakla beraber güzel bir yaklaşım bence. Bütün bu sistemi nasıl ayağa kaldıracağınızı da anlatan yarı serileri dediğim gibi mevcut. Ayağa kaldırma sırası Eureka -> Config server -> Gateway -> Diğer servisler şeklinde olmalı.

Yapılan değişiklikler

Eureka uygulamasında spring boot ve java versiyonu güncellendi. Gerisi olduğu gibi çalışabildi. Property dosyasında bazı değişiklikler yaptım ve default portu olan 8761 'de çalışmasını sağladım. Aksi takdirde servislerin bağlanmasında sorunlar yaşadım anlamadığım bir şekilde. Eureka ayağa kalktığında localhost:8761 adresinden ulaşabiliyorsunuz.

Config server uygulamasında da spring boot ve java versiyonu güncellendi. Bu kısımda eski yazımda property 'leri git tarafında tutacak şekilde ayarlamıştım. Her seferinde git 'e bağlanmak zor olabildiği için bundan vazgeçtim ve servislerin property dosyalarını direkt olarak bu projenin içine aktardım. Bu kısımda property 'lerde spring.profiles.active=native şeklinde native profilinin olması ve bu profilde başlatılacak şekilde application-native.property dosyası oluşturulması gerekiyor. Aksi takdirde git 'e bağlanmaya çalışıyor.

Gateway projesinde de spring boot ve java versiyonu güncellendi. Bu projede neredeyse hiç değişiklik olmamakla beraber eureka bağlantı bilgisi değişti. Eskiden local isimli bir profilde başlatıyordum uygulamaları fakat bunun da gereksiz olduğunu fark ettim ve bütün projelerde default ile değiştirdim.

Userservice, activityservice ve paymentservice 'de yapılanlar aynı işlemler. Üç projede de spring boot versiyonu güncellendi. Lombok çıkarıldı. Property 'ler config server 'a taşındı. Database property 'leri postgresql 'e geçirildi. Repository 'ler ise eskiden hibernate criteria api kullanıyordu şimdi JpaRepository kullanıyor ve kod gerektirmiyor. Eureka bağlantısı için de port ayarı değiştirmeyi unutmayınız. Ayrıca bu servislerin güvenlik katmanlarında yani kodlarda security config dosyalarında spring security 'nin güncellenmiş halini kullandım. Payment service rabbitmq 'ya mesaj gönderen uygulama ama o kısımda bir değişiklik yok.

Userservice, activityservice ve paymentservice failover versiyonlarında neredeyse hiç değişiklik yok gibi. Sadece java ve spring boot versiyonları güncellendi ve eureka konfigürasyonu değiştirildi. Property 'ler zaten config server 'a taşınmıştı.

Son olarak MVC uygulamasında thymeleaf sayfalarında küçük değişiklikler oldu. Tabi ki jave ve spring boot versiyonu güncellendi. Bu uygulamada failover servislerine gidilirse 503 cevabı geliyor ve FeignException olarak yakalayabiliyor. Bu sayede lütfen bekleyiniz sistemler devre dışında şeklinde bir uyarı verebiliyorsunuz. FeignException yakalamak önemli çünkü MVC uygulaması OpenFeign ile bağlanıyor. Bu uygulamayı kullanmak için biraz kurcalamanız gerekecektir çünkü ortalık biraz karmaşık :D Önce login yapın, sonra activities sayfasından bilet almaya çalışın.

Mailservice ise eski hali ile birebir aynı çalışıyor. Bu servis rabbitmq 'dan mesajları alıp mail gönderimini simule eden basit bir servis. Bir yerde bean oluşturup private yapmışım yanlışlıkla :D O yüzden kodun güncel halini alıp çalıştırın derim direkt olarak. Tabi ki java ve spring boot versiyonunu da güncelledim bu uygulamanın.

Güncel mikroservisimiz hazır

Bu şekilde eski bir projeyi daha necromencer gibi canlandırdım. 2024 yılında da o zamanlar yazdığım kodların çoğunun çalışabiliyor olması beni sevindirdi. Her ne kadar eski kodlar olsa da önce eski yazı dizisine göz atmanızı ve detaylı okumanızı tavsiye ederim. Sonrasında burada yazdığım değişiklikleri hayata geçirebilirsiniz. Veya güncel kodları alıp eski yazılardan referans alarak çalıştırmaya çalışabilirsiniz. Sistemi tekrar sıfırdan anlatma ihtiyacı bulunmuyor çünkü o zamanlar yaptığım tasarımı değiştirmeden sadece kodları güncelledim. Sizlere kolaylıklar dilerim. Bir sonraki yazıda görüşmek üzere :)


Bir yorum yazabilirsiniz