[Translation] Microservice Design Pattern-2. Microservice Application Pattern

Original address: https://microservices.io/patterns/microservices.html

Scene description

Suppose you are developing a large-scale server-side enterprise application with the following requirements:

  • Must support a variety of clients, including: WEB browser, WAP browser and native mobile APP.
  • Expose public APIs for invocation
  • Process HTTP requests, or messages, and execute corresponding business logic.
  • Access the database, cache or persist the response data
  • Communicate with other systems and exchange required information
  • Return the HTTP response, specify a specific serialization method, such as JSON, XML, etc.
  • According to business logic and functions, design and divide different logic modules

How would you design and deploy such an application?

Considerations

  • This is a project developed by a team, and an independent team is responsible for it
  • Team members will change, new members must get started quickly
  • The application must be easy to understand and modify
  • Expect to achieve continuous integration and deployment of applications
  • It must be possible to deploy applications in multiple instances to meet scalability and availability requirements.
  • Want to use relatively new technology (framework, programming language, etc.)

solution

Define a collaborative architecture that constructs an application as a set of loosely coupled microservices, each of which satisfies:

  • Highly maintainable and testable : supports rapid and frequent development and deployment.
  • Loosely coupled with other microservices : Enables the team to work independently on their own microservices most of the time, without being affected by changes in other microservices, and without affecting other microservices.
  • Independent deployment : Enable teams to deploy their services without having to coordinate with other teams.
  • Reduce communication costs : It can be split into small teams to focus on their own microservices, reducing the internal communication costs of large teams.

Services use synchronous protocols (such as HTTP/REST) ​​or asynchronous protocols (such as AMQP) to communicate. Services can be developed and deployed independently of each other. Each service has its own database to separate it from other services. Data consistency between services uses SAGA mode

For example

Suppose you are designing an e-commerce application. The functions include receiving orders from customers (StoreFrontUI), verifying and maintaining inventory balances (Inventory Service), verifying and maintaining user available balances (Accounting Service), and placing orders successfully and shipping (Shipping Service) ). This application is designed as a microservice architecture application, as shown in the figure:

image

analysis

benefit

  • Support continuous delivery and deployment of large and complex applications
    • Increased maintainability : Each service is relatively small, so it is easier to understand and change.
    • Easier to be tested : The service is smaller and the test speed is faster.
    • Better deployability : Services can be deployed independently.
    • The division of labor and module business boundaries are more clear , and a certain microservice can be delivered and maintained by one or more teams. Each team can develop, test, deploy, and extend their services independently of all other teams.
  • Each microservice is relatively smaller:
    • It's easier for developers to understand
    • IDE load is lower, faster, and improve development efficiency
    • The application starts faster, improves Debug efficiency, and speeds up deployment.
  • Fault isolation . For example, if there is a memory leak in a microservice, only that microservice will be affected. Other services can continue to process requests.
  • It is easier to update the technology stack . When a new microservice module is developed, a new technology stack can be used for experimental development and use. After it is stable, it can be gradually extended to other microservices.

harm

  • Developers must face the additional complexity brought by distributed systems :
    • Developers must be familiar with RPC communication and write fault handling logic.
    • It is more difficult to implement requests across multiple services.
    • The interaction between testing services is more difficult. Unit tests cannot cover all scenarios, and integration tests are more troublesome to deploy.
    • Achieving requests across multiple services requires careful coordination between teams.
    • IDEs are mostly geared towards building monolithic applications and do not provide explicit support for developing distributed applications.
  • Deployment complexity . In production, deploying and managing a system composed of many different services also has operational complexity. The current containerization and container orchestration solutions are to solve this problem.
  • Increase the consumption of resources such as memory . Assuming that each microservice occupies a JVM, the resources occupied by the JVM itself (such as the CPU and memory occupied by the GC, as well as meta-space, code cache, etc.) are more than the original one compared with the monolithic application. . If a microservice occupies a container, or even a virtual machine, a machine, this resource waste will be even more.

Issues to consider

When to use microservice architecture?

One of the challenges of using a microservice architecture is deciding when to use it . When developing the first version of an application, you usually do not encounter problems that require this method to solve. In addition, the use of a more sophisticated distributed architecture design will slow down the development speed. For start-ups, this may be a major problem, and the biggest challenge they face is often how to quickly develop their business and quickly iterate applications. However, as the product continues to iterate, this monolithic application will become larger and larger, and the size of the team will become larger and larger. When it is necessary to use functional decomposition into a microservice architecture, complex dependencies may make the application It is difficult to break down into a set of services.

How to decompose the application into services?

Another challenge is to decide how to divide the system into microservices. This is largely an art, but there are many strategies you can refer to:

  • Decompose and define microservices corresponding to business functions by business .
  • According to art-driven design subdomain decomposition
  • Decompose by user behavior and use case , and define microservices responsible for specific operations. For example, Shipping Service is responsible for shipping complete orders.
  • Define a microservice that is responsible for operating a certain type of entity/resource . For example, Account Service is responsible for managing user accounts.

Ideally, each service should have only a small part of responsibility. Bob Martin talked about the single responsibility principle should be used . As far as a class is concerned, there should be only one reason for its change. It also makes sense to apply the single responsibility principle to service design.

Another analogy that helps with service design is the design of Unix utilities. Unix provides a large number of utilities, such as grep, cat, and find. Each utility only does one thing, and complex tasks are achieved by using shell scripts in combination with other utilities.

How to maintain data consistency?

To ensure loose coupling, each service has its own database. Maintaining data consistency between services is a challenge, because for many applications, two-phase commit (2PC) or distributed transactions are not a good choice. The application must use the SAGA mode, the service publishes an event when its data changes, and other services use the event and update its data. There are several methods for reliably updating data and publishing events, including Event Sourcing and Transaction Log Tailing.

How to implement the query?

Another challenge is to implement queries that need to retrieve data owned by multiple services.

Related design patterns

image

  • Microservice dismantling mode
  • Each microservice database independent design pattern : how each service has its own database to ensure loose coupling.
  • Unified API gateway mode : Define how the client accesses the services in the microservice architecture.
  • Client-side service discovery and server-side service discovery modes are used to route client requests to available service instances.
  • Each host a single service and each host multiple service models, deployment strategy is about design patterns
  • Cross-cutting concerns design pattern (cross-cutting concerns) : For example, aspect-oriented design, two very different components have some similar functions. At this time, we need aspect design to unify these similar functions.
  • breaker
  • Access token
  • Observable mode
  • UI related patterns
  • Testing related design patterns : service component testing and service integration contract testing (Contract Testing)

Guess you like

Origin blog.51cto.com/11418075/2658330