More research architecture, less Framework (3): Event-driven architecture

Source: Internet
Author: User

Next, we used the field-driven development approach, using the congestion model to enjoy his benefits, but also have to face the drawbacks he brings. This disadvantage is amplified under the distributed microservices architecture.

Transactional consistency

The issue of transactional consistency is not a big problem under monolithic, but under microservices it is deadly, and we review the so-called acid principle

atomicity– atomicity, changing the state of the data is either done together or failed together
consistency– consistency, the state of the data is intact and consistent
isolation– isolation lines, even if there are concurrent transactions, do not affect each other
durability– persistent, irrevocable once a transaction is committed
When it comes to single service and relational databases, it's easy to get the acid through the characteristics of the database. But once you split the aggregation root-microservices architecture by DDD, their databases are separated, and you have to deal with the distributed transaction independently, to satisfy acid in your own code.
For distributed transactions, we generally think of the previous JTA standard, 2PC two-paragraph submission. I remember that in the Dubbo Group, the basic weekly people will ask Dubbo when to support distributed transactions. In fact, according to the CAP principle in the Distributed system, when p (partition tolerance) occurs, forcing the pursuit of C (consistency) will result in (A) availability and throughput degradation, at which point we generally use final consistency to guarantee the AP capability of our system. Of course not to say give up C, but in general the CAP can be guaranteed that, in the case of partitioning, we can ensure that the data is consistent through eventual consistency.

Cases:
Place orders in the e-commerce business to freeze inventory scenarios. It is necessary to determine whether the order is executed according to the stock situation.
Suppose you already have a distributed system, where the order module and Inventory module are two services, each with its own storage (relational database),

In a database, a transaction can fix two tables, but in microservices, it is impossible to do so.
In the DDD concept, a transaction can only change the state of an aggregation, and if multiple aggregations require a consistent state, then final consistency is required. Orders and inventories are obviously aggregations of two different gauge contexts, where eventual consistency is required, and event-driven architectures are required.

Event-driven implementation for eventual consistency

The event-driven schema synchronizes state between domain objects through asynchronous messages, and some messages can be published to multiple services at the same time, and the event spreads when the message causes a synchronization of the service to cause additional messages to be generated. There is no synchronous invocation of event drivers in strict sense.

Example:
After the order service has added orders, the order status is "turned on" and then an order created event is posted to the message queue

Inventory service after receiving the order Created event, a SKU in the inventory table is reduced to sell inventory, an increase in the order to occupy inventory, and then send a inventory locked event to the message queue

Order service received the inventory locked event to change the status of the order to "confirmed"

Someone asked, if the inventory is not enough, the lock is not successful how to do? Simply, the inventory service sends a lock fail event, and after the order service is received, the order is placed as "canceled".

Good news, we can use no locks! The big advantage of event-driven is that it cancels concurrency, all requests are queued, which helps us to implement the congestion model, and we don't need to manage the locks in memory ourselves. Unlock, queue processing efficiency is high, event-driven can be used in high-concurrency scenarios, such as snapping.

Yes, the user experience has changed, with this event-driven, the user's experience may be changed, such as the original synchronization of the architecture when there is no inventory, immediately tell you that the condition is not satisfied cannot place the order, but changed the event mechanism, the order is immediately generated, it is likely that the system notifies you that the order was canceled. Just like snapping up "Xiaomi phone", hundreds of thousands of people in line, lined up for a long time to tell you are out of stock, come again tomorrow. If you want the user to get results immediately, you can find a way in the front-end, the BFF (backend for Frontend) using a countdownlatch such a lock to the back end of the asynchronous to the front-end synchronization, of course, so BFF consumption is larger.

