国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

記一次JSF異步調(diào)用引起的接口可用率降低

這篇具有很好參考價(jià)值的文章主要介紹了記一次JSF異步調(diào)用引起的接口可用率降低。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

本文記錄了由于JSF異步調(diào)用超時(shí)引起的接口可用率降低問(wèn)題的排查過(guò)程,主要介紹了排查思路和JSF異步調(diào)用的流程,希望可以幫助大家了解JSF的異步調(diào)用原理以及提供一些問(wèn)題排查思路。本文分析的JSF源碼是基于JSF 1,7.5-HOTFIX-T6版本。

起因

問(wèn)題背景

1.廣告投放系統(tǒng)是典型的I/O密集型(I/O Bound)服務(wù),系統(tǒng)中某些接口單次操作可能依賴十幾個(gè)外部接口,導(dǎo)致接口耗時(shí)較長(zhǎng),嚴(yán)重影響用戶體驗(yàn),因此需要將這些外部調(diào)用切換為異步模式,通過(guò)并發(fā)的模式降低整體耗時(shí),提高接口的響應(yīng)速度。
2.在同步調(diào)用的場(chǎng)景下,接口耗時(shí)長(zhǎng)、性能差,接口響應(yīng)時(shí)間長(zhǎng)。這時(shí)為了縮短接口的響應(yīng)時(shí)間,一般會(huì)使用線程池的方式并行獲取數(shù)據(jù),但是如果使用線程池來(lái)做,不同業(yè)務(wù)需要不同的線程池,最后會(huì)導(dǎo)致難以維護(hù),隨著CPU調(diào)度線程數(shù)的增加,會(huì)導(dǎo)致更嚴(yán)重的資源爭(zhēng)用,寶貴的CPU資源被損耗在上下文切換上,而且線程本身也會(huì)占用系統(tǒng)資源,且不能無(wú)限增加。
3.通過(guò)閱讀JSF的文檔發(fā)現(xiàn)JSF是支持異步調(diào)用模式的,既然中間件已經(jīng)支持這個(gè)功能,所以我們就采用了JSF提供的異步調(diào)用模式,目前JSF支持三種異步調(diào)用方式,分別是ResponseFuture方式、CompletableFuture方式和定義返回值為 CompletableFuture 的接口簽名方式。

(1)RpcContext中獲取ResponseFuture方式

該方式需要先將Consumer端的async屬性設(shè)置為true,代表開啟異步調(diào)用,然后在調(diào)用Provider的地方使用RpcContext.getContext().getFuture()方法獲取一個(gè)ResponseFuture,拿到Future以后就可以使用get方法去阻塞等待返回,但是這種方式已經(jīng)不推薦使用了,因?yàn)榈诙NCompletableFuture的模式更加強(qiáng)大。

代碼示例:

asyncHelloService.sayHello("The ResponseFuture One");
ResponseFuture<Object> future1 = RpcContext.getContext().getFuture();
asyncHelloService.sayNoting("The ResponseFuture Two");
ResponseFuture<Object> future2 = RpcContext.getContext().getFuture();
try {
     future1.get();
     future2.get();
} catch (Throwable e) {
    LOGGER.error("catch " + e.getClass().getCanonicalName() + " " + e.getMessage(), e);
}

(2)RpcContext中獲取CompletableFuture方式(1.7.5及以上版本支持)

該方式需要先將Consumer端的async屬性設(shè)置為true,代表開啟異步調(diào)用,然后在調(diào)用Provider的地方使用RpcContext.getContext().getCompletableFuture()方法獲取到一個(gè)CompletableFuture進(jìn)行后續(xù)操作。CompletableFuture對(duì)Future進(jìn)行了擴(kuò)展,可以通過(guò)設(shè)置回調(diào)的方式處理計(jì)算結(jié)果,支持組合操作,也支持進(jìn)一步的編排,一定程度解決了回調(diào)地獄的問(wèn)題。

代碼示例:

asyncHelloService.sayHello("The CompletableFuture One");
CompletableFuture<String> cf1 = RpcContext.getContext().getCompletableFuture();
asyncHelloService.sayNoting("The CompletableFuture Two");
CompletableFuture<String> cf2 = RpcContext.getContext().getCompletableFuture();

