Nowadays, the word framework has become very popular. The architecture design of xx company can be seen everywhere, but most of them are just for fun. How do these frameworks come from and how are the details thought? What is the basis for mutual isolation... I believe many friends still have their own doubts, especially with the increasingly popular microservices and derived microservice gateway products. I just recently planned to write a small open source framework OSS.Core , I had some thoughts during the process, and I will record it through this article, and I hope it can help everyone understand it as much as possible, which probably revolves around the following questions:
1. The origin of microservices
2. Design ideas of microservices
3. Design and implementation of OSS.Core framework
Before I start talking about it, I hope everyone will first understand the traditional architecture and microservices. Service architectures are not independent/opposed to each other. Microservices are a logical concept derived from the traditional framework to deal with issues such as concurrent maintenance. It is more about changes in the way of thinking and problem solving at different stages of the project. Secondly, distinguish the logical architecture from the physical architecture (file). Most of the time, the logical architecture corresponds to the physical architecture, but sometimes a physical architecture can contain multiple logical architectures.
1. The origin of microservices
Microservices mainly decompose some large and complex applications into multiple service combinations, and each service is autonomous. To achieve more flexibility and easier maintenance.
In order to better understand, let’s first look at three common ways to solve concurrency:
1. Add database master-slave separation, or even multi-master writing or partitioning and other mechanisms. Correspondingly modify the connection string or add access middleware in the application to improve the processing capabilities of the database.
2. Since database resources are relatively tight and time-consuming, in order to improve access speed, distributed caching, etc. are generally used to reduce access to the underlying layer.
3. Load balancing offload processing distributes a large number of requests to different machines before they arrive at the application to solve the problem of single machine bandwidth and performance bottlenecks.
Of course, there are many other ways to solve concurrency, such as front-end static file compression, CDN acceleration, IP rate control, etc., which will be skipped here.
Many friends should have seen the above three methods. The reason why they are listed here is that combined with this picture, it can be easier to compare the changes between traditional entire services and microservices:
In the traditional overall service framework, there is a great coupling between modules, mutual calls within the project, and various complex aggregation operations, so in In most cases, it can only be deployed as a whole. In the picture on the left, we can see that during load balancing, we need to deploy it as a whole on multiple machines. The same is true for databases, and the requirements of each module in a project are different.
For example: the access frequency of products and order modules and the complexity of the process are very different. The order frequency is relatively small and the complexity is high. We prefer to run it on a relatively small scale with high budget capacity. On the machine, it is also convenient for faster troubleshooting and maintenance. As you can see in the picture on the right, after refining the services, we can use smaller deployment units to combine them according to the situation.
At the same time, in today's era of rapid iteration of Internet products, a product needs to have the ability to quickly launch different application functions for different terminals, and at the same time, business adjustments can be quickly launched. The traditional overall service model is no longer enough. Because microservices have been broken into parts, the independence of each module can be quickly combined with each other, and each module can use programming languages with different characteristics according to different demand points.
2. Microservice design ideas
Because each product has its own standards and The focus, so the design of service units is also different, but there is the most basic point: Service Autonomy
When you design a microservice module, you need to ensure the independence of the current service, especially The data module is independent. Other services have no right to directly operate the database module under the current service. External interaction can only be completed through the service interface . Because the modules are independent, you can choose the appropriate programming language and the corresponding deployment scale. Achieve local flexible optimization. While microservices are independent of each other and bring the above conveniences, it also brings some problems that we need to face:
First of all: How to define the boundaries of the current service and how to determine the scope of the current service governance.
Since the service unit is to be minimized, it is necessary to determine the responsibility boundary of the service. It is recommended to combine this issue with: ServiceLife cycleProcess, field, and estimated scale These points should be considered comprehensively, such as user services, when accessing When the workload is small and the staff is small, basic user information and balance accounts can be placed under a service module to reduce workload and distraction. When the scale is large, it can be divided into basic services and asset services.
Secondly:Cross-service dataQueryQuestion
For example, searchproducts in the client, you can also search for users or How to handle statistical data queries, etc. I will give you two ways to handle this: 1.
APIGateway This situation is suitable when there are too many service units and the client needs to query and use different services. For the data in the unit, at this time we can build an API service gateway (please note that it is different from the APP Gateway). Through this gateway, multiple services are aggregated. The client only needs to interact with the current gateway, and the gateway aggregates and forwards them to different Microservices. As shown below:
2. Data redundancy or background data synchronization
For example, in the order information, I need a few user fields such as the user's name. At this time These fields can be redundantly added to the order microservice data module. For another example, under the statistics module, the data producer and queryer belong to completely different
objectsand do not have high real-time performance. Then I suggest creating a statistical service and corresponding statistical database, and other services through Event Message interaction, update corresponding statistical data, and query can be completed through the statistics service's own data.
Again:How to solve the communication problem between servicesBecause we have made the services independent of each other, cutting off the possibility of directly operating different service databases. So how to deal with data consistency? In the traditional service
model, because they are all blended together, we can ensure data consistency through transactions or stored procedures. There are two common methods: 1. Asynchronous event message
DriverThis type of solution is suitable for scenarios where the real-time requirements for data are relatively low, such as the above The statistical service is updated. After the service event such as order placement is triggered, the response message notification is pushed to the message
queue, and the service subscribed to this queue receives updated data. As shown in the figure:
2. Direct interface request (HTTP, RPC)
Generally not recommended to prevent cascading dependencies. This type of request is mainly aimed at requests with high real-time data requirements. For example, during the flash sale order process, you need to know immediately whether the inventory service deduction is successful, etc. (Note: The support for tasks under .net is already very good. It is recommended to use asynchronous http requests, and the front end returns Task<
ActionResult> to reduce the consumption of worker threads caused by IO operations)
Finally:How the client accesses After we encapsulate the service, how the service and the final client access it need to be based on the actual
securityThe rules and requirements are determined separately. Generally speaking, if there are relatively few services and the functions are not complex, the service interface can be directly exposed to the client for access, as shown in the figure:
Or provide it to the client through the
API Gateway mentioned above. Of course, there are also many mature microservice gateways such as Service Fabric or API Management on the Azure cloud. is allowed.
3. The idea and implementation of the OSS.Core framework The OSS.Core project is a small open source product that I have been writing recently. Friends who know it should know that I have written some components before: OSS.Social, OSS.PayCenter, OSS.Common, OSS.Http project I hope to connect these components together. The general way of thinking about microservices has been introduced above. I will try my best to reflect this in the logical architecture of this product. First, show the physical architecture diagram of the project: In this project, AdminSite and WebSite are placed under the FrontEnds folder. The two sites are the user front-end and the background management front-end WebApi, Service, DomainMos (Models and Interface in the picture)Class libraryIn the Layers folder, it forms the basis of the API Infrastructure (business-related common entity enumeration auxiliary class) and Common (business-irrelevant entity auxiliary class) As infrastructure class libraries, they can be called in class libraries at all levels Repositories (temporarily The Mysql implementation of OSS.Core.RepDapper in the project (other database support may be added in the future) is mainly the specific implementation of Rep.. Interface. Plugs are specific implementations of logging, caching, and configuration interfaces under the Common plug-in, and can be directly called at all levels through Common. Returning to the topic of microservices, in this product I will not create a set of class library implementations under Layers for each service. I will separate each service in the form of folder isolation in this project. , you can regard WebApi as an API Gateway. I hope the internal calling sequence is like this: Current code structure diagram:
The above is the detailed content of OSS.Core basic ideas. For more information, please follow other related articles on the PHP Chinese website!