简述:
继之前我在《mdc 实现日志链路追踪 方便迅速排查问题》一文中抛出的问题,MDC无法很好地实现多线程之间的值传递问题,我自己私下也是抽空去找了,目前找到一个初次尝试,效果还不错的方案,下面给大家介绍一下吧。
1、新建一个简单的spring boot 项目
目录
2、引入依赖
<!--web项目所需-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 本次核心依赖 -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>tlog-all-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
3、编写logback.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="APP_NAME" value="logtest"/>
<property name="LOG_HOME" value="./logs" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--这里替换成AspectLogbackEncoder-->
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
4、新建一个service类 TestService
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class TestService {
public void test(int n) {
log.info("service输出内容:{}", n);
}
}
5、新建一个测试接口类 TestThread,并注入service
import com.example.spring_hibernate.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@RestController
@Slf4j
public class TestThread {
@Autowired
private TestService testService;
@GetMapping(value = "/hello")
public void get() {
//构建两个线程池
ExecutorService executorService = new ScheduledThreadPoolExecutor(4);
ExecutorService executorService2 = new ScheduledThreadPoolExecutor(2);
for (int i = 0; i < 10; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info(Thread.currentThread().getName() + ">>线程名>>" + System.currentTimeMillis());
//启动线程池2
executorService2.submit(new Runnable() {
@Override
public void run() {
log.info("线程池2》》" + Thread.currentThread().getName());
//调用service方法
testService.test(4);
}
});
}
});
}
}
}
6、OK,启动项目,测试接口,注意查看日志输出。
启动成功
日志输出
两次对比
OK,是不是很nice,感兴趣的道友,可以去看看它的底层源码哦。
好了,若觉得此文章还不错,记得点赞评论转发哦!!!