You can't do things in a hurry, you have to do things asynchronously;
1. Business Scenario
In the process of system development, there must be extremely time-consuming actions, which are problems that cannot be solved based on the request-response mode. Usually, decoupling thinking is adopted, and the complete execution of the entire process is scheduled based on asynchronous or event-driven methods;
File task : When the system parses large file data, after obtaining the task, it will asynchronously process the subsequent file reading and writing process;
Intermediate table : When performing data analysis of complex scenarios, after collecting the objects to be analyzed, the collection actions of each dimension will be executed concurrently, and the data will be written into a temporary intermediate table in turn to facilitate data query operations;
In the above scenario, the entire process cannot be executed based on a single request response, and the process must be advanced step by step and asynchronously. In the process, it is judged according to the scene, whether it is asynchronous orderly driven or asynchronous concurrent processing, and based on each node's The execution state determines whether the action is successful.
2. Task management
The execution cycle of complex tasks is relatively long. To ensure stable execution, fine design and management of tasks are required. Usually, tasks are described based on the following factors:
- Scenario: Define the theme scenario of the task, which is convenient for unified management and scheduling of various tasks, such as: files, data, reports, etc.;
- Planning: Split tasks into steps, and formulate and promote corresponding execution plans, such as orderly scheduling, concurrent execution, etc.;
- Status: For the execution plan of tasks and nodes, detailed status definitions must be provided, such as: start/end, in progress/completed, success/failure, etc.;
Design a reasonable task structure to manage the process more efficiently, classify tasks according to theme scenarios, add corresponding execution plans, track task execution processes according to status, and capture and retry failed actions;
3. Design ideas
1. Synchronous request response
The communication modes between services are generally divided into two types: synchronous and asynchronous; synchronous means that after the requester sends an action, it will wait for the response to complete, or the response times out and cause a fuse, that is, coupling all processing processes in one request call ;
Most of the requests in the service are in the synchronous response mode, which can improve the response speed of the system; however, in the distributed mode, the first thing to do is to control the time of the timeout and fuse, so as to avoid the accumulation of requests during peak traffic periods and drag down the entire service; The public service to be called should improve the support ability of concurrency and reduce the performance impact on the request link.
2. Asynchronous decoupling mode
The biggest advantage of the asynchronous mode is to achieve complete decoupling of requests and responses. The task only needs to trigger the start action once, and the subsequent process will gradually advance until the end; the processing logic of each service node will not be limited by the time-consuming of the entire request link. ;
There are many ways to achieve asynchrony, such as: request callback, publish and subscribe, broker proxy, etc.; it is described in detail in the previous asynchronous chapter, and will not be repeated here; asynchrony eliminates the dependency between service nodes, but also improves the process complexity;
3. Event-driven design
Event-driven is an abstract concept, that is, the collaboration between multiple services is realized through events, and the processing logic of the entire process is driven; at the business level, it is a design idea. At the technical level, the publish-subscribe method is usually adopted. Eliminate strong dependencies between services;
Events and asynchrony are similar in mode, and event-driven is more refined in design. For example, in the order scenario: the status change of the order is regarded as an event, and the services are processed in turn through message transmission. Inventory services, logistics services, etc.; Events carry certain business information and status, and the process decoupling will be more thorough and the complexity will be higher.
4. Summary of Practice
1. Structural design
In the structural design, the three core elements of tasks, nodes and data are centered to ensure complete tracking and management of the execution process of tasks. To realize the nodes of the task and related operations, have the control of retrying or directly canceling the withdrawal. ;
State management is a very complex task. To measure whether each state identifier in a task is reasonable, it is necessary to monitor the changes of the state in real time, and verify the process based on various extreme conditions, such as retry design, task cancellation, and task suspension.
2. High concurrency management
Task-based scenarios and complex management processes naturally take a long time to execute. If the scenario involves parsing of large files or data scheduling, the mechanism of task segmentation and concurrent execution will naturally be introduced;
The more common idea is to perform hash calculation on the data core number according to the number of clusters scheduled by the task. Two algorithms of modulo and segmentation can be used, and then the tasks in charge of the respective services can be processed concurrently based on multi-threading.
3. Management model
Whether it is an observer mode, a publish-subscribe model, or an event-driven design, it can be understood as a production/consumption relational model, which is managed around the three nodes of production, storage, and consumption;
- Production side: responsible for creating a specific message body. In the bus mode, the message is usually stored in the library, and then the queue push is performed, and the state change of the process is tracked to ensure the consistency of the library and the queue;
- Message body: describe the publisher and consumer of the action, key status information changes, unique identifier, creation time and version, and the rest can be defined according to the needs of the scene;
- Consumer side: The core problem to be concerned about when consuming is failure retry. To avoid the problem of data inconsistency caused by the retry mechanism, you can lock the consumption or verify the message status to achieve an idempotent effect;
- Storage side: usually adopts the dual storage mode of database and message middleware, and needs to ensure that the two actions succeed or fail at the same time.
The entire model is relatively reasonable in terms of design ideas, but the complexity of the architecture has also become very high, such as data consistency issues, state mechanisms, transactions, idempotency, process interruption, etc.; the entire link needs detailed tracking records and visual management. , Develop the interface of compensation action to solve the unexpected problem in time.
4. Component case
The Spring framework itself is extremely complex. Here we only look at the design of the event model, which includes three core roles: event, publishing, and monitoring; it is the same in concept as the observer design pattern;
Event : The basic abstract class of ApplicationEvent inherits from the EventObject class in JDK, and the specific event should inherit from this class; the source event source, the system time of the timestamp;
public class OrderState {
// 基础要素
private Integer eventId ;
private String version ;
private Long createTime ;
// 消息定位
private String source ;
private String target ;
// 状态变化
private Integer orderId ;
private Integer stateFrom ;
private Integer stateTo ;
}
public class OrderStateEvent extends ApplicationEvent {
public OrderStateEvent (OrderState orderState){
super(orderState);
}
}
Publisher : The top-level interface ApplicationEventPublisher defined by Spring provides the ability to publish events;
@Service
public class EventService implements ApplicationContextAware, ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
public void changeState (Integer orderId,Integer stateFrom,Integer stateTo){
OrderState orderState = new OrderState() ;
OrderStateEvent orderStateEvent = new OrderStateEvent(orderState) ;
logger.info(Thread.currentThread().getName()+";"+orderStateEvent);
applicationEventPublisher.publishEvent(orderStateEvent);
}
}
Listener : Implements the top-level interface EventListener in JDK. Spring extends a variety of event listeners to meet the needs of various scenarios, such as: orderly and disorderly, synchronous and asynchronous, etc.;
@Component
public class OrderStateListener implements ApplicationListener<OrderStateEvent> {
private static final Logger logger = LoggerFactory.getLogger(OrderStateListener.class) ;
@Async
@Override
public void onApplicationEvent(OrderStateEvent orderStateEvent) {
logger.info(Thread.currentThread().getName()+";"+orderStateEvent);
}
}
5. Reference source code
应用仓库:
https://gitee.com/cicadasmile/middle-ware-parent
编程文档:
https://gitee.com/cicadasmile/butte-java-note
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。