CompletableFuture<String> cf3 {
    asyncHelloService.sayHello("The CompletableFuture Three");
});
try {
    cf1.get();
    cf2.get();
    cf3.get();
} catch (Throwable e) {
    LOGGER.error("catch " + e.getClass().getCanonicalName() + " " + e.getMessage(), e);
}

(3)使用 CompletableFuture 簽名的接口(1.7.5及以上版本支持)

這種模式需要改造代碼,需要服務(wù)的提供者事先定義方法的返回值簽名為CompletableFuture,這種調(diào)用端無(wú)需配置即可使用異步。

代碼示例:

CompletableFuture<String> cf4 = asyncHelloService.sayHelloAsync("The CompletableFuture Fore");
cf4.whenComplete((res, err) {
    if (err != null) {
        LOGGER.error("interface async cf4 now complete error " + err.getClass().getCanonicalName() + " " + err.getMessage(), err);
    } else {
        LOGGER.info("interface async cf4 now complete : {}", res);
    }
});
CompletableFuture<Void> cf5 = asyncHelloService.sayNotingAsync("The CompletableFuture Five");

try {
    LOGGER.info("interface async cf1 now is : {}", cf4.get());
    LOGGER.info("interface async cf2 now is : {}", cf5.get());
} catch (Throwable e) {
    LOGGER.error("catch " + e.getClass().getCanonicalName() + " " + e.getMessage(), e);
}

通過(guò)對(duì)已上三種異步調(diào)用模式的分析,第三種需要提供者修改方法簽名支持異步,難以實(shí)現(xiàn);本著改動(dòng)最小化,API使用最優(yōu)化,我們最終選擇了第二種方式,即在調(diào)用端設(shè)置async屬性為true,同時(shí)在發(fā)起調(diào)用后從RpcContext中獲取一個(gè)CompletableFuture對(duì)象進(jìn)行后續(xù)的操作。

問(wèn)題現(xiàn)象

經(jīng)過(guò)異步模式改造,部分依賴很多外部服務(wù)的接口耗時(shí)有明顯的下降,表面看系統(tǒng)一片祥和,但是偶爾的接口可用率降低卻是一個(gè)非常危險(xiǎn)的信號(hào),下面是使用異步調(diào)用的某個(gè)接口的可用率監(jiān)控

?

?

?

通過(guò)監(jiān)控我們可以發(fā)現(xiàn),這個(gè)接口偶爾會(huì)出現(xiàn)可用率降低,一般接口可用率降低可能是因?yàn)槌瑫r(shí)或者觸發(fā)了某些隱藏問(wèn)題導(dǎo)致,但是這個(gè)接口的邏輯非常簡(jiǎn)單,就是根據(jù)id查詢數(shù)據(jù)庫(kù),業(yè)務(wù)邏輯非常簡(jiǎn)單,理論上不應(yīng)該出現(xiàn)這么多可用率降低的情況。我們通過(guò)日志排查發(fā)現(xiàn)在異步調(diào)用使用CompletableFuture的get方法阻塞等待的時(shí)候發(fā)生了TimeOutException異常,目前接口配置的超時(shí)時(shí)間為5s,本來(lái)接口超時(shí)是一個(gè)我們經(jīng)常遇見的問(wèn)題,但是我們?nèi)ヌ峁┱叨瞬樵內(nèi)罩景l(fā)現(xiàn),本次請(qǐng)求只耗費(fèi)了幾毫秒,明明提供者端幾毫秒或者幾十毫秒就返回了,為什么消費(fèi)端還超時(shí)了,帶著這個(gè)疑問(wèn)我們繼續(xù)分析,會(huì)不會(huì)是JSF異步的原因?qū)е碌摹?/p>

排查定位原因

