Dubbo分散式日誌追蹤,多執行緒不能獲取竄ID和IP問題
阿新 • • 發佈:2019-02-13
接著上一篇日誌,當用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();
}
}
- 執行結果: