Gelişmeye açık olarak tasarlamaDesign for evolution

Sürekli yenilik için gelişime açık bir tasarım çok önemlidirAn evolutionary design is key for continuous innovation

Tüm başarılı uygulamalar, zaman içinde gerek hataların düzeltilmesi, gerek yeni özelliklerin ve teknolojilerin eklenmesi, gerekse de mevcut sistemlerin daha ölçeklenebilir ve dayanıklı hale getirilmesi için değişir.All successful applications change over time, whether to fix bugs, add new features, bring in new technologies, or make existing systems more scalable and resilient. Bir uygulamanın tüm bölümleri birbirine sıkı şekilde bağlı değilse, sistemde değişiklik yapmak çok zorlaşır.If all the parts of an application are tightly coupled, it becomes very hard to introduce changes into the system. Uygulamanın bir bölümünde değişiklik yapılması başka bir bölümün bozulmasına veya kod tabanının tamamına yayılan değişikliklere yol açabilir.A change in one part of the application may break another part, or cause changes to ripple through the entire codebase.

Bu sorun, tek parçalı uygulamalarla sınırlı değildir.This problem is not limited to monolithic applications. Bir uygulama çeşitli hizmetlere bölünmüş olmasına rağmen sistemin katı ve kırılgan olmasına neden olan sıkı bağ belirtilerine sahip olabilir.An application can be decomposed into services, but still exhibit the sort of tight coupling that leaves the system rigid and brittle. Hizmetler evrilecek şekilde tasarlanırsa, ekipler yenilik yapabilir ve sürekli olarak yeni özellikler sunabilir.But when services are designed to evolve, teams can innovate and continuously deliver new features.

Mikro hizmetler, burada birçoğu adresi gelişime açık bir tasarım, yapmanın yaygın bir yolu hale gelmektedir.Microservices are becoming a popular way to achieve an evolutionary design, because they address many of the considerations listed here.

ÖnerilerRecommendations

Yüksek uyum ve gevşek bağ modelini uygulayın.Enforce high cohesion and loose coupling. Bir hizmet, mantıksal olarak aynı kategoride yer alan işlevler sağlıyorsa uyumludur.A service is cohesive if it provides functionality that logically belongs together. Bir hizmetin diğerleri etkilenmeden değiştirilebildiği hizmetler arasında gevşek bağ vardır.Services are loosely coupled if you can change one service without changing the other. Uyumun yüksek olması genellikle bir işlevde yapılan değişikliklerin ilgili diğer işlevlerde de değişiklik gerektirmesi anlamına gelir.High cohesion generally means that changes in one function will require changes in other related functions. Bir hizmetin güncelleştirilmesi için diğer hizmetlerde eşgüdümlü güncelleştirmeler yapılması gerektiğini fark ederseniz bu, hizmetlerinizin uyumlu olmadığına ilişkin bir işaret olabilir.If you find that updating a service requires coordinated updates to other services, it may be a sign that your services are not cohesive. Etki alanı Odaklı Tasarım (DDD) amaçlarından bu sınırları tanımlamaktır.One of the goals of domain-driven design (DDD) is to identify those boundaries.

Etki alanı bilgisini kapsülleyin.Encapsulate domain knowledge. Bir istemci bir hizmeti kullanırken etki alanının iş kurallarını uygulama sorumluluğu istemciye bırakılmamalıdır.When a client consumes a service, the responsibility for enforcing the business rules of the domain should not fall on the client. Bunun yerine, hizmetin sorumluluğu altındaki tüm etki alanı bilgilerini kapsüllemesi gerekir.Instead, the service should encapsulate all of the domain knowledge that falls under its responsibility. Aksi durumda, iş kurallarının tüm istemciler tarafından uygulanması gerekir ve etki alanı bilgileri uygulamanın farklı bölümlerine yayılır.Otherwise, every client has to enforce the business rules, and you end up with domain knowledge spread across different parts of the application.

Zaman uyumsuz mesajlaşma kullanın.Use asynchronous messaging. Zaman uyumsuz mesajlaşma, mesajın üreticisi ile tüketicisini birbirinden bağımsız hale getirme imkanı sağlar.Asynchronous messaging is a way to decouple the message producer from the consumer. Üretici, tüketicinin mesajı yanıtlamasına veya herhangi bir eylem gerçekleştirmesine bağımlı değildir.The producer does not depend on the consumer responding to the message or taking any particular action. Bir yayım/abonelik mimarisinde üretici mesajı kimin tükettiğini bile bilmeyebilir.With a pub/sub architecture, the producer may not even know who is consuming the message. Mesajlar, üreticide herhangi bir değişiklik yapılmaksızın yeni hizmetler tarafından kullanabilir.New services can easily consume the messages without any modifications to the producer.

