參考:https://microservices.io/post/architecture/2023/03/28/microservice-architecture-essentials-loose-coupling.html
There’s actually two different types of coupling:
runtime coupling - influences availability
design-time coupling - influences development velocity
Runtime coupling and availability
Runtime coupling between services is the degree to which the availability of one service is affected by the availability of another service. Or to be more precise, it’s degree to which the availability of an operation implemented by one service is affected by the availability of another service
微服務化以后導致一個請求會同步調用多個服務,請求的時常和可用性都會降低。
Reducing runtime coupling
使用異步的方式可以提高請求的可用性,但是客戶端變得更復雜了,必須輪詢服務器獲得請求的狀態。
這里建議的依然是orderService調用Consumer Service,只是放到異步線程了而已。其實到底是OrderService調用ConsumerService的RPC api, 還是Consumer Service監聽OrderService的事件,要看業務邏輯而定,如果ConsumerService是OrderService的強依賴(說明OrderService domain必須要理解ConsumerService domain的概念和API),那么RPC的方式是合理的,反之,異步消息的方式更合理。
DDD總是推薦異步消息,因為一個transaction只更新一個aggregate。
Design-time coupling and development velocity
The degree of design-time coupling between a pair of software elements - classes…services - is the likelihood that they need to change together for the same reason. Design-time coupling between services in a microservice architecture is especially problematic. Let’s look at why it’s a problem and how we can minimize it.
這其實就是《整潔架構》里面所說的單一指責原則,或者說共同閉包原則,如果兩個模塊總是因為同一個原因改變,那么他們就應該屬于一個模塊,或者說,在微服務架構下,一個服務內部。
If two services are loosely coupled, then a change to one service rarely requires a change to the other service. However, if two services are tightly coupled, then a change to one service often requires a change to the other service. These types of lock step changes are expensive since it typically involves breaking API changes.
For example, let’s imagine that the Order Service and Customer Service are tightly coupled. Each time a breaking changes needs to be made to the Customer Service the sequence of steps is as follows:
Change the Customer Service to add a new major version of its API. The service must implement both the old and new version of its APIs until all clients have been migrated over.
- Migrate the Order Service to the new API version
- Remove the old API version from the Customer Service
- What’s even worse, is that quite often the services are owned by different teams, which requires those teams to coordinate the changes. In other words, design-time coupling between services undermines team autonomy.
Reducing design-time coupling
Minimizing design-time coupling is one of the dark matter attractive forces that resists decomposition. There are a couple of different ways to minimize design-time coupling between services.
design subdomains to be loosely coupled - loosely coupled subdomains can be packaged as different services. Loose design-time coupling is usually achieved by each subdomain having a stable API that encapsulates its implementation.
package subdomains that are tightly coupled in the same service - If two subdomains are tightly coupled, then packaging them together in the same service will avoid design-time coupling between services.
解決方法也很簡單,就是遵循DDD的設計,子模塊(微服務)之間應該有合理的邊界,每個子模塊有相對獨立的業務邏輯,子模塊的API應該相對穩定。遵守單一指責原則,共同閉包原則。