使用requestId在分布式系統(tǒng)追蹤請求

背景

現(xiàn)在大多數(shù)企業(yè)開發(fā)的系統(tǒng)都是分布式系統(tǒng)了辜窑,隨著系統(tǒng)的復(fù)雜如何有效地追蹤定位線上問題也變得更加困難讹剔。我們可以使用requestId(traceId)來解決這一問題头岔。

實現(xiàn)思路

  1. 使用過濾器或切面在每個HTTP請求進到Controller前生成一個唯一標識請求的requestId古戴,可以使用UUID,放在ThreadLocal里摄悯,方便上下文調(diào)用赞季。
    public static final String REQUEST_ID_KEY = "requestId";
    public static ThreadLocal<String> requestIdThreadLocal = new ThreadLocal<String>();
 
    private static final Logger logger = LoggerFactory.getLogger(RequestIdUtil.class);
 
    public static String getRequestId(HttpServletRequest request) {
        String requestId = null;
        String parameterRequestId = request.getParameter(REQUEST_ID_KEY);
        String headerRequestId = request.getHeader(REQUEST_ID_KEY);
 
        if (parameterRequestId == null &amp;&amp; headerRequestId == null) {
            logger.info("request parameter 和header 都沒有requestId入?yún)?);
            requestId = UUID.randomUUID().toString();
        } else {
            requestId = parameterRequestId != null ? parameterRequestId : headerRequestId;
        }
 
        requestIdThreadLocal.set(requestId);
 
        return requestId;
    }
  1. requestId結(jié)合日志打印,這里使用slf4j標準里的MDC實現(xiàn)奢驯,例子使用logback打印日志申钩。
    代碼使用:
        MDC.put("requestId", requestId);

logback配置示例:

<configuration> 
     <appender name="logfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <Encoding>UTF-8</Encoding>
         <File>${log_base}/java-base-web.log</File>
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <FileNamePattern>${log_base}/java-base-web-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
             <MaxHistory>10</MaxHistory>
             <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>200MB</MaxFileSize>
             </TimeBasedFileNamingAndTriggeringPolicy> 
         </rollingPolicy>
         <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d^|^%X{requestId}^|^%-5level^|^%logger{36}%M^|^%msg%n</pattern>
         </layout>
     </appender>
     <root level="info"> 
        <appender-ref ref="logfile" /> 
     </root> 
</configuration>

主要是在pattern那里指定,使用MDC里面的變量用的是%X{requestId}瘪阁,requestId為放進MDC里面的key撒遣,

達到的效果就是打印出來的日志自動帶上了requestId。效果如下:

[a0b3589f-fe87-4d3a-9151-8925afd0a6c6]  at com.test.demo.TestMain2.test2(TestMain2.java:26)  

相當(dāng)于切日志管跺,這樣我們線上就可以使用requestId在ELK上搜索屬于這個請求的日志了义黎。

  1. 使用HTTP Client或者OKHTTP等在后臺請求其他系統(tǒng)的服務(wù)的時候把放在上下文的requestId放在請求參數(shù)或者頭里,推薦放在header豁跑,上面的切面一開始會判斷requestId是否在請求里面廉涕,有的話就繼續(xù)沿用調(diào)用方的requestId,這樣子在被調(diào)用的系統(tǒng)也能追蹤到屬于同一個調(diào)用鏈的日志了艇拍。
    String requestId = RequestIdUtil.requestIdThreadLocal.get();
    headerMap.put(RequestIdUtil.REQUEST_ID_KEY, requestId);
    Map<String, String> paramMap = new HashMap<String, String>();
    String resultString = JsonHttpClientUtil.post(testHttpClientUrl, headerMap, paramMap, "UTF-8");
    logger.info(resultString);
  1. requestId可以放到一個封裝響應(yīng)類里面狐蜕,這樣子我們就可以在控制臺里面看到響應(yīng)參數(shù)里面的requestId,方便在ELK里面查找日志了卸夕。也可以結(jié)合異常體系使用层释,拋的異常打印的日志自然也帶上了requestId,同時可以使用釘釘機器人來通知開發(fā)區(qū)定位問題快集,同時帶上requestId和異常堆棧信息就行了湃累。這樣就能方便的知道異常發(fā)生的上下文日志了。

總結(jié)

上面總結(jié)了一些工作中使用起來比較便利的定位問題的方法體系碍讨。希望可以給讀者帶來一些啟示治力。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市勃黍,隨后出現(xiàn)的幾起案子宵统,更是在濱河造成了極大的恐慌,老刑警劉巖覆获,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件马澈,死亡現(xiàn)場離奇詭異,居然都是意外死亡弄息,警方通過查閱死者的電腦和手機痊班,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摹量,“玉大人涤伐,你說我怎么就攤上這事馒胆。” “怎么了凝果?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵祝迂,是天一觀的道長。 經(jīng)常有香客問我器净,道長型雳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任山害,我火速辦了婚禮纠俭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浪慌。我一直安慰自己冤荆,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布眷射。 她就那樣靜靜地躺著匙赞,像睡著了一般佛掖。 火紅的嫁衣襯著肌膚如雪妖碉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天芥被,我揣著相機與錄音欧宜,去河邊找鬼。 笑死拴魄,一個胖子當(dāng)著我的面吹牛冗茸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匹中,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼夏漱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了顶捷?” 一聲冷哼從身側(cè)響起挂绰,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎服赎,沒想到半個月后葵蒂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡重虑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年践付,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缺厉。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡永高,死狀恐怖隧土,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乏梁,我是刑警寧澤次洼,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站遇骑,受9級特大地震影響卖毁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜落萎,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一亥啦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧练链,春花似錦翔脱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绿鸣,卻和暖如春疚沐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潮模。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工亮蛔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人擎厢。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓究流,卻偏偏與公主長得像,于是被迫代替她去往敵國和親动遭。 傳聞我的和親對象是個殘疾皇子芬探,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)厘惦,斷路器偷仿,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • 一:根節(jié)點包含的屬性: scan: 當(dāng)此屬性設(shè)置為true時,配置文件如果發(fā)生改變绵估,將會被重新加載炎疆,默認值為tru...
    把愛放下會走更遠閱讀 630評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,838評論 25 707
  • 最近有員工辭職了缝左。 職員a是我比較賞識一個技術(shù)人員亿遂,來公司不到三年浓若,從一個大學(xué)本科畢業(yè)生逐步成長為較為合格的技術(shù)人...
    劉言剛_北京閱讀 324評論 0 1
  • 在這個四月的傍晚,六至七點間浦徊,村里的家家戶戶都起了炊煙馏予,鼻息里都是濃郁的菜香味,一聞便知盔性,誰家做了什么菜霞丧!甚至連佐...
    好一只懶貓兒閱讀 332評論 7 5