1. Design patterns derived from life
There is a place in our life that we are reluctant to go to but have to go to is the hospital. When we go to the hospital to see a doctor, we need to go through the following procedures:
Step 1: Register
Step 2: Wait for your call
Step 3: Find the corresponding doctor to tell the disease, the doctor according to the symptoms of the test sheet
Step 4: We bring the test sheet and use the equipment to test
Step 5: After the test results come out, we need to take the test sheet and go to the doctor
Step 6: The doctor will prescribe the right medicine based on the test results.
Everyone don’t want to go to the hospital, because we go to a hospital is very troublesome, through the above process was the time of day, wait your turn in all the process and result such as test time is longest, likely to be several days to some paper, paper after also need to be lined up to let the doctor see the results.
As a patient, we hope to have one-to-one service after arriving at the hospital, and corresponding doctors will follow us for the whole process.
However, how would we think about this problem as hospital managers? The number of doctors and equipment in a hospital is limited, but there are many patients every day, basically dozens of times as many as doctors. How can we use the limited resources of doctors and equipment to solve the problems of more patients?
Suppose a hospital has 10 doctors and 20 devices. It takes 10 minutes for the doctor to perform step 3, 10 minutes for step 6, 20 minutes for the device to perform step 4, and 20 minutes for step 5. If the doctor receives the patient and gives the patient a test sheet, then waits for the patient to get the result and gives the patient medicine, and then sends the patient away, it will be very time-consuming for the doctor to follow the patient from the third step to the sixth step. It takes 10+20+20+10=60 minutes for a doctor to see a patient, and only 8 patients can be treated in 8 hours a day. A hospital can only handle 108=80 patients per day. But if the doctor after finish among the patients to test the next hung over for a number of patients, namely after executing the step 3, doctors can continue to perform step 2, nobody patients to get the paper after that executes the step 5 can then went to the doctor to perform step 6, thus make full use of the resources, A doctor seeing a patient only requires effort steps 3 and 6 no, it takes 10+10=20 minutes to see 860/20=24 patients per day, and the whole hospital can see 1024=240 patients per day. This is the core idea of Reactor design pattern, which solves the one-to-many problem and greatly improves the utilization rate of resources.
C/C++, Linux, Golang technology, Nginx, ZeroMQ, MySQL, Redis, Fastdfs, MongoDB, ZK, Streaming media, CDN, P2P, K8S, Docker, TCP/IP, coroutine, DPDK, FFMPEG, etc.)
2 Reactor design pattern implementation
NIO is a classic case, use the reactor design pattern is very traditional IO client over a connection, the server will need a thread to handle, each thread will be an interactive operation all processing is complete, including read and return, on the surface to be connected is not in the thread, but if the thread is not enough, new connections will not be processed. So a thread is responsible for connecting, reading, and writing.
In the case of massive concurrency in this processing mode, even the introduction of thread pools cannot meet the needs. At this time, consider dividing a complete request into several small tasks, just as hospitals separate doctor’s visits and instrument checks. Each small task is non-blocking, and NIO is used for reading and writing operations. So we split a connection operation into multiple tasks, each of which is non-blocking, which is a huge increase in efficiency, but it also increases the number of threads in the thread pool, but it’s much simpler and has a single task, kind of like our microservice idea.
Reactor can be subdivided into: Reactor single-thread model, Reactor multi-thread model, Reactor master-slave model from the choice of thread pool and Reactor.
2.1 Reactor single thread model
The single-threaded model uses a dedicated thread to process client requests. This thread loops to listen for incoming client requests and, once received, dispatches them to the appropriate processing thread for processing. This pattern adopts an event-driven design, which only invokes the processor for data processing when an event is triggered. The Reactor pattern allows you to control the number of threads, allowing a single thread to process a large number of events.
2.2 Reactor multithreaded model
Using one thread can support all I/O processing, but the bottleneck is also obvious. If the client processes multiple requests slowly in the business thread, the subsequent clients will be backlogged, resulting in slow response, so we need to introduce the Reactor multi-threaded model.
You can introduce worker threads into thread pools, put processor execution into thread pools, and use multithreading to process business logic.
2.3 Reactor master-slave model
For machines with multiple cpus, the Reactor is split in two to maximize system resources.
1) The Main Reactor is responsible for monitoring connections, and sends the monitored connections to the Sub Reactor for processing. The Main Reactor responds to connection requests.
2) The Sub Reactor processes connections, from which the Reactor processes IO requests.
3 Architecture Model
Handle: Indicates the Handle of the operating system. It can be an open file, a Socket connection, or a Timer.
Synchronous Event Demultiplexer: Synchronous Event Demultiplexer waits for events in Handles to occur.
Initiation Dispatcher, which provides methods for registering, deleting, and forwarding Event Handlers
Event Handler: Interface to the Event Handler
Concrete Event Handler: The actual implementation of the Event Handler, with a Handle bound. Because in practice we tend to have more than one event handler, we separate the interface and implementation of the event handler, similar to polymorphism in high-level languages such as C++ and Java.
— — — — — — — —