通過(guò)閱讀JSF的源碼,我們了解到JSF異步調(diào)用的基本流程為客戶端向服務(wù)端發(fā)送請(qǐng)求前,會(huì)先判斷本次請(qǐng)求是否需要走異步調(diào)用,如果需要的話,會(huì)生成一個(gè)JSFCompletableFuture對(duì)象 這個(gè)類是繼承自CompletableFuture的,同時(shí)使用一個(gè)futureMap對(duì)象緩存了請(qǐng)求的唯一msgId和一個(gè)MsgFuture對(duì)象,MsgFuture對(duì)象里面持有了本次調(diào)用使用的channel、message、timeout、compatibleFuture等屬性,方便服務(wù)端回調(diào)后,可以通過(guò)msgId找到對(duì)應(yīng)的MsgFuture對(duì)象做后續(xù)處理。

首先在doSendAsyn方法里生成MsgId和MsgFuture對(duì)象的映射,然后序列化數(shù)據(jù),最后通過(guò)netty的長(zhǎng)連接向channel里面寫入要發(fā)送的數(shù)據(jù)。

(1)生成JSFCompletableFuture

?

?

?

(2)維護(hù)msgId和MsgFuture的關(guān)系

?

?

?

(3) 維護(hù)msgId和MsgFuture的關(guān)系

?

?

?

(4)發(fā)起調(diào)用

?

?

?

服務(wù)端收到請(qǐng)求后,會(huì)觸發(fā)服務(wù)端的ServerChannelHandler類的channelRead方法被回調(diào),這個(gè)方法里面會(huì)驗(yàn)證序列化協(xié)議,然后生成一個(gè)JSFTask的任務(wù),將這個(gè)任務(wù)提交到JSF的業(yè)務(wù)線程池去執(zhí)行,等業(yè)務(wù)線程池里的任務(wù)執(zhí)行完成以后,會(huì)調(diào)用write方法將返回值通過(guò)channel寫回客戶端。

(1)服務(wù)端收到響應(yīng)處理

?

?

?

(2)服務(wù)端回寫響應(yīng)

?

?

?

客戶端收到響應(yīng)后,會(huì)觸發(fā)客戶端的ClientChannelHandler類的channelRead方法,這個(gè)方法里面會(huì)通過(guò)服務(wù)端返回的msgId找到客戶端緩存的MsgFuture對(duì)象,然后會(huì)判斷對(duì)象內(nèi)的compatibleFuture屬性是不是非空,如果非空,會(huì)往Callback線程池內(nèi)提交一個(gè)任務(wù),這個(gè)任務(wù)的主要功能是執(zhí)行CompletableFuture的completeExceptionally和complete方法,用于觸發(fā)CompletableFuture的下一階段執(zhí)行。

(1)客戶端收到響應(yīng)

?

?

?

(2)找到本地的MsgFuture

?

?

?

(3)將MsgFuture添加到線程池

?

?

?

(4) 觸發(fā)CompletableFuture的complete或者completeExceptionally方法

?

?

?

通過(guò)對(duì)已上源碼的分析,我們雖然知道了JSF異步調(diào)用的全部流程,但是還是無(wú)法解釋為什么偶爾會(huì)出現(xiàn)不應(yīng)該超時(shí)的超時(shí)(此處指服務(wù)端明明沒有超時(shí),客戶端還顯示超時(shí)了),通過(guò)對(duì)各個(gè)流程的排除,我們最終定位到可能和JSF異步回調(diào)后將任務(wù)添加到Callback線程池去執(zhí)行CompletableFuture的complete方法有關(guān),因?yàn)檫@個(gè)方法會(huì)繼續(xù)執(zhí)行CompletableFuture后續(xù)的階段,我們業(yè)務(wù)代碼在拿到RpcContext里面返回的CompletableFuture對(duì)象以后,一般會(huì)使用CompletableFuture的一元依賴方法ThenApply去執(zhí)行一些后續(xù)處理,CompletableFuture的complete方法就是用來(lái)觸發(fā)這些后續(xù)階段去執(zhí)行的。

異步調(diào)用業(yè)務(wù)代碼:

?

?

下面介紹一下CompletableFuture的基礎(chǔ)知識(shí),每個(gè)CompletableFuture都可以被看作一個(gè)被觀察者,其內(nèi)部有一個(gè)Completion類型的鏈表成員變量stack,用來(lái)存儲(chǔ)注冊(cè)到其中的所有觀察者。當(dāng)被觀察者執(zhí)行完成后會(huì)彈棧stack屬性,依次通知注冊(cè)到其中的觀察者,所以在這個(gè)階段會(huì)去調(diào)用我們程序中的ThenApply方法,下圖是CompletableFuture內(nèi)部的關(guān)鍵屬性。

?

?

?

如果上面的異步調(diào)用流程感覺不清晰,可以看下面的一張調(diào)用關(guān)系圖

?

?

?

?

通過(guò)查看Callack線程池的默認(rèn)配置,發(fā)現(xiàn)他的核心線程數(shù)為20,隊(duì)列長(zhǎng)度256,最大線程數(shù)200。看到這我們猜測(cè)可能是核心線程數(shù)不夠用,導(dǎo)致一些回調(diào)任務(wù)積壓在隊(duì)列中沒來(lái)得及執(zhí)行導(dǎo)致了超時(shí)。由于無(wú)法通過(guò)其他方式獲取當(dāng)時(shí)CallBack線程池的運(yùn)行狀態(tài),因此我們通過(guò)修改業(yè)務(wù)代碼,在發(fā)生超時(shí)異常的時(shí)候獲取Callback線程池當(dāng)前的狀態(tài)來(lái)驗(yàn)證我們的猜測(cè)。

(1)獲取線程池狀態(tài)代碼

?

?

?

修改完代碼上線后,系統(tǒng)運(yùn)行一段時(shí)間出現(xiàn)了接口可用率降低的現(xiàn)象,接著我們查詢?nèi)罩?,從日志里可以看出,在發(fā)生超時(shí)異常的時(shí)候,JSF的Callback線程池核心線程數(shù)已滿,同時(shí)隊(duì)列中積壓了71個(gè)任務(wù),通過(guò)這個(gè)日志就可以確定是因?yàn)镴SF 回調(diào)線程池核心線程數(shù)滿導(dǎo)致任務(wù)排隊(duì)出現(xiàn)的超時(shí)

?

?

?

問(wèn)題分析

1、通過(guò)上面的日志我們知道是因?yàn)楫惒骄€程池滿導(dǎo)致的,理論上正常請(qǐng)求就算有些排隊(duì)?wèi)?yīng)該也會(huì)很快就能處理掉,但是我們排查業(yè)務(wù)代碼后發(fā)現(xiàn),我們有些業(yè)務(wù)在ThenApply里面做了一些耗時(shí)的操作、還有在ThenApply里面又調(diào)用了另外一個(gè)異步方法。

2、第一種情況會(huì)導(dǎo)致線程池的線程會(huì)被一直占用,其他任務(wù)都會(huì)在排隊(duì),這種其實(shí)還是能接受的,但是第二種情況可能會(huì)出現(xiàn)線程池循環(huán)引用導(dǎo)致死鎖,原因是父任務(wù)會(huì)將異步回調(diào)放在線程池執(zhí)行,父任務(wù)的子任務(wù)也會(huì)將異步回調(diào)放在線程池執(zhí)行,Callback線程池核心線程大小為20,當(dāng)同一時(shí)刻有20個(gè)請(qǐng)求到達(dá),則Callback core thread被打滿,子任務(wù)請(qǐng)求線程時(shí)進(jìn)入阻塞隊(duì)列排隊(duì),但是父任務(wù)的完成又依賴于子任務(wù),這時(shí)由于子任務(wù)得不到線程,父任務(wù)無(wú)法完成,主線程執(zhí)行g(shù)et進(jìn)入阻塞狀態(tài),并且永遠(yuǎn)無(wú)法恢復(fù)。

解決方案

短期方案:因?yàn)榫€程池核心線程滿導(dǎo)致排隊(duì),所以將JSF 的回調(diào)線程池核心線程數(shù)從20調(diào)整為200,

長(zhǎng)期方案:優(yōu)化代碼將ThenApply里面耗時(shí)的操作不放在回調(diào)線程池執(zhí)行,同時(shí)優(yōu)化代碼邏輯,將在ThenApply方法內(nèi)部再次開啟異步調(diào)用的流程去除。

調(diào)整完前后的對(duì)比:

?

?

?