No way, the product manager does not accept, the product manager said the user experience must be no inventory will not generate orders, this program will continue to generate canceled orders, he can not accept, how to do? In order list query, skip these cancel status orders, may need an additional view to do. I am not an idealist, to solve the current problem is my first consideration, we design the purpose of microservices is to solve the business concurrency. The problem with user experience is now, so architecture design also needs compromise: ( But at least the analysis was over, and I knew where I was going to compromise, why I was compromised, and what could change in the future.

Multiple fields multi-table join query

I personally think that the aggregation root pattern is particularly appropriate for modifying the state, but it is inconvenient to search the data, such as filtering out a batch of eligible orders such as the requirements, the aggregate root object itself can not bear the bulk of the query task, because it is not his responsibility. That must depend on the "domain Service" facility.
When a method is inconvenient for an entity or value object, using Domain Services is the best solution, make sure that Domain Services are stateless.

Our query tasks are often complex, such as querying the list of items, asking for a sort of sales in the last month, sorting by the return rate of the goods, and so on. However, after MicroServices and DDD, our storage model has been removed, the above query is to deal with orders, users, products in many areas of data. How to do? At this point we are going to introduce the concept of a view. For example, the following, query the user name of the operation of the order, directly call two services themselves in memory join efficiency is very low, plus some filter conditions, paging, can not be done. So we broadcast the event, a separate view service to receive these events, and form a materialized view (materialized view), the data has been join, processed, placed in a separate query library, waiting for the query, this is a typical space-time processing method.

After analysis, in addition to simply based on the primary key find or not too many associated list queries, most of our query tasks can be placed in a separate query library, the query library can be a relational database ReadOnly library, can also be a NoSQL database, In fact, we used elasticsearch as a specialized query view in the project, and it worked very well.

Bounding context (bounded) and data coupling

In addition to the multi-domain join problem, we often encounter some scenarios in the business, such as e-commerce commodity information is the basic information, belongs to a separate BC, and other BC, whether it is marketing services, price services, shopping cart services, order services are required to reference this product information. But the information needed is only a small part of the product, marketing services need the product ID and name, the status of the top shelf, the order service needs the product ID, name, catalog, price and so on. This is a small subset of a commodity (product ID, name, specification, spec value, details, etc.) defined in the Commodity center. This illustrates the same terminology for different gauge contexts, but the concept is not the same. This problem maps to our implementation, each time in the order, marketing module directly query commodity module, it is certainly not appropriate, because

Commodity centers need to adapt the data required for each service, providing different interfaces
The concurrency must be huge.
The coupling between services is serious, once the outage, the scope of the impact of the upgrade is very large.
Especially the last one, which severely limits our access to microservices. "Loose coupling, each service itself can be frequently upgraded without affecting other modules." This requires that we take the event-driven approach, properly redundancy some data to different BC, and disassemble this coupling. This coupling is sometimes achieved by embedding the value object into the entity, which is redundant when the entity is generated, such as when the order is generated and the information of the goods is redundant, sometimes by means of an additional value object list, marketing center redundancy part of the relevant product list data, And always pay attention to monitor the status of the goods, synchronous replacement of this clearance context of the product list.

A single scenario analysis, in an e-commerce system, we can assume that members and products are the basis of all business data, their changes should be broadcast to all areas of the way, each area to retain the information they need.

Ensure final consistency

Eventual consistency depends on many conditions successfully

Reliance on the reliability of message delivery, a system may have changed state, the message was sent to the B system lost, resulting in the state of AB inconsistent
Depend on the reliability of the service, if a system changes its state, but has not had time to send the message to hang up. can also cause inconsistent state
I recall that JMS in the Java EE specification has processing requirements for both of these issues, one is that JMS guarantees the delivery reliability of the message through various acknowledgment messages (Client acknowledge, etc.), and that the JMS message delivery operation can be added to the transaction of the database-that is, no message is sent , will cause the database rollback (no data, not very accurate description, ask the experts to correct). However, the JMS specification of MQ is now few, especially the consistency need to reduce performance, now advertised high-throughput MQ has thrown the problem to our own application solution. So here are a few common ways to improve the results of eventual consistency.

Using local transactions

Or an example of the above order deduction.

Order service open Local transaction, first add order;
Then the order created event is inserted into a special event table, the transaction commits;
There is a separate scheduled task thread that periodically scans the event table, sweeps it out to be sent and drops it to MQ, and sets the event to "sent".

The advantage of the scheme is that the transaction of the local database is used, and if the event is not successfully inserted, then the order is not created, and the thread scans the event to be sent, and ensures that the message is not leaked (our goal is to prefer to resend, not to miss, because event processing is designed to be idempotent).
The disadvantage is that the event should be handled separately in the business logic, cumbersome and easy to forget; event send some lag, time scan performance consumption is large, and will produce high water level hidden danger of database;

We made a slight improvement by using the database-specific MySQL binlog tracking (Ali's Canal) or Oracle's Goldengate technology to get notification of changes to the database's event table so that the scheduled task could be avoided by scanning the

However, the use of these database log tools, and specific database implementation (even a specific version) binding, the decision-making time please be cautious.

Use event Sourcing to trace events

Event traceability is a special idea for us, he does not persist the entity object, but only the initial state and the event of each change is recorded, and in memory based on the event to restore the entity object's latest state, the implementation is similar to the implementation of database Redolog, It's just that he put this mechanism into the application layer.

Although the traceability of events has many claimed advantages, the introduction of this technology to be particularly careful, first of all, he is not necessarily suitable for most business scenarios, once changed a lot of cases, the efficiency is really a big problem, and some query problems are also troubled.

We only explore the use of event souring and axonframework in individual business, and because of the complexity of implementation, the specific situation will need to wait until the practice period of time to summarize, may need an additional article to describe in detail

These are some of my understanding of event-driven in the microservices architecture, and the article partly draws on Chris Richardson's blog,https://www.nginx.com/blog/ Event-driven-data-management-microservices/I would like to express my thanks to him here.

More research architecture, less Framework (3): Event-driven architecture

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.