Bir ağ geçidinde yerleşik olarak etki alanı bilgilerine yer vermeyin.Don't build domain knowledge into a gateway. Ağ geçitleri, bir mikro hizmet mimarisinde istek yönlendirme, protokol çevirisi, yük dengeleme veya kimlik doğrulaması gibi şeyler için kullanışlı olabilir.Gateways can be useful in a microservices architecture, for things like request routing, protocol translation, load balancing, or authentication. Ancak, ağ geçidi bu tür altyapı işlevleriyle sınırlandırılmalıdır.However, the gateway should be restricted to this sort of infrastructure functionality. Yoğun bir bağımlılık haline gelmesinin önlenmesi için hiç etki alanı bilgisi uygulamamalıdır.It should not implement any domain knowledge, to avoid becoming a heavy dependency.

Açık arabirimler sunun.Expose open interfaces. Hizmetler arasında yer alan özel çeviri katmanları oluşturmamaya özen gösterin.Avoid creating custom translation layers that sit between services. Bunun yerine, bir hizmetin iyi tanımlanmış bir API sözleşmesine sahip bir API sunması gerekir.Instead, a service should expose an API with a well-defined API contract. Geriye dönük uyumluluğu koruyarak API’yi geliştirebilmeniz için API’nin sürümü tutulmalıdır.The API should be versioned, so that you can evolve the API while maintaining backward compatibility. Bu sayede, bir hizmeti buna bağımlı olan tüm yukarı akış hizmetlerinde güncelleştirme koordinasyonu sağlamanıza gerek kalmadan güncelleştirebilirsiniz.That way, you can update a service without coordinating updates to all of the upstream services that depend on it. Genel erişime açık hizmetler, HTTP üzerinden bir RESTful API sunmalıdır.Public facing services should expose a RESTful API over HTTP. Arka uç hizmetleri, performans nedeniyle RPC stili bir mesajlaşma protokolü kullanabilir.Backend services might use an RPC-style messaging protocol for performance reasons.

Hizmet sözleşmelerine göre tasarlayın ve test edin.Design and test against service contracts. Hizmetler iyi tanımlanmış API’ler sunuyorsa bunlara göre geliştirme ve test işlemleri gerçekleştirebilirsiniz.When services expose well-defined APIs, you can develop and test against those APIs. Böylece, bağımlı olunan tüm hizmetleri çalıştırmak zorunda kalmadan tek bir hizmeti geliştirebilir ve test edebilirsiniz.That way, you can develop and test an individual service without spinning up all of its dependent services. (Doğal olarak, yine de gerçek hizmetlerle tümleştirme ve yük testi gerçekleştirirsiniz.)(Of course, you would still perform integration and load testing against the real services.)

Altyapıyı etki alanı mantığından uzakta soyutlayın.Abstract infrastructure away from domain logic. Etki alanı mantığının mesajlaşma veya kalıcılık gibi altyapıyla ilgili işlevlerle karışmasına izin vermeyin.Don't let domain logic get mixed up with infrastructure-related functionality, such as messaging or persistence. Aksi takdirde, etki alanı mantığındaki değişiklikler altyapı katmanlarının güncelleştirilmesini gerektirir ve tersi için de aynısı geçerli olur.Otherwise, changes in the domain logic will require updates to the infrastructure layers and vice versa.

Geniş kapsamlı kritik konuları ayrı bir hizmete boşaltın.Offload cross-cutting concerns to a separate service. Örneğin, birkaç hizmetin istek kimliklerini doğrulaması gerekiyorsa, bu işlevi ayrı bir özel hizmete taşıyabilirsiniz.For example, if several services need to authenticate requests, you could move this functionality into its own service. Daha sonra, kimlik doğrulama hizmetini kendisini kullanan hizmetlerden hiçbirine dokunmadan geliştirebilirsiniz (örneğin yeni bir kimlik doğrulama akışı ekleyerek).Then you could evolve the authentication service — for example, by adding a new authentication flow — without touching any of the services that use it.

Hizmetleri bağımsız olarak dağıtın.Deploy services independently. DevOps ekibinin uygulamadaki diğer hizmetlerden bağımsız olarak tek bir hizmet dağıtabildiği durumlarda, güncelleştirmeler daha hızlı ve güvenli bir şekilde gerçekleştirilebilir.When the DevOps team can deploy a single service independently of other services in the application, updates can happen more quickly and safely. Hata düzeltmeleri ve yeni özellikler daha düzenli bir tempoyla sunulabilir.Bug fixes and new features can be rolled out at a more regular cadence. Hem uygulamayı hem de yayın işlemini bağımsız güncelleştirmeleri destekleyecek şekilde tasarlayın.Design both the application and the release process to support independent updates.