Dubbo分布式日志追踪,多线程不能获取窜ID和IP问题

接着上一篇日志,当用MDC或者ThreadContext来put或者get数据的时候,不同线程是获取不到的,他们都是ThreadLocal维护,所以线程独立。

如果需要子线程获取则将参数传入,在Thread的run方法执行的时候将传入的ID和IP都put到MDC或者ThreadContext中。

  • 这里使用ThreadContext:
<context:component-scan base-package="spring04"/>

    <bean id="threadPool"
          class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 核心线程数 -->
        <property name="corePoolSize" value="3"/>
        <!-- 最大线程数 -->
        <property name="maxPoolSize" value="10"/>
        <!-- 队列最大长度 >=mainExecutor.maxSize -->
        <property name="queueCapacity" value="25"/>
        <!-- 线程池维护线程所允许的空闲时间 -->
        <property name="keepAliveSeconds" value="300"/>
        <!-- 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.  -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
        </property>
    </bean>
  • 创建一个AbstractRunnable实现Runnable,以后创建线程都用AbstractRunnable创建
package spring04;

import org.slf4j.MDC;

public abstract class AbstractRunnable implements Runnable {
    private String traceid;
    private String ip;

    public AbstractRunnable(String traceid, String ip) {
        this.traceid = traceid;
        this.ip = ip;
    }

    private void log() {
        MDC.put(Constant.TRANC_ID, traceid);
        MDC.put(Constant.LOCAL_IP, ip);
    }

    protected abstract void thread();

    public void run() {
        log();
        thread();
    }

    public String getTraceid() {
        return traceid;
    }

    public void setTraceid(String traceid) {
        this.traceid = traceid;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }
}
  • 个线程池context
package spring04;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Component
public class TreadContext {

    @Autowired
    private ThreadPoolTaskExecutor executor;

    private static TreadContext context;

    private List<AbstractRunnable> threads = new ArrayList<AbstractRunnable>();

    @PostConstruct
    private void init() {
        context = this;
    }

    /**
     * 关闭线程池
     */
    public void close() {
        executor.shutdown();
    }

    /**
     * 执行所有线程池
     */
    public void open() {
        for (Runnable thread : this.threads) {
            executor.execute(thread);
        }
    }

    /**
     * 添加多个线程任务
     *
     * @param threads
     * @return
     */
    public TreadContext source(List<AbstractRunnable> threads) {
        this.threads.addAll(threads);
        return context;
    }

    /**
     * 添加单个线程任务
     *
     * @param thread
     */
    public void source(AbstractRunnable thread) {
        this.threads.add(thread);
    }

    /**
     * 获取线程池管理对象
     *
     * @return
     */
    public static TreadContext getContext() {
        return context;
    }
}
  • 常量
package spring04;

public class Constant {
    public static final String TRANC_ID = "TRANC_ID";
    public static final String LOCAL_IP = "LOCAL_IP";
}
  • 线程类
package spring04;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class MyThread extends AbstractRunnable {

    private static Logger logger = LoggerFactory.getLogger(MyThread.class);

    public MyThread(String traceid, String ip) {
        super(traceid, ip);
    }

    /**
     * 用来替代run方法
     */
    protected void thread() {
        logger.info("thread name:{}  ,trace_id:{}  ,local_ip:{}", Thread.currentThread().getName(), MDC.get(Constant.TRANC_ID), MDC.get(Constant.TRANC_ID));
    }

}
  • 执行的main方法
package spring04;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.ArrayList;
import java.util.List;

public class Main {

    private static Logger logger = LoggerFactory.getLogger(Main.class);

    private static String ID = "10000000000001";
    private static String IP = "192.168.80.123";

    public static void main(String[] args) {
        AbstractApplicationContext appContext = new ClassPathXmlApplicationContext("application04.xml");
        TreadContext context = appContext.getBean(TreadContext.class);
        MDC.put(Constant.TRANC_ID, ID);
        MDC.put(Constant.LOCAL_IP, "192.168.80.123");
        AbstractRunnable thread1 = new MyThread(ID, IP);
        AbstractRunnable thread2 = new MyThread(ID, IP);
        List<AbstractRunnable> threads = new ArrayList<AbstractRunnable>();
        threads.add(thread1);
        threads.add(thread2);
        context.source(threads).open();
        logger.info("thread name:{}  ,trace_id:{}  ,local_ip:{}", Thread.currentThread().getName(), MDC.get(Constant.TRANC_ID), MDC.get(Constant.LOCAL_IP));
        appContext.registerShutdownHook();
    }
}
  • 执行结果:

这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_20641565/article/details/78628115

https://blog.csdn.net/qq_20641565/article/details/78628115

猜你喜欢

转载自blog.csdn.net/varyall/article/details/81534142