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

来源:互联网 发布:java数据字典怎么写 编辑:程序博客网 时间:2024/06/05 18:32

接着上一篇日志,当用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;@Componentpublic 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();    }}
  • 执行结果:

这里写图片描述

原创粉丝点击