亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java 實(shí)現(xiàn)分布式服務(wù)的調(diào)用鏈跟蹤

 更新時(shí)間:2021年06月07日 08:50:33   作者:果果果果果  
分布式服務(wù)中完成某一個(gè)業(yè)務(wù)動(dòng)作,需要服務(wù)之間的相互協(xié)作才能完成,在這一次動(dòng)作引起的多服務(wù)的聯(lián)動(dòng)我們需要用1個(gè)唯一標(biāo)識(shí)關(guān)聯(lián)起來(lái),關(guān)聯(lián)起來(lái)就是調(diào)用鏈的跟蹤。本文介紹了Java 實(shí)現(xiàn)分布式服務(wù)的調(diào)用鏈跟蹤的步驟

為什么要實(shí)現(xiàn)調(diào)用鏈跟蹤?

隨著業(yè)務(wù)的發(fā)展,所有的系統(tǒng)最終都會(huì)走向服務(wù)化體系,微服務(wù)的目的一是提高系統(tǒng)的穩(wěn)定性,二是提高持續(xù)交付的效率,為什么能提高這兩項(xiàng)不是今天討論的內(nèi)容。

當(dāng)然這也不是絕對(duì)的,如果業(yè)務(wù)還在MVP驗(yàn)證,團(tuán)隊(duì)規(guī)模小個(gè)人覺(jué)得完全沒(méi)必要微服務(wù)化、單體應(yīng)用是比較好的選擇。作者是有經(jīng)歷過(guò)從單體應(yīng)用到1000+應(yīng)用的增長(zhǎng)經(jīng)歷,也是見(jiàn)證了公司從初創(chuàng)到上市的過(guò)程,對(duì)于系統(tǒng)階段和業(yè)務(wù)階段的匹配還是有比較深的感受的。

服務(wù)拆分后帶來(lái)的問(wèn)題是什么呢?服務(wù)的依賴關(guān)系復(fù)雜后,對(duì)于問(wèn)題的排查也增加了復(fù)雜度,當(dāng)然站在更高的角度來(lái)看拆分帶來(lái)的不只是排錯(cuò)復(fù)雜性的提升,工程效率、組織協(xié)作也都會(huì)帶來(lái)新的挑戰(zhàn)。

回到主題,如何快速查詢整個(gè)請(qǐng)求鏈路上的日志并呈現(xiàn)出來(lái)是解決排查問(wèn)題復(fù)雜度的根本方法,這就是今天我們要講的內(nèi)容,如何自己來(lái)實(shí)現(xiàn)一個(gè)全鏈路跟蹤。

如何實(shí)現(xiàn)?

第一步,看圖、看場(chǎng)景,用戶瀏覽器的一次請(qǐng)求行為所走的路徑是什么樣的

如上圖、省略了4層和7層的LB,請(qǐng)求直接到gateway->A->B 那如何把個(gè)request關(guān)聯(lián)起來(lái)呢?從時(shí)序上來(lái)看我們只要在gateway生成一個(gè)traceId然后層層透?jìng)?,那么每一次的request的我們就能通過(guò)traceid關(guān)聯(lián)查詢出來(lái)了。
如何透?jìng)?、如何記錄呢?或者說(shuō)如何透?jìng)?、如何記錄讓各?yīng)用的開(kāi)發(fā)人員無(wú)需關(guān)注呢?

第二步,實(shí)現(xiàn)。不想看代碼可直接拉最后看結(jié)果和原理

如何傳遞,這里我們使用定義統(tǒng)一的Request類,所有的api層需要使用這個(gè)規(guī)范,代碼如下:

public class Request<T> implements Serializable {
    //header:攜帶需要傳遞的信息
    private RequestHeader header;
    //業(yè)務(wù)參數(shù)
    private T bizModel;
    //...省略get set
}
public class RequestHeader implements Serializable {

    //調(diào)用鏈唯一ID
    private String traceId;
    //當(dāng)前用戶Id
    private String userId;
    //上游調(diào)用方appId
    private String callAppId;
    //...省略get set
}

有了這個(gè)Request之后,我們?cè)诰W(wǎng)關(guān)層每次都生成traceId, 然后在各服務(wù)之間傳遞就能做到調(diào)用鏈的關(guān)聯(lián)了。我們繼續(xù)看個(gè)各應(yīng)用應(yīng)該如何定義服務(wù)和使用

    @ApiMethod
    @PostMapping("/test")
    @ApiOperation(value = "test", notes = "", response = String.class)
    public Response<ExampleRespDTO> test(@RequestBody Request<ExampleReqDTO> req) {
        ExampleRespDTO exampleRespDTO = new ExampleRespDTO();
        exampleRespDTO.setName(req.getBizModel().getName());

        //輸出當(dāng)前應(yīng)用的header信息
         System.out.println("上游的traceId:"+RequestContext.getHeader().getTraceId());
        System.out.println("上游的callAppId:"+RequestContext.getHeader().getCallAppId());
        System.out.println("上游的userId:"+RequestContext.getHeader().getUserId());


        /***
         * 模擬調(diào)用其他應(yīng)用服務(wù)
         * 通過(guò)RPCRequest 來(lái)構(gòu)建request對(duì)象
         */
        Request<OtherAppServiceReqDTO>  otherAppServiceReqDTORequest =RPCRequest.createRequest(new OtherAppServiceReqDTO());

        //輸出下游應(yīng)用的header信息
        System.out.println("調(diào)用下游的traceId:"+otherAppServiceReqDTORequest.getHeader().getTraceId());
        System.out.println("調(diào)用下游的callAppId:"+otherAppServiceReqDTORequest.getHeader().getCallAppId());
        System.out.println("調(diào)用下游的userId:"+otherAppServiceReqDTORequest.getHeader().getUserId());

        return Response.successResponse(exampleRespDTO);
    }

看完上面代碼的同學(xué),應(yīng)該看到了有一個(gè)模擬調(diào)用其他服務(wù)的地方,這里主要解決的是服務(wù)和服務(wù)之間的調(diào)用header傳遞的問(wèn)題,這里封裝了一個(gè)createRequest的方法,其主要內(nèi)容還是把當(dāng)前應(yīng)用的requestHeader 賦值給請(qǐng)求其他服務(wù)的request上。這也是一個(gè)測(cè)試接口,最后面有測(cè)試的結(jié)果

public class RPCRequest {
    public static <T> Request<T> createRequest(T requestData){
        Request<T> request = new Request();
        RequestHeader requestHeader=new RequestHeader();
        requestHeader.setTraceId(RequestContext.getHeader().getTraceId());
        requestHeader.setUserId(RequestContext.getHeader().getUserId());
        requestHeader.setCallAppId(AppConfig.CURRENT_APP_ID);
        request.setHeader(requestHeader);
        request.setBizModel(requestData);
        return request;
    }
}

當(dāng)前request中的header存在什么地方呢,我們看一下RequestContext的代碼

public class RequestContext {
  private static ThreadLocal<RequestHeader> threadLocal=new ThreadLocal<>();
   public static void setHeader(RequestHeader header){
       threadLocal.set(header);
   }
   public static RequestHeader getHeader(){
       return threadLocal.get();
   }
   public static void clear(){
       threadLocal.remove();
   }
}

header是什么時(shí)候放進(jìn)去的呢?這里就是AOP該發(fā)揮作用的時(shí)候了,直接看代碼

public class ApiHandler {
    public ApiHandler() {
    }

    public Response handleApiMethod(ProceedingJoinPoint pjp, ApiMethod apiMethod) {
        //獲取上游調(diào)用方的request header
        Object[] args = pjp.getArgs();
        Request request = (Request) args[0];
        RequestHeader header = request.getHeader();
        //將header加入到當(dāng)前request 到ThreadLocal保存
        RequestContext.setHeader(header);
        Response response = null;
        try {
            //構(gòu)建response header
            ResponseHeader responseHeader = new ResponseHeader();
            responseHeader.setTraceId(RequestContext.getHeader().getTraceId());
            //執(zhí)行service方法
            response = (Response) pjp.proceed(args);
            response.setHeader(responseHeader);

        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }finally {
            //清除ThreadLocal中當(dāng)前請(qǐng)求的header 對(duì)象
            RequestContext.clear();
        }
        return response;

    }
}

不想看代碼的,直接看下圖,原理比較簡(jiǎn)單,淺黃色為AOP作用,接口執(zhí)行前和執(zhí)行后,其中reqeuest和header的定義在第1段代碼

這里沒(méi)有介紹如何收集數(shù)據(jù)和查詢展示,比較簡(jiǎn)單的辦法是使用logback打本地日志,然后通過(guò)agent抽到集中式日志進(jìn)行查詢展示,例如ELK。

測(cè)試一下結(jié)果:

1、接口文檔

2、執(zhí)行結(jié)果

以上就是Java 實(shí)現(xiàn)分布式服務(wù)的調(diào)用鏈跟蹤的詳細(xì)內(nèi)容,更多關(guān)于Java 分布式服務(wù)的調(diào)用鏈跟蹤的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java詳細(xì)分析講解自動(dòng)裝箱自動(dòng)拆箱與Integer緩存的使用

    Java詳細(xì)分析講解自動(dòng)裝箱自動(dòng)拆箱與Integer緩存的使用

    裝箱就是把基本類型轉(zhuǎn)換成包裝類,拆箱就是把包裝類轉(zhuǎn)換成基本類型,下面這篇文章主要給大家介紹Java中自動(dòng)裝箱、自動(dòng)拆箱與Integer緩存,需要的朋友可以參考下
    2022-04-04
  • 使用Java進(jìn)行FreeMarker的web模板開(kāi)發(fā)的基礎(chǔ)教程

    使用Java進(jìn)行FreeMarker的web模板開(kāi)發(fā)的基礎(chǔ)教程

    這篇文章主要介紹了使用Java進(jìn)行FreeMarker模板引擎開(kāi)發(fā)的基礎(chǔ)教程,文中針對(duì)FreeMarker的網(wǎng)頁(yè)標(biāo)簽用法給出了一些例子,需要的朋友可以參考下
    2016-03-03
  • gateway與spring-boot-starter-web沖突問(wèn)題的解決

    gateway與spring-boot-starter-web沖突問(wèn)題的解決

    這篇文章主要介紹了gateway與spring-boot-starter-web沖突問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java通過(guò)反射將 Excel 解析成對(duì)象集合實(shí)例

    Java通過(guò)反射將 Excel 解析成對(duì)象集合實(shí)例

    這篇文章主要介紹了Java通過(guò)反射將 Excel 解析成對(duì)象集合實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • IDEA中實(shí)現(xiàn)springboot熱部署方式

    IDEA中實(shí)現(xiàn)springboot熱部署方式

    在IDEA中實(shí)現(xiàn)SpringBoot的熱部署可以通過(guò)修改設(shè)置來(lái)完成,首先在設(shè)置中搜索Compiler,并勾選Build project automatically,然后進(jìn)入Advanced Settings,勾選Allow auto-make to start even if developed application is currently running
    2024-09-09
  • mybatis關(guān)聯(lián)關(guān)系映射的實(shí)現(xiàn)

    mybatis關(guān)聯(lián)關(guān)系映射的實(shí)現(xiàn)

    MyBatis的關(guān)聯(lián)關(guān)系映射在復(fù)雜數(shù)據(jù)模型中至關(guān)重要,使開(kāi)發(fā)人員能夠以最靈活的方式滿足不同項(xiàng)目的需求,本文就來(lái)介紹一下mybatis關(guān)聯(lián)關(guān)系映射的實(shí)現(xiàn),感興趣的可以了解一下
    2023-09-09
  • 如何在springboot中使用定時(shí)任務(wù)

    如何在springboot中使用定時(shí)任務(wù)

    這篇文章主要介紹了如何在springboot中使用定時(shí)任務(wù),幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-12-12
  • SpringBoot配置Apollo代碼實(shí)例

    SpringBoot配置Apollo代碼實(shí)例

    這篇文章主要介紹了SpringBoot配置Apollo代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java利用POI讀寫(xiě)Excel文件工具類

    Java利用POI讀寫(xiě)Excel文件工具類

    這篇文章主要為大家詳細(xì)介紹了Java利用POI讀寫(xiě)Excel文件的工具類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 一文帶你徹底理解Java序列化和反序列化

    一文帶你徹底理解Java序列化和反序列化

    這篇文章主要介紹了Java序列化和反序列化的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-09-09

最新評(píng)論