I spent the past two days reading "Microservice Design", and finally got a framework understanding of microservices. Personally, I am quite satisfied with this book. First of all, it is relatively thin and suitable for quick reading, but it has a lot of knowledge points. The author has given a lot of citations and cases, which can be studied in depth. There are many references. Below are the relevant main notes I have summarized in this book.
You can also look directly at the outline I compiled:
http://naotu.baidu.com/file/ec17996ffdd7db86b8bc09a8f84fd8fe?token=30c2fd9e299b9390
1. What are microservices
Microservices are small, autonomous services that work together. The most important of which are two points, small and autonomous.
The novel is to focus on doing one thing. A microservice only focuses on one field, so how can it be considered small? The author's judgment method is that as long as you don't think it is too big, then it is small and does not need to be split. The system already feels that the code base is relatively large, so it needs to be disassembled;
Autonomy says that a microservice is an independent entity. It can be deployed independently, and the services communicate through the network, which directly isolates the services physically.
The main advantages of microservices over monolithic services are:
Elasticity: Fault tolerance, microservices can handle service unavailability and functional degradation well. The monolithic service can only reduce the probability that the function is completely unavailable by deploying multiple copies and load balancing.
Scalability: If there are some functions in a monolithic service that have performance problems, the entire service needs to be extended; while microservices only need to be extended for those microservices with performance problems.
Technology heterogeneity: The natural isolation of microservices allows different functional modules to be implemented using different technologies, which allows us to adopt new technologies faster and with less risk.
What is the difference between microservices and SOA?
Microservices are a specific method of SOA. Microservices have more specific suggestions for implementing SOA. SOA did not originally guide how to divide large applications into small ones.
Principles of implementing microservices
1. Model around business concepts
2. Embrace an automation culture
3. Hide internal implementation details
4. Decentralize everything
5. Can be deployed independently
6. Isolation Failure
7. Highly observable
2. How to implement microservices
2.1 How to model a service
Principle: high cohesion, low coupling.
There is an important concept: a bounded context, a specific responsibility bounded by explicit boundaries. If we are talking about a module system, the bounded context can be considered as the sum of the module itself and the external interface. Pay attention to shared hidden models, clarify internal and external representations, and do not share internal representations; ensure that service boundaries and domain bounded contexts can be consistent, and microservices can well represent these bounded contexts, so as to achieve high cohesion and low coupling.
Don't partition the system too early, it should be gradually split by the monolithic system.
The service is bound to grow slowly until it needs to be split.
Onion architecture can be extremely difficult to slice due to its many layers.
2.2 Integration Scheme
Avoid database integration
REST or RPC question, REST should be used as a starting point
Prioritize collaboration over orchestration
Avoid destructive modifications
Understand Postel's Law, be strict with yourself and be tolerant of others
Use fault-tolerant readers
Think of the UI as a composition layer
2.3 How to split a monoblock system
Database, which is usually the most difficult piece of content for microservices to split. The author provides several ideas for the splitting of the database:
break foreign keys
Shared static data, similar to public static data such as cities, can replicate a set of tables for each microservice; it can also be stored directly in files; or public microservices can be extracted separately.
To share dynamic data, usually these dynamic data need to be extracted and used as a separate service.
Shared dictionary tables, you can have these dictionary tables in each microservice, but only the items needed by each service are stored in it.
Database splitting, which is a must for microservice splitting, so as to ensure that the database has no dependencies.
Transactions, two methods: distributed transactions, or using eventual consistency
For reports, due to database splitting, the source of report data may come from multiple microservices. At this time, there is a problem with the source of report data. There are three solutions:
Each microservice provides batch API, which can obtain batch data
Export the data of each microservice to the reporting system
The data of each microservice is pushed to the reporting system in real time. This solution is generally adopted, and the delay is small.
2.4 How to deploy
Continuous integration into microservices, ensuring each microservice has a CI
Building Pipelining and Continuous Delivery for Microservices
Types of builds: platform specific builds, OS builds, images as builds
Try to ensure that each service has one container, which can relatively simplify deployment
Embrace automation, deployment of microservices is very difficult without automation
2.5 How to test
Types of tests: functional test, UAT test, end-to-end test, smoke test, CDC test
The consumer-driven contract testing (CDC) test method only tests a single microservice, and only the producer, and all external collaborators of the microservice are stubbed or mocked;
The author recommends using CDC testing instead of end-to-end testing as much as possible, because end-to-end testing is difficult to function;
However, CDC's test also has some limited scenarios, especially for third-party API tests, there is no way to use it.
2.6 How to monitor
There are two types of monitoring: service monitoring and system monitoring.
Service monitoring:
For each service, the minimum requirements to monitor are: request response time, error rate, health status of downstream services, response time and error rate of downstream services.
Standardize collection metrics as well as storage metrics.
System monitoring:
Standardized association identification, which can monitor the entire request link. such as zipkin
Aggregate host metrics like CPU.
Use queryable tools to aggregate and store logs. Such as Kibana ElasticSearch
2.7 Safety measures
Identity authentication and authorization, related technologies: SSO and OpenID
For the authentication and authorization between services, the author has organized three methods:
Implicit trust, i.e. everything is allowed within the boundaries
Authenticate the caller
Ask the caller to provide the credentials of the original principal
Data-at-rest security
Try to use well-known algorithms for encryption, such as AES-128/AES-256, and salted password hashes; to ensure the security of the encryption algorithm
Encryption is also required for data storage and backup
defense in depth
Logs: Eliminate sensitive information
firewall
Intrusion detection
network isolation
Operating system, patched regularly
3. Scale operation of microservices
This is the focus of this book and the focus of microservices in operations.
First there is an important point: in a distributed architecture, failures are everywhere. The network itself is unreliable, so failures are unavoidable. And after scale, failure has become an inevitable event. Instead of trying to waste too much time on inevitable failures, spend more time handling them gracefully. The author cites an example of how Google manages hard drives: Google exposes hard drives outside the server chassis and snaps them to Velcro, in order to replace them quickly if they fail, rather than trying to prevent them from failing.
Architectural Security Measures:
An important point here: a very slow response is one of the worst failure modes. If a system goes down, you'll find out very quickly. But when it's just slow, you need to wait a while before giving up. And slow response requests will occupy valuable connection pool resources, which will affect other functions.
How to fix it: set timeouts, circuit breakers, bulkheads, isolation (upstream services allow downstream services to go offline), idempotent
Redesign
The system should be designed to account for a 10x increase in capacity, but over 100x it will have to be rewritten.
Don't build a large-scale system in the first place; it's possible to build it and it's not needed.
Scaling the database
Read scaling: master-slave replication
Write Scaling: Sharding
Choose NoSQL
Command-Query Responsibility Segregation + Event Sourcing
cache
Three caches:
Client-side caching, i.e. browser caching, is controlled by HTTP cache-phase parameters: cache-control, Expires, Entity Tags
Proxy cache, special server is set in front of the actual source service, such as: Squid, Varnish, Apache Traffic Server
Server cache, such as Redis, Memcache
question:
Hide the source service. When a large number of caches are invalid, a large number of requests will be sent to the source service, which may cause the source service to go down. The solution is: when the cache is invalid, you can make the original request fail quickly, push an asynchronous message to the origin service, and rebuild the cache in the background.
Cache poisoning, in the case of Expires: Nerver, caches are never invalidated until the browser cache is full or the user manually clears them. The solution: change the URLs of these pages so that they can be retrieved again.
CAP theory
That is, Consistency, Availability, and partition tolerance can only guarantee two of them.
Therefore, each function in a distributed system can only guarantee one in consistency and availability.
AP: There will be outdated data, but availability and eventual consistency can be guaranteed; for example: inventory query
CP: Strong consistency, fail fast. Example: transfer money
Service Discovery and Service Registration
Related technologies: DNS, zookeeper, consul, eureka
Documentation Services
Related technologies: Swagger, HAL
4. Architect Responsibilities
Responsibilities of an evolutionary architect: vision, empathy, cooperation, adaptability, autonomy, governance.
Code Governance: Examples, Service Code Templates
5. Microservice team
Conway's Law: When any organization designs a system (a system in a broad sense), the delivered design is structurally consistent with the organization's communication structure. Highlights the dangers of trying to have a system design that doesn't match the organizational structure.
Small teams will work more effectively than large teams. Two Pizza Teams: That is, no team should be so big that two pizzas are not enough.
adapt to communication
Communication between teams has costs, and if multiple teams work on the same system, one thing will eventually happen: people will either figure out how to coordinate/communicate costs, or stop changing. And the latter is what led us to end up with large, hard-to-maintain codebases.
If the organization building a system is more loosely coupled, the system it builds tends to be more modular and therefore less coupled; a single team with many services tends to be more tightly integrated for the services it manages, and this Ways are difficult to maintain in a distributed organization.