通過(guò)查看監(jiān)控可以發(fā)現(xiàn),優(yōu)化后接口可用率一直保持在100%。

作者:京東零售 宋維飛

來(lái)源:京東云開發(fā)者社區(qū) 轉(zhuǎn)載請(qǐng)注明來(lái)源文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-777087.html

到了這里,關(guān)于記一次JSF異步調(diào)用引起的接口可用率降低的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 記一次uni-app中調(diào)用java代碼中的方法全過(guò)程

    記一次uni-app中調(diào)用java代碼中的方法全過(guò)程

    一、 開發(fā)環(huán)境 ? JAVA環(huán)境 jdk1.8 ? AndroidStudio 下載地址:Android Studio官網(wǎng) : https://developer.android.google.cn/studio/index.html ? App離線SDK下載 請(qǐng)下載2.9.8+版本的android平臺(tái)SDK. https://nativesupport.dcloud.net.cn/AppDocs/download/android.html# ? HBuilderX下載 官方下載地址: https://www.dcloud.io/hbuilderx.ht

    2024年02月12日
    瀏覽(25)
  • 異步http接口調(diào)用庫(kù):httpx

    異步http接口調(diào)用庫(kù):httpx

    談到http接口調(diào)用,Requests大家并不陌生,例如,robotframework-requests、HttpRunner等HTTP接口測(cè)試庫(kù)/框架都是基于它開發(fā)。這里將介紹另一款http接口測(cè)試框架:httpx。 它的API和Requests高度一致。 github: GitHub - encode/httpx: A next generation HTTP client for Python. ?? 安裝: httpx 簡(jiǎn)單使用 當(dāng)然,它

    2024年01月15日
    瀏覽(17)
  • 記一次排查:接口返回值寫入excel后,從單元格copy出來(lái)的數(shù)據(jù)會(huì)帶有多重引號(hào)的問(wèn)題

    記一次排查:接口返回值寫入excel后,從單元格copy出來(lái)的數(shù)據(jù)會(huì)帶有多重引號(hào)的問(wèn)題

    在項(xiàng)目里剛好有3個(gè)服務(wù),同一個(gè)網(wǎng)關(guān)內(nèi)層的3個(gè)服務(wù),兩個(gè)php的,一個(gè)golang的,為了提高負(fù)載以及進(jìn)行分流,部分客戶的接口調(diào)用會(huì)被網(wǎng)關(guān)自動(dòng)分配到go服務(wù)。 恰好為了測(cè)試,我寫了一個(gè)全量用戶的生產(chǎn)、測(cè)試環(huán)境調(diào)用接口返回結(jié)果進(jìn)行對(duì)比的腳本,于是發(fā)現(xiàn)了題中的問(wèn)題:

    2024年02月05日
    瀏覽(21)
  • springboot @Async 異步調(diào)用接口處理數(shù)據(jù)

    springboot @Async 異步調(diào)用接口處理數(shù)據(jù)

    @Async 異步背景 新增的數(shù)據(jù)需要分發(fā)給下游業(yè)務(wù)系統(tǒng),由于下游業(yè)務(wù)系統(tǒng)狀態(tài)未知,所以需要異步發(fā)送數(shù)據(jù)給下游業(yè)務(wù)系統(tǒng)。 系統(tǒng)生效按鈕---controller新增--異步調(diào)用servcie---數(shù)據(jù)集成 在springboot框架中實(shí)現(xiàn)步驟 首先在啟動(dòng)類上加上 @EnableAsync 注解開啟項(xiàng)目的異步調(diào)用功能,其次

    2024年02月16日
    瀏覽(23)
  • 記一次Feign調(diào)用報(bào)錯(cuò)feign.codec.DecodeException: Error while extracting response for type [java.util.List...

    ? ? ? ? 在今天工作時(shí),臨時(shí)收到生產(chǎn)問(wèn)題,檢查發(fā)現(xiàn)是在本服務(wù)Feign遠(yuǎn)程調(diào)用其他服務(wù)時(shí)方法時(shí)發(fā)生的,具體報(bào)錯(cuò)詳情,及原因和解決方法均記錄在下方。 ????????feign.codec.DecodeException: Error while extracting response for type [java.util.ListObject] and content type [application/json]; nested

    2024年04月13日
    瀏覽(21)
  • OpenApi接口的一次調(diào)用經(jīng)歷(附代碼)

    OpenApi接口的一次調(diào)用經(jīng)歷(附代碼)

    去弄一個(gè)api_key:https://platform.openai.com/account/api-keys? ?先看所有能用的模型: 返回: babbage davinci text-davinci-edit-001 babbage-code-search-code text-similarity-babbage-001 code-davinci-edit-001 text-davinci-001 ada curie-instruct-beta babbage-code-search-text babbage-similarity whisper-1 code-search-babbage-text-001 text-curie-

    2024年02月12日
    瀏覽(22)
  • php 接口請(qǐng)求一次,controller調(diào)用了兩次。

    這幾天開發(fā)一個(gè)數(shù)據(jù)導(dǎo)出功能 由于是數(shù)據(jù)導(dǎo)出,所以有點(diǎn)慢。然后發(fā)現(xiàn)一個(gè)問(wèn)題,前端只請(qǐng)求一次,controller卻收到了兩次請(qǐng)求。而且第二次請(qǐng)求i必定失敗 這就悲催了。腦子懵懵的! 由于我這就是個(gè)小活兒,于是環(huán)境就是使用的nginx+fastcgi 網(wǎng)上搜索了一圈,大多都是說(shuō)跨域的

    2024年02月06日
    瀏覽(16)
  • 【并發(fā)編程】線程池多線程異步去分頁(yè)調(diào)用其他服務(wù)接口獲取海量數(shù)據(jù)

    前段時(shí)間在做一個(gè)數(shù)據(jù)同步工具,其中一個(gè)服務(wù)的任務(wù)是調(diào)用A服務(wù)的接口,將數(shù)據(jù)庫(kù)中指定數(shù)據(jù)請(qǐng)求過(guò)來(lái),交給kafka去判斷哪些數(shù)據(jù)是需要新增,哪些數(shù)據(jù)是需要修改的。 剛開始的設(shè)計(jì)思路是,,我創(chuàng)建多個(gè)服務(wù)同時(shí)去請(qǐng)求A服務(wù)的接口,每個(gè)服務(wù)都請(qǐng)求到全量數(shù)據(jù),由于這些

    2024年02月13日
    瀏覽(31)
  • 介紹 dubbo-go 并在Mac上安裝,完成一次自己定義的接口RPC調(diào)用

    介紹 dubbo-go 并在Mac上安裝,完成一次自己定義的接口RPC調(diào)用

    對(duì)開發(fā)者更透明,減少了很多的溝通成本。 RPC向遠(yuǎn)程服務(wù)器發(fā)送請(qǐng)求時(shí),未必要使用 HTTP 協(xié)議,比如還可以用 TCP / IP,性能更高(內(nèi)部服務(wù)更適用)。 ?? 注意:在整個(gè)流程中,最終的調(diào)用并不是由注冊(cè)中心來(lái)完成的。雖然注冊(cè)中心會(huì)提供信息,但實(shí)際上調(diào)用方需要自己進(jìn)行

    2024年02月10日
    瀏覽(18)
  • 【并發(fā)編程】自研數(shù)據(jù)同步工具的優(yōu)化:創(chuàng)建線程池多線程異步去分頁(yè)調(diào)用其他服務(wù)接口獲取海量數(shù)據(jù)

    前段時(shí)間在做一個(gè)數(shù)據(jù)同步工具,其中一個(gè)服務(wù)的任務(wù)是調(diào)用A服務(wù)的接口,將數(shù)據(jù)庫(kù)中指定數(shù)據(jù)請(qǐng)求過(guò)來(lái),交給kafka去判斷哪些數(shù)據(jù)是需要新增,哪些數(shù)據(jù)是需要修改的。 剛開始的設(shè)計(jì)思路是,,我創(chuàng)建多個(gè)服務(wù)同時(shí)去請(qǐng)求A服務(wù)的接口,每個(gè)服務(wù)都請(qǐng)求到全量數(shù)據(jù),由于這些

    2024年02月12日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包