A method and system for order state timeout driving and self-cleaning scheduling based on a delay queue
Patent Information
- Application Number
- CN202611315290.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-08-27
- Publication Date
- 2026-10-20
Smart Images

Figure FT_1 
Figure FT_2
Abstract
Description
Technical Field
[0001] This invention relates to the field of computer software development technology, specifically to a method and system for order status timeout-driven and self-cleaning scheduling based on a delayed queue, applicable to scenarios in pharmaceutical e-commerce and online diagnosis and treatment platforms for unified management and automatic scheduling of timeout status of multiple types of orders. Background Technology
[0002] In pharmaceutical e-commerce and online medical consultation platforms, orders go through multiple business states from creation to completion (such as pending payment, pending prescription review, pending shipment, outbound, pending receipt, etc.), and most states have timeout constraints: for example, pending payment orders should be automatically cancelled and the reserved inventory should be released if payment is not made within a specified time; prescription review results should be actively checked if they are not returned in time; and outbound orders should be automatically completed if receipt is not confirmed within a specified number of days.
[0003] Existing technologies generally employ a "database timed polling" approach to implement the aforementioned timeout handling: a scheduled task is written for each type of order, and the task starts at a fixed period (e.g., every minute), scans the corresponding order table, compares the order creation time or status change time with the current time for each order, filters out expired orders, and then executes cancellation, rollback, or completion logic for each one. Another existing technology uses a message middleware "dead-letter queue": when an order is created, a message with a set lifespan is sent to the message middleware. After the message expires, it is transferred to the dead-letter queue, and the consumer program retrieves the message from the dead-letter queue and triggers timeout handling.
[0004] The existing technology has the following drawbacks: (1) It is difficult to balance real-time performance and system pressure. The accuracy of timeout determination in database polling is limited by the polling cycle. Although shortening the cycle can improve real-time performance, it will result in high-frequency full table scans of the order table, and the database pressure will increase sharply as the order volume increases.
[0005] (2) Duplication of development and difficulty in reuse. The platform has its own timeout rules for various types of orders, such as prescription, procurement, application, consultation and delivery. Under the polling method, each type of order needs to develop a separate timed task and comparison logic. The code is duplicated and the rules are scattered. Adding a new type of timeout business requires redeveloping the entire set of scanning logic.
[0006] (3) High cost of querying remaining waiting time. The front-end page needs to display countdown information such as "remaining payment time of the order" to the user. In the existing implementation based on delayed queue, querying the expiration time of a certain order requires using a script to traverse the internal linked list of the queue and unpack and compare them one by one. The complexity of a single query is proportional to the length of the queue. When the page displays in batches, the overall cost is close to quadratic. When the queue is backed up, the query becomes significantly slower or even times out.
[0007] (4) The residual messages in the queue expand indefinitely. If an order is paid, canceled, or completed in advance before the delayed message expires, the delayed message in the queue will not disappear. It will still trigger an invalid consumption after the expiration. After long-term operation, a large number of residual messages corresponding to the final state order will accumulate in the queue, which wastes storage and increases the overhead of invalid processing.
[0008] (5) Message loss during the initial application startup. The transfer of delayed messages depends on the transfer logic registered when the consumer subscribes. If the consumer has not completed registration after the application restarts, messages that expire during the period cannot be transferred and consumed, resulting in omissions in timeout processing, such as orders remaining in a pending payment state or locked inventory that cannot be released. Summary of the Invention
[0009] To overcome the aforementioned technical problems in the prior art, this invention provides a method and system for order status timeout driving and self-cleaning scheduling based on a delayed queue. This aims to solve the problems of repetitive development and difficulty in reusing multiple types of order timeout rules; the high complexity of remaining waiting time queries and poor batch display performance; the problem of infinite expansion of residual messages in the delayed queue; and the problem of lost delayed messages during application restarts.
[0010] To achieve the above objectives, this invention provides a timeout-driven order status method based on delayed queues, comprising: maintaining a queue registry on the server side, wherein the queue registry statically registers multiple delayed queue entries in an enumerated manner, each entry containing a mapping relationship between a queue key, a business description, and a timeout business event type, wherein multiple event classes corresponding to the timeout business event type all contain an order number attribute and a target status attribute and share the same construction signature; when a business node needs to set a timeout constraint for an order, a unified delivery entry is invoked, passing in the order number, target status, delay duration, and queue identifier; the combination of the order number and the target status is used as a composite delayed message identifier, wherein the composite delayed message identifier... The format is "order number#target status". A delayed message carrying the composite delayed message identifier is delivered to the delayed queue corresponding to the queue identifier. After the delayed message expires, the composite delayed message identifier is retrieved from the delayed queue, and the order number and target status are reconstructed by splitting it according to the delimiter. The corresponding timeout business event type is searched in the queue registry based on the queue identifier. The constructor corresponding to the timeout business event type is called via reflection, passing the order number and target status as arguments. A business event object carrying the order number and target status is constructed and published to the application's event bus. Each business listener executes the corresponding timeout processing logic according to the target status branch.
[0011] Preferably, the plurality of delay queues include the following six types of queues: prescription order delay queue, purchase order delay queue, dressing order delay queue, consultation order cancellation delay queue, prescription order outbound delay queue, and paid consultation order delay queue.
[0012] Preferably, a deduplication check is performed before delivery: using the composite delayed message identifier as a field, an atomic operation in the in-memory database is used to determine whether the composite delayed message identifier already exists in the expiration time index table. If it already exists, the delivery is abandoned; if it does not exist, a delayed message is simultaneously delivered to the delayed queue and the corresponding mapping relationship is written to the expiration time index table. The atomic operation includes at least one of the following methods: a distributed lock based on the in-memory database, an HSETNX atomic command in the in-memory database, or a Lua atomic script executed by the in-memory database server.
[0013] Accordingly, the present invention also provides a method for querying the remaining waiting time of delayed messages in a delayed queue, comprising: when delivering a delayed message, adding the delayed message carrying the composite delayed message identifier to the delayed queue, and simultaneously writing the composite delayed message identifier and the corresponding expiration timestamp into an independent expiration time index table, wherein the composite delayed message identifier is composed of an order number and a target status; upon receiving a remaining waiting time query request for a target order, constructing a target composite delayed message identifier based on the order number and target status of the target order; and using the target composite delayed message identifier as a key to query whether a corresponding expiration time exists in the expiration time index table. The system calculates the remaining waiting time based on the expiration timestamp if a match is found and the current time has not exceeded the expiration timestamp. If a match is found and the current time has exceeded the expiration timestamp, the corresponding index entry in the expiration timestamp index table is deleted and zero is returned. If no match is found, an atomic script executed by the in-memory database server iterates through all elements of the delay queue at once on the server side. The script takes the target composite delay message identifier as input parameter, returns the score of the matching element as the expiration timestamp after the traversal is completed, fills the expiration timestamp back into the expiration timestamp index table, and calculates the remaining waiting time based on the expiration timestamp and returns it.
[0014] Preferably, the delayed queue is constructed based on the following data structures of the in-memory database: an ordered set sorted by expiration time, a list storing unexpired messages in delivery order, and a blocking queue for blocking retrieval by the consumer; the expiration time index table is a hash table independent of the above three data structures, the field of the hash table is the composite delayed message identifier, and the value is the corresponding expiration timestamp, and the complexity of a single query of the hash table is constant.
[0015] Accordingly, the present invention also provides a method for cleaning up residual messages in a delayed queue, comprising: maintaining a delayed queue and a corresponding expiration time index table, wherein the expiration time index table stores a mapping relationship between composite delayed message identifiers of delivered delayed messages and their corresponding expiration timestamps, wherein the composite delayed message identifier is composed of an order number and a target status; periodically triggering a cleanup task to read all composite delayed message identifiers from the expiration time index table and parse out the order number corresponding to each composite delayed message identifier; determining the corresponding business order table according to the queue type of the delayed queue, and performing a batch query using a single "field IN (set of order numbers)" statement. The system performs a reverse lookup of the order status corresponding to the order number in the business order table; it then identifies the composite delayed message identifier corresponding to the order whose status has entered the final state as the pending cleanup identifier. The final state is defined according to the queue type: the final state of the prescription order queue includes pending receipt and cancelled; the final state of the prescription order outbound queue includes completed; the final state of the purchase order queue and the dressing order queue includes completed and cancelled; and the final state of the consultation order queue includes ended, rejected, and various timeout closures. Finally, it deletes the delayed message corresponding to the pending cleanup identifier from the delayed queue and deletes the index entry corresponding to the pending cleanup identifier from the due date index table.
[0016] Preferably, the timed cleanup task is triggered by a configurable timed expression. When an exception occurs in the cleanup of a single queue, only the error information of that queue is recorded, without interrupting the cleanup process of the remaining queues. The reading of all composite delayed message identifiers from the expiration time index table is performed at a constant level, without touching the internal structure of the delayed queue.
[0017] Accordingly, the present invention also provides an order status timeout-driven system based on delayed queues, comprising: a queue registry for statically registering multiple delayed queue entries in an enumerated manner, each entry containing a queue key, a business description, and a mapping relationship of timeout business event types, wherein multiple event classes corresponding to the timeout business event types all contain an order number attribute and a target status attribute and share the same construction signature; a delayed event scheduling center for providing a delayed event delivery entry, a remaining time query entry, and a delayed event removal entry, wherein the delayed event scheduling center is connected to a delayed queue group and an expiration time index table in a memory database; the delayed event delivery entry uses a combination of order number and target status as a composite delayed message identifier for delivery, and performs deduplication before delivery: using the composite delayed message identifier as a field, the atomic operation of the memory database determines whether the composite delayed message identifier already exists in the expiration time index table; if it already exists, the delivery is abandoned; if it does not exist, a delayed message is simultaneously delivered to the delayed queue and the corresponding mapping relationship is written to the expiration time index table; the atomic operation of deduplication includes at least one of the following methods: a distributed lock based on a memory database, memory... The system includes: HSETNX atomic commands for the database and Lua atomic scripts executed by the in-memory database server; an expiration time index table, which maintains an independent hash mapping table for each delayed queue in the in-memory database, storing the mapping relationship between composite delayed message identifiers and corresponding expiration timestamps, wherein the composite delayed message identifier is composed of an order number and a target status; an event consumer dispatcher, used to traverse all entries in the queue registry when the application is ready to start, pre-create queue objects for each delayed queue corresponding to each entry and start independent asynchronous consumption threads, so that the queue objects and consumption threads are registered before any business delivery occurs; and after a delayed message expires, it retrieves the composite delayed message identifier from the delayed queue, splits it according to the delimiter to restore the order number and target status, finds the corresponding timeout business event type according to the queue registry, constructs the business event object by calling the corresponding constructor method through reflection and publishes it to the application's event bus; and a final state reverse cleaner, used to periodically read all composite delayed message identifiers from the expiration time index table, batch reverse-search the business order database according to the queue type, and synchronously delete the delayed messages corresponding to orders whose order status has entered the final state from the delayed queue and the expiration time index table.
[0018] Preferably, the delayed event removal entry provided by the delayed event scheduling center is used by the business party to call the removal entry when an order is paid, canceled, or manually processed before the delayed message expires. At the same time, the delayed event scheduling center deletes the corresponding delayed message from the delayed queue and deletes the corresponding index entry from the expiration time index table.
[0019] Preferably, the event consumer dispatcher performs classified exception capture and isolation processing on the reflection construction process: it captures five types of exceptions respectively: instantiation exception, illegal access exception, constructor method non-existent exception, exception thrown inside the constructor method, and thread interruption exception; when any exception occurs, the context is recorded, including the queue key and the original message content that caused the failure; the reflection failure only affects the current message, does not affect the retrieval and consumption of subsequent messages in the same queue, and does not affect the consumption threads of other queues.
[0020] The present invention has at least the following technical effects through the technical solution provided by the present invention: This invention binds the composite delayed message "order number#target status" to the queue registry's <queue, event type>, allowing heterogeneous business processes such as timeout cancellation, timeout callback, timeout completion, and automatic refund for six types of orders to share the same delivery, consumption, query, and cleanup process. Adding a new timeout business only requires registering one enumeration item and writing a listener, eliminating the need for redeveloping scanning and scheduling logic, significantly reducing development and maintenance costs. The independent expiration time index table in this invention eliminates the need to traverse the internal linked list of the queue for single order countdown queries, reducing the overall complexity of batch display scenarios from near quadratic to linear. Simultaneously, the "missed hit rollback and backfilling" mechanism ensures that existing delayed messages are compatible without any data migration at launch, representing a performance improvement that can be smoothly rolled out. The final state reverse cleanup in this invention uses the final state of orders in the business database as a benchmark to reverse-delete residual messages in the queue, ensuring that the long-term volume of the delayed queue is related to the number of orders in transit rather than the total historical order volume; it also reduces the overhead of invalid consumption after expiration. Consumers and queue objects register before any business delivery when the application is ready. Messages expiring within the restart window can still be processed and consumed normally, avoiding asset losses such as orders remaining in an intermediate state and inventory not being released. The scheduling center distributes timeout notifications to the business side via events. Business processing failures do not block queue consumption. Combined with delivery deduplication and proactive removal, the eventual consistency of timeout processing is guaranteed in a distributed environment. Attached Figure Description
[0021] The accompanying drawings are provided to further illustrate embodiments of the present invention and form part of the specification. They are used together with the following detailed description to explain the embodiments of the present invention, but do not constitute a limitation thereof. In the drawings: Figure 1 This is a flowchart of the order status timeout-driven and self-cleaning scheduling method based on a delayed queue provided in an embodiment of the present invention; Figure 2 This is a block diagram of an order status timeout driving system based on a delay queue provided in an embodiment of the present invention. Detailed Implementation
[0022] The specific embodiments of the present invention will be described in detail below with reference to the accompanying drawings. It should be understood that the specific embodiments described herein are for illustration and explanation only and are not intended to limit the scope of the present invention.
[0023] In this invention, the terms "system" and "network" are used interchangeably. "Multiple" refers to two or more; therefore, in this invention, "multiple" can also be understood as "at least two." "And / or" describes the relationship between related objects, indicating that three relationships can exist. For example, A and / or B can represent: A alone, A and B simultaneously, or B alone. Additionally, the character " / ", unless otherwise specified, generally indicates that the preceding and following related objects have an "or" relationship. Furthermore, it should be understood that in the description of this invention, terms such as "first" and "second" are used only for descriptive purposes and should not be construed as indicating or implying relative importance or order.
[0024] Please see Figure 1 This invention provides a method for order status timeout-driven and self-cleaning scheduling based on a delayed queue, comprising the following steps: Step S1: Static queue registration and consumer pre-registration A queue registry is maintained on the server side. This registry statically registers entries for multiple delayed queues using an enumeration method. Each entry contains a mapping between a queue key, a business description, and a timeout business event type. Multiple event classes corresponding to the timeout business event type all contain order number and target status attributes and share the same constructor signature. When the application is ready to start, it iterates through all entries in the queue registry, first creating a delayed queue object for each queue and placing it in the global queue cache. Then, an independent asynchronous thread is started to listen to the corresponding blocked queue in a blocking mode. Because the queue object is created and the message delivery logic is registered before any business delivery occurs, the lost window of "messages expiring and not being delivered" during the initial application restart is eliminated; then step two is executed.
[0025] In this embodiment of the invention, the queue registry statically registers six entries in an enumeration format, with the following triples <queue key, business description, and event type> as follows: ①〈pharmacy:delay:prescribe, prescription order, prescription order timeout event class〉; ②〈pharmacy:delay:purchase, purchase order, purchase order timeout event class〉; ③〈pharmacy:delay:pastepurchase, patch order, patch purchase order timeout event class〉; ④〈pharmacy:delay:inquiryordercancel, consultation order, consultation order timeout event class〉; ⑤〈pharmacy:delay:openOrderOutbound, the timeout event class for pharmacy order outbound; ⑥〈pharmacy:delay:inquiryorderalreadypay, paid consultation order, paid consultation order timeout event class〉.
[0026] The six event classes mentioned above follow a unified construction convention: they are all ordinary data carrier classes, each containing only two attributes—order number (long integer) and target status (integer), and each exposing a consistent two-parameter constructor method: "(long integer order number, integer target status)". After retrieving the composite identifier and splitting it according to the delimiter to restore the order number and target status, the consumer thread constructs the event object using a reflection call sequence of "getting the declared constructor method (long integer type, integer type) → passing in the actual parameters to create an instance". Because all event classes share the same construction signature, the scheduling center can complete the general construction without being aware of any specific event type, which is the basis for the decoupling between the scheduling layer and the business layer.
[0027] The event listener employs a mechanism of "declarative annotations + automatic scanning and registration during container startup," eliminating the need for any hard-coded binding within the scheduling center. Specifically: each business service class's processing methods are annotated with event listener annotations, and the method's unique input parameter type declares the event types it is interested in. During the startup scanning phase, the microservice development framework's container parses all methods annotated with this annotation, establishes a mapping table of "event type → listener method" based on the input parameter type, and registers it with the application's in-system event bus. Upon receiving an event object, the runtime event bus matches it to the mapping table according to its actual runtime type and calls back the corresponding listener method. This mechanism inherently supports one-to-many—the same event type can be subscribed to by multiple listeners simultaneously (e.g., the order timeout event can be subscribed to by both order cancellation processing and inventory rollback processing), and it also supports independent addition and deletion of listeners without affecting the scheduling center code. Therefore, adding a new type of timeout business only requires two steps: adding an enumeration entry to the queue registry and writing a processing method annotated with the listener annotation; the rest of the delivery, handling, consumption, querying, and cleanup processes are completely reused.
[0028] Step S2: Delayed Event Delivery When a business node (such as a doctor submitting a prescription, placing a purchase order, order fulfillment, or patient consultation) needs to set a timeout constraint for an order, it calls a unified delivery entry point, passing in the order number, target status, delay duration, and queue identifier. The combination of the order number and target status serves as the composite delayed message identifier, with the format "order number#target status". The delayed message carrying the composite delayed message identifier is delivered to the delayed queue corresponding to the queue identifier, and simultaneously, the composite delayed message identifier and its corresponding expiration timestamp are written to a separate expiration time index table, forming a "queue + index" dual accounting system.
[0029] Before delivery, a deduplication check is performed: using the composite delayed message identifier as a field, an atomic operation in the in-memory database is used to determine whether the composite delayed message identifier already exists in the expiration time index table. If it already exists, the delivery is abandoned; otherwise, the delayed message is simultaneously delivered to the delayed queue and the corresponding mapping relationship is written to the expiration time index table. The atomic operation includes at least one of the following methods: a distributed lock based on the in-memory database, an HSETNX atomic command in the in-memory database, or a Lua atomic script executed by the in-memory database server.
[0030] In this embodiment of the invention, when a business node (such as a doctor submitting a prescription, placing a purchase order, order dispatching, or consultation) needs to set a timeout constraint for an order, it calls the unified delivery entry point, passing in the order number, target status, delay duration, and queue identifier. The scheduling center uses "order number#target status" as a composite delayed message identifier, first checking for duplicates in the queue—only one delayed message for the same order and target status is allowed to exist to prevent duplicate delivery and duplicate timeout processing; after the duplicate check is passed, the composite identifier is added to the delayed queue, and <composite identifier → expiration timestamp> is simultaneously written to the expiration time index table of the queue, forming a "queue + index" dual accounting.
[0031] This embodiment guarantees the atomicity of deduplication and delivery on three levels: The first layer—distributed mutual exclusion of business entry points—ensures that all business entry points that trigger delayed event delivery (such as doctors submitting prescriptions, patients placing purchase orders, order fulfillment, and patient consultations) are protected by a distributed lock based on an in-memory database. A fair lock is requested using "business type + order number" as the lock key. Only after successful acquisition can the business process begin and delayed events be delivered. The lock is released after processing is complete. Since concurrent requests for the same order are serialized at the entry point, deduplication and delivery are within the same critical section, naturally possessing atomicity.
[0032] The second layer—atomic write semantics for the index hash table—allows the writing of the expiration time index hash table to utilize the HSETNX atomic command (write only if the field does not exist) in the in-memory database. Executing HSETNX with the composite identifier "order number#target status" as the field results in a return value of 1, indicating this is the first registration, and the message is then sent to the delayed queue; a return value of 0 indicates that the delayed event for this order and target status already exists, and the current attempt is abandoned. Because HSETNX is a single-command atomic operation on the in-memory database server, only one node can successfully write in a multi-node concurrent environment, thus ensuring the atomicity of deduplication and registration even in lock-free scenarios.
[0033] The third layer—server-side atomic scripts—is a fallback. If the three actions of "duplicate checking → queue submission → index writing" need to be strictly bound into an indivisible operation, it can be encapsulated into a Lua script, executed by the in-memory database server in a single thread. The script first checks if the composite identifier exists in the index hash table; if not, it sequentially executes the ZADD operation of the sorted set and the HSET operation of the index hash table; if it exists, it returns directly. The execution of Lua scripts in an in-memory database inherently possesses atomicity, completely eliminating the time window between checking and writing.
[0034] This embodiment uses a combination of the first and second layers to balance performance and correctness; the third layer serves as an enhanced implementation method for high-concurrency scenarios.
[0035] The criteria for deduplication are not stored in the local memory of any application node, but are centrally stored in an expiration time index hash table and a delayed queue structure in a shared in-memory database. Therefore, the deduplication results are consistently visible to all application nodes. Although application nodes maintain a local cache mapping of queue objects, this mapping only caches the client handles of the queues (to avoid duplicate connection object creation) and does not cache any message content. The `contains` and `HSETNX` calls during deduplication are actually sent to the in-memory database server for execution. Furthermore, the composite delayed message identifier consists of "order number + separator + target status". The order number is generated by a distributed unique sequence number generation algorithm and is globally unique. Therefore, this identifier can uniquely identify a delayed event across the entire cluster, and there are no identifier conflicts or semantic ambiguities between nodes.
[0036] In this embodiment of the invention, the delay queue in the in-memory database is composed of four types of data structures working together, each with the following responsibilities: (1) A sorted set of expiration times (ZSET), with keys in the form of redisson_delay_queue_timeout:{queue key}, members being the delayed message body, and a score representing the absolute expiration timestamp in milliseconds. This structure is responsible for "sorting by time and determining which message expires first".
[0037] (2) Delayed message list (LIST), with key names in the form of redisson_delay_queue:{queue key}, stores all unexpired message bodies in the delivery order, used for message location and overall traversal.
[0038] (3) Target blocking double-ended queue (LIST), the key name is the queue key itself (in this embodiment, the keys of the six queues are pharmacy:delay:prescribe, pharmacy:delay:purchase, pharmacy:delay:pastepurchase, pharmacy:delay:inquiryordercancel, pharmacy:delay:openOrderOutbound, pharmacy:delay:inquiryorderalreadypay). After the message expires, the server script moves it from the ordered set to this list, and the consumer thread retrieves the message from the list in a blocking manner.
[0039] (4) Expiration time index hash table (HASH), with key names in the form of pharmacy:delay:expire:{queue key}, and fields that are composite delayed message identifiers "order number#target status", with values being the absolute expiration timestamp in milliseconds for the message. This structure is a newly added independent index in this scheme, which is the key to realizing constant-level query of remaining waiting time and reverse cleanup of final state, and is also one of the core structures that distinguish this scheme from the general delayed queue implementation.
[0040] The above (1), (2), and (3) are the basic structures for delayed delivery and transportation, and (4) is the independent index layer superimposed on it in this scheme. The two are written synchronously during delivery, forming a "queue + index" dual accounting.
[0041] This embodiment uses the open-source distributed collaboration component Redisson (version 3.23.5, integrated via redisson-spring-boot-starter) to implement a distributed delayed queue and a distributed lock. Specifically: RBlockingDeque is used to obtain the target blocking double-ended queue, and RDelayedQueue is used to build a delayed queue on top of it. Redisson implements the atomic operation of "moving expired messages from the ordered set to the blocking queue" on the server side using Lua scripts; RMap is used to operate the expiration time index hash table; and RLock (reentrant lock) and RFairLock (fair lock) are used to implement cross-node mutual exclusion collaboration. Message encoding and decoding uses a custom FastJsonCodec codec. Similarly, Redisson is only one implementation option in this embodiment; other distributed collaboration components with equivalent capabilities (such as a distributed queue using Curator + ZooKeeper, or a self-encapsulated transport logic in Lua scripts) can also be used to implement this solution.
[0042] Step S3: Expired Consumption and Event-Based Distribution After a delayed message expires, the composite delayed message identifier is retrieved from the delayed queue and split according to the delimiter to restore the order number and target status. Based on the queue identifier, the corresponding timeout business event type is searched in the queue registry. The constructor corresponding to the timeout business event type is called via reflection, passing the order number and target status as arguments. A business event object carrying the order number and target status is constructed and published to the application's event bus.
[0043] Each business listener executes the corresponding timeout handling logic according to the target status branch: if a prescription order times out in the pending payment status, the order is cancelled and the inventory management system is notified to roll back and lock the inventory; if the prescription review status expires, the review results are proactively queried from the Internet hospital; if a 15-day period expires for an outbound order, it is automatically marked as completed; and if a paid consultation order is issued, it is automatically refunded or automatically completed according to different status branches such as doctor not seeing the patient or not replying.
[0044] In this embodiment of the invention, after a delayed message expires, it is automatically transferred to a blocking queue. The consuming thread retrieves the composite identifier, splits it according to the delimiter to restore the order number and target status, and then constructs a business event object carrying the <order number and target status> using reflection based on the event type registered in the queue registry, and publishes it to the application's event bus. Each business listener processes the order according to the target status branch: if a prescription order times out in the pending payment state, the order is canceled and the inventory management system is notified to roll back and lock the inventory; if the prescription review status expires, the review result is actively queried from the internet hospital; if a pre-shipped order expires in fifteen days, it is automatically marked as completed; if a paid consultation order is processed, it is automatically refunded or automatically completed according to different status branches such as doctor not seeing the patient or not replying. The scheduling center is unaware of any business semantics; adding a new type of timeout business only requires adding a registration entry to the registry and implementing the corresponding event listener.
[0045] The consumer thread performs categorized exception handling and isolation in the reflection construction process. The specific degradation strategy is as follows: (1) Exception classification and capture. Four types of reflection exceptions are captured separately: instantiation exception, illegal access exception, constructor non-existent exception, and exception thrown inside the constructor, as well as interruption exception when the consumer thread is blocked and waiting. This avoids swallowing exceptions in a general way, which would make the problem unlocatable.
[0046] (2) On-site record. When any anomaly occurs, the complete scene is immediately recorded at the error level, including the queue key of the queue to which it belongs, the original message content that caused the failure (i.e., composite identifier) and the complete anomaly stack. The operation and maintenance side can use this to accurately locate the specific queue and specific order, and manually compensate through the management interface.
[0047] (3) Single message isolation and queue-level isolation. Reflection failure only affects the current message and does not affect the retrieval and consumption of subsequent messages in the same queue, nor does it affect the operation of the independent consumption threads of the other five queues; since the consumption threads of each queue are independent of each other, an event-type exception in a certain queue will not spread to a global failure.
[0048] (4) Pre-registration verification of registration items. The queue registry is a static enumeration determined at compile time. The event type is bound and verified during the compilation phase. The case of non-existent class or mismatched constructor signature is discovered at compile time, and the probability of such exceptions occurring at runtime is extremely low. At the same time, a reachability pre-check can be performed on the event class constructor method of each registration item during the pre-registration phase of application startup. If the pre-check fails, an alarm will be issued at the startup phase, thus shifting the problem to the left.
[0049] (5) Manual and automatic compensation channels. For messages that fail to be processed due to reflection failure, their entries in the expiration time index hash table are still retained. Therefore, the daily final state reverse cleanup task can identify and count such remnants. For orders that need to be reprocessed, compensation can be achieved by re-delivering the delay event by order number through the management interface or by directly triggering the corresponding business event.
[0050] Step S4: Constant-level query of remaining wait time Upon receiving a query request for the remaining waiting time of a target order, a target composite delay message identifier is constructed based on the target order number and target status. Using this identifier as the key, the system checks if a corresponding expiration timestamp exists in the expiration time index table. If a match is found and the current time has not exceeded the expiration timestamp, the remaining waiting time is calculated based on the expiration timestamp and returned. If a match is found and the current time has exceeded the expiration timestamp, the corresponding index entry in the expiration time index table is deleted, and zero is returned.
[0051] If no match is found, the atomic script executed on the in-memory database server will traverse all elements of the delay queue at once. The script takes the target composite delay message identifier as the input parameter. After traversal, it returns the score of the matching element as the expiration timestamp, fills the expiration timestamp back into the expiration time index table, and calculates the remaining waiting time based on the expiration timestamp and returns it.
[0052] In this embodiment of the invention, when the front-end queries the order countdown, the scheduling center directly reads the expiration time index table using a composite identifier: if the result is a match and the order has not yet expired, the expiration time is returned directly, with a single query being constant-level; if the result is a match but the order has expired, the index entry is lazily deleted and zero is returned; if the result is a match, the system reverts to the old version of the traversal query—using a script to traverse the internal linked list of the delayed queue, unpacking and comparing each entry to obtain the expiration time, and then filling the result back into the index table, so that subsequent queries for the existing orders return to the constant-level main path. After the existing messages are filled back and naturally disappear upon expiration, the revert path can be taken offline, achieving a smooth migration between the old and new structures. Lazy deletion is only triggered during the query. If no one queries an order after it expires, and the index entry will remain permanently, lazy deletion itself is indeed insufficient to cover the "no one queries" scenario. Therefore, this embodiment does not use lazy deletion as the only means of index entry recycling, but designs three complementary recycling paths to ensure that the index does not remain permanently: Path 1: Business-side proactive removal. When an order is paid for, canceled, or manually processed before the delay message expires, the business side calls the unified removal entry point, simultaneously deleting the element and the expiration time index from the delay queue; even if the queue element no longer exists, the index is forcibly cleared. This is the most important and widely applicable recycling path.
[0053] Path 2: Lazy deletion during query. This is only used as an incidental cleanup for items that happen to be found and have expired, and it is an opportunistic cleanup with zero additional cost, without any fallback responsibility.
[0054] Path 3: Daily Final State Reverse Cleanup. This is the true fallback path. A scheduled task iterates through all composite identifiers in the index hash table, reverse-checking the business order database. Any order that has entered the final state is simultaneously deleted from the queue and index, regardless of whether its index entry has been queried or expired. Therefore, any index entry that "has expired and has not been queried" will be reclaimed no later than the next cleanup cycle after its order enters the final state, with no permanent residue.
[0055] While there is some overlap between lazy deletion and scheduled cleanup tasks, there is no conflict, and this overlap is an intentional redundancy design. There are two reasons for this lack of conflict: First, both deletion operations are idempotent—when deleting a field from the index hash table, if the field does not exist, a null value is returned without an error, so regardless of which is executed first or how many times, the final result is consistent. Second, the key of the index item is a composite identifier "order number#target status," allowing for precise key positioning during deletion operations, preventing accidental deletion of other data being processed by the other. The value of this overlap lies in the fact that lazy deletion is a zero-cost, incidental cleanup on the online path, continuously reducing the index size between scheduled cleanups; scheduled cleanup provides a complete fallback on the offline path, ensuring no omissions. The combination of these two ensures that the size of the index hash table at any given time is related to the number of orders in transit, rather than the total number of historical orders.
[0056] The division of labor between lazy deletion and scheduled cleanup can be clearly distinguished according to four dimensions: "triggering time, judgment basis, cleanup scope, and responsibility positioning": (1) Lazy deletion is triggered online by front-end countdown query. The judgment basis is whether the expiration timestamp recorded in the index item is less than or equal to the current time (pure time judgment, without accessing the business database). The cleanup scope is limited to the index item hit in the current query. The responsibility positioning is online opportunistic cleanup; (2) Scheduled cleanup is triggered offline by scheduled task according to configurable scheduled expression (default is 3 am every day). The judgment basis is the final state of the order business obtained by reverse querying the business order database. The cleanup scope is all status messages of the final state orders in all six queue indexes. The responsibility positioning is offline complete fallback. The "script" here specifically refers to the Lua script executed on the in-memory database server, rather than the Java code on the application side. The reason for using a server-side script instead of an application-side loop is that if the queue elements were read and compared one by one on the application side, a network round trip would be required for each element compared. Traversing a queue of length N would result in N network round trips, which is unacceptable. In contrast, the Lua script is received by the in-memory database server and executed atomically in a single thread. The entire traversal process only requires one network round trip, and the data will not be modified by other commands during the traversal, ensuring that the expiration timestamp read is consistent with the queue elements.
[0057] Specifically, the script's logic is as follows: It uses the delayed message list key and the ordered set of expiration times key as input parameters, and the composite delayed message identifier to be queried as the input parameter value. The script first obtains the list length, then reads each list element sequentially from zero by index. For each element, it unpacks it according to Redisson's message encapsulation format (a packaged structure of random identifier + message body) to reconstruct the message body, and compares it with the input parameter identifier. If a match is found, the element is used as a member to read its score (i.e., the absolute expiration millisecond timestamp) from the ordered set of expiration times and returns immediately. If no match is found after the iteration ends, zero is returned.
[0058] Step S5: Proactive removal when ending early When an order is paid for, canceled, or manually processed before the due date of the delayed message, the business side calls the unified removal entry, deletes the corresponding delayed message from the delayed queue, and deletes the corresponding index entry from the due date index table; even if the queue element no longer exists, the index entry is forcibly cleaned up to avoid dirty data residue.
[0059] Step S6: Timed reverse cleanup of final state residue A cleanup task is triggered periodically to read all composite delayed message identifiers from the due date index table and parse out the order number corresponding to each composite delayed message identifier. Based on the queue type of the delayed queue, the corresponding business order table is determined, and a batch query statement using a single "field IN (order number set)" is used to retrieve the order status corresponding to the order number in the business order table.
[0060] The composite delayed message identifier corresponding to orders whose status has entered the final state is used as the cleanup identifier. The final state is defined according to the queue type: the final state of the prescription order queue includes "awaiting receipt" and "cancelled"; the final state of the prescription order outbound queue includes "completed"; the final state of the purchase order queue and the dressing order queue includes "completed" and "cancelled"; the final state of the consultation order queue includes "finished," "rejected," and various timeout closures. Delayed messages corresponding to the cleanup identifier are deleted from the delayed queue, and the index entry corresponding to the cleanup identifier is deleted from the due date index table. The cleanup task is triggered periodically according to a configurable timed expression. When an exception occurs during the cleanup of a single queue, only the error information of that queue is recorded, without interrupting the cleanup process of other queues.
[0061] In this embodiment of the invention, the scheduled cleanup task triggers the final state reverse cleanup machine according to a configurable scheduled expression (default 3 AM daily): It reads all composite identifiers from the due date index table queue by queue (constant-level reading, without touching the internal structure of the queue), and parses out the order number set; it then performs batch reverse lookups of the order database according to queue type—the prescription queue looks up the prescription order table (pending receipt, cancelled are final states), the outbound queue looks up the prescription order table (completed are final states), the procurement and dressing queue looks up the procurement order table (completed, cancelled are final states), and the consultation queue looks up the consultation order table (completed, rejected, and various timeout closures are final states); for orders that hit the final state, all status delay messages (the same order may have multiple target status messages) in that queue are synchronously deleted from the queue and index. If a single queue cleanup fails, only the error in that queue is recorded, without affecting other queues. Finally, a statistical report of the number of cleanup entries and total time consumed for each queue is output.
[0062] The correspondence between the six delayed queues and the business order table, the fields involved in the judgment, and their status enumeration values in this embodiment are described in the following table: Queue (Business Meaning) Reverse order lookup table Order number corresponding field Status determination field The state value determined to be the final state Square root order queue Prescription order table tb_order_prescribe_info id (primary key) order_status (order status) 2 = Pending receipt, -1 = Cancelled Cubed order outbound queue Prescription order table tb_order_prescribe_info id (primary key) order_status (order status) 3 = Completed Purchase order queue Purchase order table tb_order_purchase_info order_id (order ID) order_status (order status) 2 = Completed, -1 = Cancelled Application order queue Purchase order table tb_order_purchase_info order_id (order ID) order_status (order status) 2 = Completed, -1 = Cancelled Online consultation order cancellation queue The medical consultation order table is tb_inquiry_order. id (primary key) inquiry_status (consultation status) 3 = Completed, 4 = Rejected, 5 = Closed due to timeout, 6 = Payment timeout cancelled, 7 = Cancelled due to doctor's failure to respond. Paid medical consultation order queue The medical consultation order table is tb_inquiry_order. id (primary key) inquiry_status (consultation status) 3 = Completed, 4 = Rejected, 5 = Closed due to timeout, 6 = Payment timeout cancelled, 7 = Cancelled due to doctor's failure to respond. Note: The composite identifier for delayed messages is in the form of "order number#target status", where the order number is the value of the order number field listed in the table above. During cleanup, all composite identifiers are first retrieved in batches from the index hash table, and the set of order numbers is parsed out. Then, a batch query statement of "field IN (set of order numbers)" is used to look up the corresponding order table, retrieving only the order number and status columns to avoid database pressure caused by querying each order individually. For orders whose status matches the final status value in the table above, all delayed status messages (messages with multiple target statuses for the same order) in that queue are simultaneously deleted from the delayed queue and the index hash table.
[0063] The "Various Timeout Closures" in the consultation order table correspond to three specific values in the status field: 5 = Timeout Closure (the consultation session is closed due to lack of effective interaction within the specified time), 6 = Payment Timeout Cancellation (the consultation order is cancelled due to failure to complete payment within the specified time after creation), and 7 = Doctor's Lack of Response Cancellation (the system automatically closes the order and triggers a refund if the doctor does not proactively respond to the patient within the specified time). These three values, along with 3 = Ended and 4 = Rejected, constitute the final state set of a consultation order. In practice, a unified criterion is "status value greater than or equal to 3," meaning that a consultation order with a status field value of 3 or higher is considered to be in the final state.
[0064] In this embodiment, the final state determination logic is centralized within a single component called the final state reverse cleaner, and the branches are routed to their respective final state determination methods according to the queue type. Therefore, changes to the final state definition have a clear and unique maintenance entry point.
[0065] This invention provides an order status timeout driven system based on a delayed queue, such as... Figure 2 As shown, it is deployed on the cloud pharmacy server and consists of the following modules: The queue registry statically registers all delayed queues using an enumeration method. Each entry contains a triple <queue key, business description, and timeout business event type>. This embodiment registers six types of queues: prescription order queue, purchase order queue, dressing order queue, consultation order cancellation queue, prescription order outbound queue, and paid consultation order queue, each bound to its respective timeout business event type. The delayed event scheduling center provides entry points for delayed event delivery, remaining time query, and delayed event removal, and connects to the delayed queue group and expiration time index table in the in-memory database. A combined structure of delayed queues and blocking queues is built based on the distributed collaborative components of the in-memory database, providing three unified entry points for delayed event delivery, remaining time query, and delayed event removal. This embodiment uses the open-source in-memory key-value database Redis as the storage medium for the delayed queues. The production environment uses Redis 5.0 or later (supporting ZSET sorted sets, HASH hash tables, and Lua script EVAL capabilities), deployed in sentinel / cluster mode. Clients are isolated from other cached data through an independent database logical library (database 1 in this embodiment). It should be noted that this solution does not limit the in-memory database product itself; any in-memory database with the three basic capabilities of "sorted sets + hash tables + server-side atomic scripts" (such as KeyDB, Tair, and other compatible implementations) can be equivalently replaced without affecting the implementation of this solution. The expiration time index table maintains an independent hash mapping table for each delayed queue in the in-memory database. It stores the mapping relationship between the composite delayed message identifier and the corresponding expiration timestamp. The key is the delayed message identifier, and the value is the millisecond timestamp of the expiration time. It serves as the main index for constant-level queries. The event consumer dispatcher is used to traverse all entries in the queue registry when the application is ready to start and pre-create queue objects and consumption threads for each queue. It also retrieves the composite delayed message identifier, constructs a business event object, and publishes it to the application's in-app event bus after a delayed message expires. It blocks and waits for expired messages and transforms them into business events to publish to the application's in-app event bus. The final state reverse cleaner performs a daily reverse lookup of the business order database. It periodically reads all composite delayed message identifiers from the due date index table, performs a batch reverse lookup of the business order database by queue type, and synchronously deletes any residual delayed messages that have entered the final state of the order from the delayed queue and the due date index table.
[0066] In this embodiment of the invention, when the application is ready to start (listening for the application ready event), all entries in the queue registry are traversed. A delayed queue object is first created for each queue and placed in the global queue cache. Then, an independent asynchronous thread is started to listen to the corresponding blocked queue in a blocking mode. Because the queue object has already been created and registered with message handling logic before any business delivery occurs, the lost window of "messages expiring and not being handled" in the early stages of application restart is eliminated.
[0067] Specifically, when the application is ready to start, the event consumer dispatcher iterates through all entries in the queue registry, pre-creates a queue object for each corresponding delayed queue, and starts an independent asynchronous consumption thread. This ensures that the queue object and consumption thread are registered before any business delivery occurs. This pre-registration mechanism guarantees that even if a delayed message expires during application restart, it can still be processed and consumed normally because the consumer and queue object are already ready. This prevents issues such as orders being permanently stuck in an intermediate state or locked inventory from being released.
[0068] In this embodiment of the invention, the delayed queue carrier can be replaced by a dead-letter queue of a message middleware, a time wheel timer, or a database polling scan; as long as the combination of "composite delayed message identifier + independent expiration time index + final state reverse cleanup" is retained, it falls within the protection concept of this embodiment. The delayed message identifier "order number#target status" can be expanded to "order number#target status#tenant identifier" or "order number#target status#retry count" to support multi-tenant isolation and timeout retry counting. The expiration time index structure can be replaced by an ordered set sorted by expiration timestamp, which, in addition to retaining constant-level single-key query capabilities, can also support range scanning for "querying orders that will expire within a future time window".
[0069] Furthermore, the event construction method can be to construct business event objects using registry reflection, or it can be replaced by factory registration or policy mapping. The application-wide event bus can be replaced by message middleware topics to achieve cross-service timeout event distribution. The cleanup timing can be to use daily scheduled reverse cleanup, or it can be replaced by lazy verification during consumption (when a message expires and is dequeued, first check whether the order has reached its final state; if so, discard it directly), or both can be used together.
[0070] Furthermore, embodiments of the present invention also provide a computer-readable storage medium having a computer program stored thereon, which, when executed by a processor, implements the method described in the present invention.
[0071] The optional embodiments of the present invention have been described in detail above with reference to the accompanying drawings. However, the embodiments of the present invention are not limited to the specific details in the above embodiments. Within the scope of the technical concept of the embodiments of the present invention, various simple modifications can be made to the technical solutions of the embodiments of the present invention, and these simple modifications all fall within the protection scope of the embodiments of the present invention.
[0072] It should also be noted that the various specific technical features described in the above embodiments can be combined in any suitable manner without contradiction. To avoid unnecessary repetition, the embodiments of the present invention will not describe the various possible combinations separately.
[0073] Those skilled in the art will understand that all or part of the steps in the methods of the above embodiments can be implemented by a program instructing related hardware. This program is stored in a storage medium and includes several instructions to cause a microcontroller, chip, or processor to execute all or part of the steps of the methods described in the various embodiments of this application. The aforementioned storage medium includes various media capable of storing program code, such as a USB flash drive, a portable hard drive, a read-only memory (ROM), a random access memory (RAM), a magnetic disk, or an optical disk.
[0074] Furthermore, various different implementations of the present invention can be combined arbitrarily, as long as they do not violate the spirit of the present invention, they should also be regarded as the content disclosed in the present invention.
Claims
1. A timeout-driven method for order status based on a delayed queue, characterized in that, include: The server maintains a queue registry, which statically registers multiple delayed queue entries in an enumeration manner. Each entry contains a mapping relationship between a queue key, a business description, and a timeout business event type. The multiple event classes corresponding to the timeout business event type all contain an order number attribute and a target status attribute and share the same construction signature. When a business node needs to set a timeout constraint for an order, it calls the unified delivery entry point and passes in the order number, target status, delay duration, and queue identifier. The combination of the order number and the target status is used as the composite delayed message identifier. The format of the composite delayed message identifier is "order number#target status". The delayed message carrying the composite delayed message identifier is delivered to the delayed queue corresponding to the queue identifier. After the delayed message expires, the composite delayed message identifier is retrieved from the delayed queue, and the order number and the target status are restored by splitting it according to the delimiter; According to the queue identifier, the corresponding timeout business event type is searched in the queue registry. The constructor method corresponding to the timeout business event type is called by reflection, and the order number and the target status are passed as actual parameters. A business event object carrying the order number and the target status is constructed and published to the application event bus. Each service listener executes the corresponding timeout handling logic according to the target state branch.
2. The method according to claim 1, characterized in that, The multiple delay queues include the following six types of queues: prescription order delay queue, purchase order delay queue, dressing order delay queue, consultation order cancellation delay queue, prescription order outbound delay queue, and paid consultation order delay queue.
3. The method according to claim 1, characterized in that, Before delivery, a deduplication check is performed: using the composite delayed message identifier as a field, an atomic operation in the memory database is used to determine whether the composite delayed message identifier already exists in the expiration time index table. If it already exists, the delivery is abandoned. If it does not exist, a delayed message is simultaneously delivered to the delayed queue and the corresponding mapping relationship is written to the expiration time index table. The atomic operations include at least one of the following methods: distributed locks based on in-memory databases, HSETNX atomic commands in in-memory databases, and Lua atomic scripts executed by the in-memory database server.
4. A method for querying the remaining waiting time of delayed messages in a delayed queue, characterized in that, include: When delivering a delayed message, the delayed message carrying the composite delayed message identifier is put into the delayed queue, and the composite delayed message identifier and the corresponding expiration timestamp are simultaneously written into an independent expiration time index table. The composite delayed message identifier is composed of the order number and the target status. Upon receiving a query request for the remaining waiting time of a target order, a target composite delay message identifier is constructed based on the order number and target status of the target order; Using the target composite delayed message identifier as the key, query whether there is a corresponding expiration timestamp in the expiration time index table; If the hit is successful and the current time has not exceeded the expiration timestamp, calculate the remaining waiting time based on the expiration timestamp and return. If a match is found and the current time has exceeded the expiration timestamp, then delete the corresponding index entry in the expiration time index table and return zero; If no match is found, an atomic script executed on the in-memory database server iterates through all elements of the delay queue at once. The script takes the target composite delay message identifier as input parameter, returns the score of the matching element as the expiration timestamp after the traversal is completed, fills the expiration timestamp back into the expiration time index table, and calculates the remaining waiting time based on the expiration timestamp and returns it.
5. The method according to claim 4, characterized in that, The delayed queue is constructed based on the following data structures of the in-memory database: an ordered set sorted by expiration time, a list storing unexpired messages in delivery order, and a blocking queue for blocking retrieval by the consumer; the expiration time index table is a hash table independent of the above three data structures, the field of the hash table is the composite delayed message identifier, and the value is the corresponding expiration timestamp, and the complexity of a single query of the hash table is constant.
6. A method for cleaning up residual messages in a delayed queue, characterized in that, include: Maintain a delayed queue and a corresponding expiration time index table. The expiration time index table stores the mapping relationship between the composite delayed message identifier of the delivered delayed message and the corresponding expiration timestamp. The composite delayed message identifier is composed of the order number and the target status. A cleanup task is triggered periodically to read all composite delay message identifiers from the due date index table and parse out the order number corresponding to each composite delay message identifier. Based on the queue type of the delayed queue, determine the corresponding business order table, and use a batch query statement with a single "field IN (order number set)" to retrieve the order status corresponding to the order number in the business order table; The composite delayed message identifier corresponding to the order whose status has entered the final state is used as the cleanup identifier. The final state is defined according to the queue type: the final state of the prescription order queue includes pending receipt and cancelled; the final state of the prescription order outbound queue includes completed; the final state of the purchase order queue and the dressing order queue includes completed and cancelled; and the final state of the consultation order queue includes ended, rejected, and various timeout closures. Delete the delayed message corresponding to the pending cleanup identifier from the delay queue, and delete the index entry corresponding to the pending cleanup identifier from the expiration time index table.
7. The method according to claim 6, characterized in that, The timed cleanup task is triggered by a configurable timed expression. When an exception occurs during the cleanup of a single queue, only the error information of that queue is recorded, without interrupting the cleanup process of the remaining queues. The reading of all composite delayed messages from the expiration time index table is performed at a constant level, without touching the internal structure of the delayed queue.
8. An order status timeout driven system based on a delayed queue, characterized in that, include: The queue registry is used to statically register entries for multiple delayed queues in an enumerated manner. Each entry contains a mapping relationship between a queue key, a business description, and a timeout business event type. The multiple event classes corresponding to the timeout business event type all contain an order number attribute and a target status attribute and share the same construction signature. The delayed event scheduling center provides entry points for delayed event delivery, remaining time query, and delayed event removal. This center is connected to a delayed event queue group and an expiration time index table in the in-memory database. The delayed event delivery entry uses a combination of order number and target status as a composite delayed message identifier for delivery. Before delivery, a deduplication check is performed: using the composite delayed message identifier as a field, an atomic operation in the in-memory database determines whether the identifier already exists in the expiration time index table. If it exists, the delivery is abandoned; otherwise, a delayed message is simultaneously delivered to the delayed queue and the corresponding mapping relationship is written to the expiration time index table. The atomic deduplication operation includes at least one of the following methods: a distributed lock based on the in-memory database, an HSETNX atomic command in the in-memory database, or a Lua atomic script executed by the in-memory database server. The expiration time index table maintains an independent hash mapping table for each delayed queue in the memory database, storing the mapping relationship between the composite delayed message identifier and the corresponding expiration timestamp. The composite delayed message identifier is composed of the order number and the target status. The event consumer dispatcher is used to traverse all entries in the queue registry when the application is ready to start. It pre-creates a queue object for each delayed queue corresponding to the entry and starts an independent asynchronous consumption thread, so that the queue object and the consumption thread are registered before any business delivery occurs. After the delayed message expires, it retrieves the composite delayed message identifier from the delayed queue, splits it according to the delimiter to restore the order number and target status, looks up the corresponding timeout business event type according to the queue registry, constructs the business event object by calling the corresponding constructor through reflection, and publishes it to the application's in-process event bus. The final state reverse cleaner is used to periodically read all composite delayed message identifiers from the due date index table, perform batch reverse lookups of the business order database by queue type, and synchronously delete the delayed messages corresponding to orders whose order status has entered the final state from the delayed queue and the due date index table.
9. The system according to claim 8, characterized in that, The delayed event removal entry provided by the delayed event scheduling center is used by the business party to call the removal entry when an order is paid, canceled, or manually processed before the delayed message expires. At the same time, the delayed event scheduling center deletes the corresponding delayed message from the delayed queue and deletes the corresponding index entry from the expiration time index table.
10. The system according to claim 8, characterized in that, The event consumer dispatcher performs classified exception capture and isolation processing on the reflection construction process: it captures five types of exceptions: instantiation exception, illegal access exception, constructor method non-existent exception, exception thrown inside the constructor method, and thread interruption exception; when any exception occurs, the context is recorded, including the queue key and the original message content that caused the failure; reflection failure only affects the current message, does not affect the retrieval and consumption of subsequent messages in the same queue, and does not affect the consumption threads of other queues.