Monolitik bir mimariden mikroservis bir mimariye geçiş serüveninizde, yeni yapınız üzerinde uygulayabilme ihtimaliniz olan onlarca kötü çözüm (anti-pattern) olabilir. Aşağıda sunacağım maddelere bakarak, bu serüvende kaçınmanız gereken veya uygulamanız gereken şeyleri belirleyebilirsiniz. Zaten mikroservis mimarisine geçtiyseniz veya mikroservis mimarisi ile ürününüze başladıysanız maddeleri inceleyerek ‘neleri hatalı, neleri doğru yapıyorsunuz’ bunun analizini de yapabilirsiniz.
Anti-pattern’lar teknik olabildiği gibi, strateji, süreç veya organizasyon konularında da olabilir. Aslında onlarca anti-pattern vardır, ancak bu makalede en genel olanları sizlere sunuyor olacağım. (Makalede uluslararası jargonu, yani anti-pattern ifadesini kullanacağım. Türkçesini kötü çözüm veya hatalı kullanım olarak düşünebilirsiniz.)
Mikroservis yapısına geçmenin, bir sihir gibi tüm geliştirme sorunlarını çözeceğine inanmak.
Mikroservis mimarisine geçince tüm sorunlarınız çözülmeyecek, hatta mikroservis mimarisi uyguladığınız için başka çözmeniz gereken sorunlarla da karşılaşacaksınız. Ancak, pazarda ürününüzü avantajlı konuma getirme hedefiniz varsa, mikroservis mimarisi bu hedefin önündeki birçok engeli kaldıracaktır. Bu engellerin çoğu teknik olmakla beraber, mimarinin dokunduğu süreçsel ve organizasyonel sıkıntılarınızın bir kısmı da çözülebilir.
Mikroservis mimarisine ihtiyaç yokken, herkes yapıyor diye ve bir heves uğruna mikroservis dönüşümü yapmak.
Tüm ürünlerin mikroservis mimarisi ile kurgulanması gibi bir zorunluluk yoktur. En iyi mimari, ürünü en hızlı canlıya çıkartan, ürün bakımının en iyi yapılabildiği, ürün geliştirme verimliliğinin en yüksek olduğu ve ürün yaşam döngüsünde ürünün yaşamasına çok bir engel çıkartmayan mimaridir. Ürününüzün içeriğine göre bu mimari monolitik mimari de olabilir. Yani mikroservis mimarisinin size uyup uymayacağı şirket ve ürün stratejinizle çok ilgilidir. Bu konunun detaylarını şu makalemden okuyabilirsiniz. Unutmayın aşağıdaki meşhur kitapta da geçtiği gibi, gideceğiniz yer kafanızda net değilse, hangi yoldan gittiğinizin de bir önemi yoktur.
“Alice: Would you tell me, please, which way I ought to go from here?
The Cheshire Cat: That depends a good deal on where you want to get to.
Alice: I don’t much care where.
The Cheshire Cat: Then it doesn’t much matter which way you go.
Alice: …So long as I get somewhere.
The Cheshire Cat: Oh, you’re sure to do that, if only you walk long enough.”
― Lewis Carroll, Alice in Wonderland
Mikroservis dönüşümü yapılırken, proje başarı hedefi olarak ulaşılan mikroservis sayısını koymak.
Takımlar, ne kadar çok mikroservis yaparlarsa o kadar başarılı olacaklarını düşünüp, ihtiyaç değilken bile her bir küçük fonksiyonaliteyi mikroservis yaparlarsa, ortaya karmaşık, bakımı yapılamayan, birbirleriyle haberleşmekte bile zorlanan bir servisler topluluğu çıkacaktır.
Mikroservis’lere karar verirken Domain Driven Design yöntemi ile monolitik sistem üzerinde decomposition yapılmalı ve neyin mikroservis olması neyin olmaması gerektiğine çok iyi karar verilmelidir. Ayrıca monolitik bir mimarinin mikroservis mimarisine dönüşümüne başlar başlamaz onlarca mikroservisi aynı anda oluşturmak daha sonra gereksiz bölme ve birleştirme işlemlerine neden olabilir. Bunun yerine, yavaş yavaş ve sistemin en müsait noktasını seçerek, iteratif bir şekilde mikroservis dönüşümüne başlamalısınız.
Birden çok uygulama geliştirme ekibinin, herhangi bir koordinasyon olmadan mikroservis mimarisini kendi içinde uygulamaya çalışması.
Mikroservis dönüşümü için kurulan takımların birbirinden habersiz bir şekilde aynı konuları tekrar tekrar çözümlemesi ciddi vakit kaybı yaşatacaktır. Mikroservis mimarisinde hiç altyapı, ortak kütüphane veya ortak kod geliştirme yaklaşımları olmaz diyemeyiz. Ekipler belli bir oranda ortak kütüphaneler, kod geliştirme yaklaşımları veya tasarım desenleri ile desteklenmelidir. Özellikle Logging, DB Access ve Service Communications gibi dikey ve direkt business value üretmeyen konularda. Workflow, yani BPM de yine merkezi olarak yönetilmesi istenilen bir konu olabilir. Eğer dönüşümü iyi bir mimari ekip koordine ediyorsa işleri hızlandırmak adına ortak bir proje şablonu (template) belirleyip dönüşüm ekiplerine dağıtmaları çok faydalı olacaktır.
Tabi bir hatalı yaklaşımdan diğer bir hatalı yaklaşıma düşmemek lazım. Eğer merkezde tüm servislerin kullandığı bir altyapı projesi oluşturup bir ekibin bunu sürekli diğer ekiplere dağıtması gibi bir süreç kurduysanız bu da ayrı bir anti-pattern’dir.
Ayrıca CI/CD için her takımın kendi sistemini kurması veya aracını satın alması ya da hiçbir araç kullanmaması da ciddi bir kayıp olacaktır. Bir öncü takım gerekli derleme, pipeline, code review ve yaygınlaştırma gibi süreçleri oturtup diğer takımlara sunabilir.
Temiz kod, nesne odaklı tasarım ve otomatik test gibi temel yazılım geliştirme tekniklerini uygulamadan veya taahhüt etmeden mikroservis mimarisini benimsemeye çalışmak.
Mikroservis mimarisi sadece var olan monolitik mimariyi 100’e bölmek değildir. Bu mimarinin düzgün uygulanabilmesi için birbirinden bağımsız çalışan onlarca takımın belli bir disiplin içerisinde geliştirme yaptıklarından da emin olmalısınız. Takımlar bağımsız diye iç düzenlerini karmaşa ve kaos ile kurgularsa zincirin diğer halkaları da kısa sürede etkilenecek ve kaos bir virüs gibi tüm organizasyona yayılacaktır. Bu nedenle takımların temiz kod yazdıklarından, code-review yaptıklarından, nesne odaklı tasarım yaptıklarından, otomasyonu ciddiye alarak belli yerleri otomasyon ile kurguladıklarından ve temel proje template’lerini uyguladıklarından emin olmanız, sağlıklı bir mikroservis mimarinizin ve bu mimariyi geliştiren düzgün ekiplerinizin olduğundan emin olmanızı sağlar.
Monolitik uygulamalar geliştirirken kullanılan geliştirme sürecini, politikaları ve organizasyon yapısını mikroservis yapısında da korumak.
Mikroservis dönüşümünde hala silo yapılarınız varsa, kendi kendine organize olabilen takımlar oluşturmadıysanız, agile prensiplere göre geliştirme yapmıyorsanız, manuel test yapmaya devam ediyorsanız, ayda 1 ve geceleri deployment yapmaya devam ediyorsanız veya edecekseniz, bunlar çok hatalı uygulamalar olacaktır. Mikroservis dönüşümünü fırsata çevirip organizasyonel bir dönüşüme de girmeniz gerekebilir. Bu tür konular iş birimleri tarafından gereksiz eforlar olarak görünebileceği için arkanızda iyi bir sponsor da bulunmak zorundadır.
Mikroservis mimarisine geçişte teknoloji ve DevOps tarafını daha fazla önemsemek ve dönüşüm için gerekli olan Domain Driven Design (DDD) gibi domain’leri yeniden yapılandıran teknikleri ihmal etmek.
Yeni teknolojiler her zaman çekicidir. IT insanları hep son teknolojiler ile geliştirme yapmak ister. Ancak şu var ki mikroservis dönüşümünde, özellikle ilk zamanlarda, ihtiyaç kadar bir sistem kurmalısınız. Daha sonra dönüşüm ilerledikçe yeni ihtiyaçlara göre altyapınızı geliştirip mimarinizi mükemmelleştirecek teknolojileri yavaş yavaş entegre edebilirsiniz. Örneğin; daha başlar başlamaz gRPC ile bir sistem kurmayabilirsiniz. Bunun yerine klasik REST çağrıları ile ilerleyebilirsiniz.
Mikroservis dönüşümünde teknoloji kadar önemli olan şey decomposition’dır. Yani Domain Driven Design (DDD) ile eski monolitik yapınızı nasıl mikroservislere parçalayacağınızın çalışmasıdır. Bu çalışmanın çok dikkatli ve güzel bir şekilde yapılması gerekir. Ne çok büyük mikroservisler ne de çok küçük mikroservisler yapmamalısınız ve birbirinden mümkün olduğunca bağımsız mikroservisler tasarlamalısınız. Mikroservisler bağımsız bir şekilde geliştirilebilmeli, yaygınlaştırılabilmeli, ölçeklenebilmeli ve bakımı yapılabilmelidir.
Mikroservis mimarisini kurgularken mikroservisleri çok küçük veya çok büyük tasarlamak.
Bir önceki maddede bahsettiğimiz gibi DDD çok önemlidir. DDD ile mikroservislerin boyutuna karar vermelisiniz. Eğer kocaman mikroservisler yaparsanız monolitik’teki sorunlar aynen geçerli olur. Küçücük yaparsanız ortaya çok karmaşık bir yapı çıkar. Servisler durmadan başka servislerden veri toplayıp birleştiriyorsa bazı servisler birleştirilmelidir. Ayrıca takım organizasyonunuz mikroservisleri sahiplenecek şekilde kurgulanmalı, bir mikroservisten birden çok takım sorumlu olmamalıdır. Şu yazımda bu konunun detaylarını bulabilirsiniz.
Çok fazla teknoloji kullanmak.
Her ne kadar takımlar için teknolojik bağımsızlık önemli olsa da kurum içerisinde bir teknoloji takibi yapılmalı ve teknoloji envanteri tutulmalıdır. Eğer dileyenin dilediği teknolojiyi kullanmasına izin verirseniz, takımlar bağımsız bir şekilde istedikleri teknolojileri kullanırlar ve bir zaman sonra birbiri ile konuşmakta zorlanan servisler ve takımlar ortaya çıkar. Ayrıca işe alımlar ve ekipler arası geçirgenlikler de zorlaşmaya başlar. Bu nedenle ne teknolojiyi har vurup harman savurmalı, ne de monolitik bir yaklaşım ile “al sana java veya c# hayrını gör” denmemelidir. Burada da konu ile alakalı bir yazıma bağlantı veriyorum.
Servisler arası ortak erişilen bir veri tabanı kullanmak.
Mikroservis mimarisinin en önemli konularından birisi her servisin kendisine ait veri tabanının olmasıdır. Aksi bir durum bağımsız bir şekilde geliştirme yapmanın önündeki engellerden biridir. Ortak veri tabanı kullanımında servisler birbirine bağlı olurlar, çünkü DB katmanında join’ler ile farklı servislerin verisi birbirlerini okuyacaktır. Bunun yerine servislere bağımsız veri tabanları koymalı ve ilgili servisten istenen bilgiler servis tarafından diğer servislere API olarak verilmelidir.
Bazı durumlarda da diğer mikroservisin verisini kendi veri tabanına anlık kopyalamak veri okumalarında performans adına çok önem arz edecektir. Change Data Capture dediğimiz bu servisler arası veri kopyalama yöntemi ile read işlemi hızlandırılacak ve Command and Query Segregation (CQRS) kısmen sağlanmış olacaktır.
Mikroservisleri versiyonlamadan kullanmak.
Mikroservis mimarisinde versiyon konusu çok önemlidir. Eskisi gibi tek, dev bir uygulamanız yok artık. Bunun yerine onlarca servis var. Bu servislerin aynı anda farklı versiyonları yaşıyor olabilir, daha doğrusu yaşıyor olması lazım. Çünkü kimse kimseye aynı anda bir gece geçiş yapacağız demiyor artık. Bunun yerine feature flag gibi yöntemler ile veya versiyonlama ile diğer servislerin kendilerine olan bağımlılıklarını minimize ederek servisler için bağımsız bir şekilde yaşam döngüsü kurulmalıdır.
Ayrıca API versiyonlaması semantik bir şekilde yapılmalıdır. Client hangi API’nin hangi versiyonuna gittiğini anlayabilmeli, aktif olan versiyonlara yönlenebilmeli ve geri ne döneceğini bilmelidir.
Mikroservislerin dışa açtıkları API’lerin genel ve çok parametreli olması.
Bu durumda servislerde yapılabilecek değişiklerde client’lar sürekli kendilerini güncellemek zorunda kalabilirler. Dışarıya açılan API’ler anlamlı ve mümkün olduğunca 1 işlem yapan basit fonksiyonlar olmalıdırlar. Businesss Implementasyonu kendi içerisinde gizlemeli (encapsulation) ve parametre sayısı minimum kalmalıdır.
Mikroservis mimarisine geçmiş olmaya rağmen hala ESB (Enterprise Service BUS) kullanmak.
Mikroservis mimarisinin en önemli özelliklerinden birisi de servislerin ortada duran monolitik bir ESB ile haberleşmek zorunda kalmamalarıdır. Mikroservisler birbiri ile MessageBus, REST, gRPC ve API Gateway vasıtasıyla iletişim kurabilirler ama hantal ve eski moda ESB yaklaşımının mikroservis mimarisinde işi yoktur.
Asenkron iletişim ve EventBus kullanmamak, senkron iletişime devam etmek.
Eğer mikroservis mimarisine geçip EventBus kullanmıyorsanız mimariniz eksik demektir. Asenkron işlemleri EventBus üzerinden yapıyor olmanız lazım. Eğer mikroservisler birbirlerini sürekli REST çağrıları ile çağırıp, işlemlerini senkron olarak gerçekliyorlarsa dağıtık bir monolitik olma yolunda ilerliyorsunuz demektir.
Konfigürasyonu Manuel yönetmek.
Artık onlarca servisiniz var ve her ekipten kendi konfigürasyonlarını yönetmelerini istemek ve ekiplerin bunu manuel bir şekilde her talepte kod değişikliği yaparak çözmesi zamanla yönetilemez bir durumu doğuracaktır. Konfigürasyon için otomatize sistemler kurulmalı, bu sistemler sayesinde kod değişikliği yapılmadan gerekli config değişikliklerinin canlı ortama anında ve bir kesinti yapmadan geçmesi sağlanmalıdır.
Sonuç
Bu makalede mikroservis dünyasında en çok ortaya çıkan anti-pattern’ları listeledim. Özellikle teknik manada çok daha fazla ekleme yapılabilir. Çok önemli olduğunu düşündüğünüz ama yazıda olmayan anti-pattern’lar varsa iletişime geçebilirsiniz.
Referanslar
https://chrisrichardson.net/post/antipatterns/2019/01/28/melbourne-microservices.html
https://itnext.io/anti-patterns-of-microservices-6e802553bd46
https://arxiv.org/pdf/1908.04101.pdf
https://www.infoq.com/articles/seven-uservices-antipatterns/