"Microservice Design"

Introduction : "Microservice Design" is a very brilliant technical book. It is excellent in terms of readability and practical technical dry goods. It even reminds me of the classics such as "In-depth Understanding of Computer Systems" and "UNIX Programming Art". The feeling of a good book. The following are some general reading notes I made. I very much hope that you can read the whole book and dig more knowledge.


 

1. What are microservices: some small and autonomous services that work together.

  • Small and focused on doing one thing well : defining the boundaries of the service according to the boundaries of the business.
  • Autonomy : A microservice is an independent entity. All services communicate through network calls, which strengthens the isolation between services and avoids tight coupling. These services should be modifiable independently of each other, and the deployment of one service should not cause changes to the consumer of that service. 

    2. The main benefits of microservices

  • Technology Heterogeneity : Different technology stacks, languages, databases or frameworks can be used.
  • Elasticity : A key concept in elastic engineering is bulkheads. If one component of the system becomes unavailable without causing a cascading failure, the rest of the system can still function normally.
  • Scaling : Using smaller multiple services, you can scale only the services that need to be scaled, so that those services that don't need scaling can be run on smaller, less-performing hardware.
  • Simplified deployment : In a microservices architecture, the deployment of each service is independent, so that specific parts of the code can be deployed more quickly.
  • Matching with the organizational structure : Microservices architecture can well match the architecture to the organizational structure, avoiding an overly large code base, and thus achieving the ideal team size and productivity.
  • Composability : Services of different granularities can be combined for different purposes to provide functionality to customers.

    3. Principles of Microservices

  • Experience with modeling around business concepts
    shows that interfaces defined around the bounded context of the business are more stable than interfaces defined around technical concepts. Modeling the domain of how systems work not only helps us form more stable interfaces, but also ensures that we can better reflect changes in business processes. Use bounded contexts to define possible domain boundaries.
  • Accepting a culture of automation
    Microservices introduces a lot of complexity, and a key part of its rollup is that we have to manage a large number of services. A key way to address this is to embrace an automation culture. At a cost upfront, building tools to support microservices makes a lot of sense. Automated testing is essential because ensuring that our vast array of services work is a more complex process than a monolithic system. Invoking a unified command line to deploy the system to each environment in the same way is a useful practice, and is a key part of using continuous delivery to get quick feedback on the quality of the product after each commit.
    Consider using environment definitions to help you identify differences between environments, while maintaining the ability to deploy in a consistent manner. Consider creating custom images to speed up deployment, and creating fully automated immutable servers that will make it easier to pinpoint problems with the system itself.
  • Hiding Internal Implementation Details
    To maximize the ability of a service to evolve independently of other services, hiding implementation details is critical. Bounded context modeling can help in this regard, as it helps us focus on which models should be shared and which should be hidden. Services should also hide their databases so as not to fall into database coupling, which is also the most common type of coupling in traditional service-oriented architectures. Use Data Pump or Event Data Pump to bring together data across multiple services for reporting purposes.
     
    When possible, try to choose a technology-agnostic API. This gives you the freedom to use different technology stacks. Consider using REST, which normalizes the separation of internal and external implementation details, even with RPC you can still adopt these ideas.
  • Decentralize everything
    To maximize the autonomy that microservices can bring, we need to continue to look for opportunities to delegate decision-making and control to the team that owns the service. Early in the process, whenever possible, try to use resource self-service, allow people to deploy software on demand, make development and testing as easy as possible, and avoid having separate teams do it.
     
    Ensuring the team maintains ownership of the service is an important step in the process, ideally even letting the team decide for themselves when to bring those changes live. Use an internal open source model to ensure that people can change services owned by other teams, but be aware that implementing this model requires a lot of work. Aligning the team with the organization makes Conway's Law work and helps teams that are building business services to become experts in the business domain they are building. Some global guidance is necessary, try using a co-governance model where each member of the team is collectively accountable for the evolution of the system's technical vision.
     
    Scenarios like Enterprise Service Bus or Service Orchestration System, which lead to centralized and dumb services of business logic, should be avoided. Use collaboration instead of orchestration or dumb middleware, use smart endpoints to ensure related logic and data, and maintain service cohesion within service boundaries.

• Can be deployed independently

We should always strive to ensure that services can be deployed independently. Even when incompatible changes need to be made, we should provide both the old and new versions, allowing consumers to slowly migrate to the new version. This helps us release new features faster. Teams with these microservices can also become increasingly autonomous because they don't need to be constantly orchestrated during deployment. When using RPC-based integration, avoid using generated stub code, tightly bound client/server techniques like Java RMI provides.

By adopting the single-service single-host model, you can reduce the side effects of deploying one service, such as affecting another completely unrelated service. Consider using blue/green deployment or canary deployment techniques to differentiate between deployments and releases and reduce the risk of release errors. Use consumer-driven contract testing to catch breaking changes before they happen.

Remember that you can change a single service and deploy it to production without deploying any other services in parallel, this should be the norm, not the exception. Your consumers should decide for themselves when to update, and you need to accommodate them.

• Quarantine failure

Microservices architectures can be more resilient than monolithic architectures, provided we understand the failure modes of the system and plan accordingly. If we don't take into account the fact that calls downstream may fail, the system will suffer catastrophically cascading failures and the system will be more vulnerable than before.

When using network calls, do not handle remote calls as if they were local, as this hides different failure modes. So make sure to use a client library that does not over-abstract remote calls.

If we have an antifragile creed in our hearts and expect failures everywhere, we're on the right track. Be sure to set your timeouts correctly, and understand when and how to use bulkheads and circuit breakers to limit the collateral effects of faulty components. If only one part of the system is misbehaving, understand the impact on the user. Know what a network partition might mean and whether sacrificing availability or consistency is the right decision in a particular situation.

• Highly observable

We cannot rely on observing the behavior of a single service instance, or a server, to see if the system is functioning properly. Instead, we need to take a holistic view of what's going on. Use semantic monitoring to see if your system is functioning properly by injecting synthetic transactions into your system, simulating the behavior of real users. Aggregate your logs and data so that when you encounter a problem, you can drill down into the cause. And when you need to reproduce a pesky problem, or just see how your systems interact in production, contextual flags can help you track calls between systems.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325066641&siteId=291194637