Message service imitating Taobao open platform -- server message log processing

Posted by Alk3m1st on Wed, 12 Jan 2022 00:49:08 +0100

overall design

The message log is an important basis for the normal operation and abnormal troubleshooting of the monitoring system. The log is divided into two parts. One part is the disk log, which records the specific contents of all messages received and sent. This part of the log is stored on the disk file in the form of text, which is mainly used for exception troubleshooting, but it is not convenient to view. In order to achieve the purpose of system monitoring, the database table of message log is established, which is updated to the database table record when sending and receiving messages. At the same time, auxiliary information such as message status and sending times are saved, and the message retransmission function is realized according to the database table and auxiliary information.

Our messages are asynchronous. Request messages and response messages appear in pairs. In order to facilitate viewing and monitoring, the log record does not save the original log record, but is adjusted from the design level. The same log record is used to record request messages and corresponding response messages.

Log class

/**
 * Message log
 * @author wqliu
 * @date 2021-08-21
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("ip_api_message_log")
public class ApiMessageLog extends BaseEntity {

    private static final long serialVersionUID = 1L;

    /**
     * Request message ID
     */
    @TableField("request_id")
    private String requestId;

    /**
     * Request application code
     */
    @TableField("request_app_code")
    private String requestAppCode;

    /**
     * Request message subject code
     */
    @TableField("request_topic_code")
    private String requestTopicCode;

    /**
     * Request time
     */
    @TableField("request_time")
    private LocalDateTime requestTime;

    /**
     * Request content
     */
    @TableField("request_data")
    private String requestData;

    /**
     * Response message ID
     */
    @TableField("response_id")
    private String responseId;

    /**
     * Response application code
     */
    @TableField("response_app_code")
    private String responseAppCode;

    /**
     * Response message subject code
     */
    @TableField("response_topic_code")
    private String responseTopicCode;

    /**
     * response time
     */
    @TableField("response_time")
    private LocalDateTime responseTime;

    /**
     * Response content
     */
    @TableField("response_data")
    private String responseData;

    /**
     * Response results
     */
    @TableField("response_result")
    private String responseResult;



    /**
     * error message
     */
    @TableField("error_message")
    private String errorMessage;

    /**
     * current state
     */
    @TableField("status")
    private String status;

    /**
     * Sending times
     */
    @TableField("send_count")
    private Integer sendCount;

}

Log objects are mainly divided into three parts:
Request message part: message ID, application code, message subject code, request time and request content
Response message part: message identification, application code, message subject code, response time, response content, response result and error information
Auxiliary information: current status and sending times
lower

Message status

Firstly, there are two modes of interfacing with our interface platform, one is based on websocket, and the other is based on api service polling. Therefore, there are actually two sets of message states.

/**
 * Message status
 * @author  wqliu
 * @date  2021-10-5 10:07
*/
public enum MessageStatus
{

	/**
	 * Pending request
	 */
	WAIT_REQUEST,

	/**
	 * Requested
	 */
	REQUESTED,

	/**
	 * Responded
	 */
	RESPONSED,

	/**
	 * No request required (message type is response message or client does not subscribe to message)
	 */
	NOT_TO_REQUEST,

	/**
	 * Pending (message interface only)
	 */
	WAIT_HANDLE
	

}

There are more states based on websocket. First, when the message is created, the state is set to wait to be REQUESTED_ Request, and then further judge that if the message type is a response message or the client does not subscribe to a message, it is set to no need to request NOT_TO_REQUEST, otherwise, the client querying the subscription message will push the message, update the status to REQUESTED, and update the status to responded after receiving the client message confirmation request.

The api based service polling method is relatively simple. The above two states are required. After the message is generated, it is WAIT_HANDLE, that is, wait for the docking party to query and process. After receiving the interface call confirmed by the message, update the status to responded.

Create log

Create a log record. This action occurs when a request message is initiated. Fill in the request message part of the log object, and initialize the message status and sending times.

   /**
     * Save request message log
     * @param requestMessage
     */
    protected void saveLog(RequestMessage message) {
        ApiMessageLog log=new ApiMessageLog();
        log.setRequestId(message.getId());
        log.setRequestAppCode(message.getPublishAppCode());
        log.setRequestTopicCode(message.getTopic());
        log.setRequestTime(LocalDateTime.now());
        log.setRequestData(message.getContent());
        log.setResponseAppCode(message.getResponseAppCode());
        log.setStatus(message.getStatus());
        log.setSendCount(message.getSendCount());

        apiMessageLogService.add(log);

    }

Update log

Update the log record. This action occurs when the server sends a response message to the client or the server receives a response message from the client. Find the corresponding log record according to the request message ID and update the response message part.

    /**
     * Update message log
     * @param messageResponse Response message
     */
    protected void updateLog(ResponseMessage message) {

        ApiMessageLog log = apiMessageLogService.getByRequestMessageId(message.getRequestMessageId());
        //The publisher of the response message, corresponding to the response of the request message
        log.setResponseAppCode(message.getPublishAppCode());
        log.setResponseTopicCode(message.getTopic());
        log.setResponseTime(LocalDateTime.now());
        log.setResponseData(message.getContent());
        log.setResponseResult(message.getResult());
        log.setErrorMessage(message.getErrorMessage());
        log.setResponseId(message.getId());
        //Update message to responded
        log.setStatus(MessageStatus.RESPONSED.name());

        apiMessageLogService.modify(log);


    }

Topics: Java server http