Browse Source

feat:新增requestId标记接口和任务

wangzaijun 2 weeks ago
parent
commit
8feb90be85

+ 6 - 0
mo-daq/pom.xml

@@ -46,6 +46,12 @@
             <artifactId>spring-boot-starter-undertow</artifactId>
         </dependency>
 
+        <!-- AOP 支持 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+
 <!--        <dependency>-->
 <!--            <groupId>org.springframework.boot</groupId>-->
 <!--            <artifactId>spring-boot-starter-quartz</artifactId>-->

+ 5 - 0
mo-daq/src/main/java/com/smppw/modaq/application/api/ParseApi.java

@@ -21,6 +21,11 @@ public class ParseApi {
         this.service = service;
     }
 
+    @GetMapping("health")
+    public ResponseEntity<String> health() {
+        return ResponseEntity.ok("ok");
+    }
+
     @GetMapping("report")
     public ResponseEntity<String> report(String startDateTime) {
         Date now = new Date();

+ 2 - 2
mo-daq/src/main/java/com/smppw/modaq/application/task/ParseSchedulerTask.java

@@ -53,7 +53,7 @@ public class ParseSchedulerTask {
     /**
      * 定时任务每11分钟执行一次
      */
-    @Scheduled(cron = "0 */11 * * * ?")
+    @Scheduled(cron = "0 */1 * * * ?")
     public void letter() {
         String taskKey = "mo_email_parse_letter_task";
         TaskRecordDO task = this.taskRecordService.getTaskRecord(taskKey, 11 * 2 * 60);
@@ -85,7 +85,7 @@ public class ParseSchedulerTask {
     /**
      * 定时任务每小时的15分和45分执行一次
      */
-    @Scheduled(cron = "0 15,45 * * * ?")
+    @Scheduled(cron = "0 */1 * * * ?")
     public void report() {
         String taskKey = "mo_email_parser_report_task";
         TaskRecordDO task = this.taskRecordService.getTaskRecord(taskKey, 60 * 2 * 60);

+ 2 - 0
mo-daq/src/main/java/com/smppw/modaq/common/conts/Constants.java

@@ -1,6 +1,8 @@
 package com.smppw.modaq.common.conts;
 
 public class Constants {
+    public static final String MDC_REQUEST_ID_KEY = "requestId";
+
     public static final long DEFAULT_SERIAL_ID = 999L;
 
     public static final String WATERMARK_REPLACE = "+_+" + System.lineSeparator();

+ 40 - 0
mo-daq/src/main/java/com/smppw/modaq/infrastructure/components/RequestIdFilter.java

@@ -0,0 +1,40 @@
+package com.smppw.modaq.infrastructure.components;
+
+import cn.hutool.core.util.IdUtil;
+import com.smppw.modaq.common.conts.Constants;
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.MDC;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+
+@Component
+@Order(1)
+public class RequestIdFilter implements Filter {
+
+    private static final String REQUEST_ID_HEADER = "X-Request-ID";
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+
+        try {
+            // 尝试从Header获取RequestId,没有则生成
+            String requestId = httpRequest.getHeader(REQUEST_ID_HEADER);
+            if (!StringUtils.hasText(requestId)) {
+                requestId = "REQ-" + IdUtil.simpleUUID();
+            }
+
+            MDC.put(Constants.MDC_REQUEST_ID_KEY, requestId);
+            chain.doFilter(request, response);
+        } finally {
+            // 确保清除MDC
+            MDC.remove(Constants.MDC_REQUEST_ID_KEY);
+        }
+    }
+}

+ 26 - 0
mo-daq/src/main/java/com/smppw/modaq/infrastructure/components/ScheduledTaskAspect.java

@@ -0,0 +1,26 @@
+package com.smppw.modaq.infrastructure.components;
+
+import cn.hutool.core.util.IdUtil;
+import com.smppw.modaq.common.conts.Constants;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class ScheduledTaskAspect {
+
+    @Around("@annotation(org.springframework.scheduling.annotation.Scheduled)")
+    public Object wrapScheduledTask(ProceedingJoinPoint pjp) throws Throwable {
+        try {
+            // 生成任务唯一ID
+            String taskId = "TASK-" + IdUtil.nanoId();
+            MDC.put(Constants.MDC_REQUEST_ID_KEY, taskId);
+            return pjp.proceed();
+        } finally {
+            MDC.remove(Constants.MDC_REQUEST_ID_KEY);
+        }
+    }
+}

+ 20 - 0
mo-daq/src/main/java/com/smppw/modaq/infrastructure/config/ThreadPoolConfig.java

@@ -2,12 +2,15 @@ package com.smppw.modaq.infrastructure.config;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.TaskDecorator;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 
+import java.util.Map;
 import java.util.concurrent.ThreadPoolExecutor;
 
 @Configuration
@@ -25,6 +28,7 @@ public class ThreadPoolConfig {
         taskExecutor.setThreadNamePrefix("asyncExecutor--");
         taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
         taskExecutor.setAwaitTerminationSeconds(60);
+        taskExecutor.setTaskDecorator(new MdcTaskDecorator());
 
         // 修改拒绝策略为使用当前线程执行
         taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
@@ -43,6 +47,7 @@ public class ThreadPoolConfig {
         scheduler.setAwaitTerminationSeconds(60); // 关闭时等待任务完成的时间
         scheduler.setWaitForTasksToCompleteOnShutdown(true); // 关闭时等待任务完成
         scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
+        scheduler.setTaskDecorator(new MdcTaskDecorator());
 
         // 可选配置
         scheduler.setErrorHandler(t -> {
@@ -55,4 +60,19 @@ public class ThreadPoolConfig {
 
         return scheduler;
     }
+
+    static class MdcTaskDecorator implements TaskDecorator {
+        @Override
+        public Runnable decorate(Runnable runnable) {
+            Map<String, String> contextMap = MDC.getCopyOfContextMap();
+            return () -> {
+                try {
+                    MDC.setContextMap(contextMap);
+                    runnable.run();
+                } finally {
+                    MDC.clear();
+                }
+            };
+        }
+    }
 }

+ 2 - 2
mo-daq/src/main/resources/logback.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration debug="true">
     <!-- 日志格式:年-月-日 时:分:秒 [线程] 日志级别 所在类:行号 - 具体信息 换行 -->
-    <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] - [%X{x-api-requestid}] %-5level %logger{50}:%-4L - %msg%n"/>
-    <property name="LOG_HOME" value="/home/wwwroot/modaq/logs"/>
+    <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] - [%X{requestId}] %-5level %logger{50}:%-4L - %msg%n"/>
+    <property name="LOG_HOME" value="./logs"/>
 
     <!--输出到控制台-->
     <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">