国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

如何處理有依賴(lài)的消息

Tony / 3618人閱讀

摘要:生產(chǎn)者生產(chǎn)的消息要滿(mǎn)足不了消費(fèi)者才行??梢钥吹揭粋€(gè)有依賴(lài)的消息我們?cè)谔幚淼倪^(guò)程,會(huì)多一次查詢(xún)操作,性能多少會(huì)受點(diǎn)影響。如果沒(méi)有的消息進(jìn)來(lái),孤兒院里是醬紫的。收到之后再處理,緊接著又找到的條消息,再出來(lái),讓去處理。

在項(xiàng)目中踏完一系列坑后總結(jié)出來(lái),消息的處理有兩個(gè)要?jiǎng)?wù):

消費(fèi)一定要快,我們喜歡供小于求的市場(chǎng)。生產(chǎn)者生產(chǎn)的消息要滿(mǎn)足不了消費(fèi)者才行。

任何消息都不能丟,因?yàn)檫@都是數(shù)據(jù)啊,即使處理不了也得找地方存著。最好每次的消息都存著,之后就變成了event sourcing(另一個(gè)大坑)。

要實(shí)現(xiàn)上述2點(diǎn),其實(shí)要解決很多問(wèn)題。一個(gè)字就不是那么做到的。業(yè)務(wù)系統(tǒng)收到消息有可能會(huì)觸發(fā)一連串的,并且包裹著事務(wù)的邏輯。因?yàn)橥ǔN覀兿M绻@一連串的處理失敗的話(huà),可以把a(bǔ)ck退回給MQ。一旦業(yè)務(wù)邏輯過(guò)于復(fù)雜,work消費(fèi)消息的速度也會(huì)變慢。這就需要開(kāi)發(fā)人員去做權(quán)衡了,是不是有些非常heavy的操作可以先記一筆,等業(yè)務(wù)不繁忙的時(shí)候再做。具體實(shí)現(xiàn)不在這篇討論。

問(wèn)題

回到主題,有一類(lèi)消息最讓人頭疼,就是消息之間有依賴(lài),關(guān)系一般為單向的父子關(guān)系。舉個(gè)栗子,Product和SKU的關(guān)系,一個(gè)Product包含多個(gè)SKU。比如我們的業(yè)務(wù)邏輯是要監(jiān)聽(tīng)這兩個(gè)消息組成一顆樹(shù)放到索引中。可想而知,這棵樹(shù)肯定是至少兩層結(jié)構(gòu),第一級(jí)是Product,下面掛著一個(gè)或多個(gè)SKU。

一般來(lái)說(shuō),子結(jié)構(gòu)如果是個(gè)多帶帶的消息肯定會(huì)有個(gè)字段說(shuō)明自己的parent id是什么。那么很自然的,我們?cè)谀骋豢讨皇盏揭粋€(gè)SKU的Create事件,會(huì)去通過(guò)parent id找到索引中對(duì)應(yīng)的Product,然后上去。問(wèn)題來(lái)了,要是索引中沒(méi)有對(duì)應(yīng)的Product怎么辦,消息是沒(méi)有順序的,可能是Product的Create事件還沒(méi)處理到,或者是生產(chǎn)者出了bug消息沒(méi)發(fā)出來(lái)造成的。這時(shí)SKU的消息就成了孤兒消息。

解決思路一

比較近粗暴的方式,就是利用SKU上的parent id虛擬出一個(gè)只有id的Product,由處理SKU事件的worker來(lái)幫忙創(chuàng)建這個(gè)Product。等下次Product的Create消息進(jìn)來(lái)做一次更新就好了。(處理消息應(yīng)該不要區(qū)分這是Create還是Update還是Delete,消費(fèi)者就都當(dāng)Update來(lái)做比較好,可以想想為什么)。

當(dāng)然這個(gè)思路一看就有點(diǎn)bad smell,從單一職責(zé)的角度上來(lái)看,處理SKU的worker應(yīng)該只關(guān)注SKU,不應(yīng)該關(guān)注Product。如果Product也是個(gè)孤兒怎么辦呢?這個(gè)worker可能會(huì)越寫(xiě)越復(fù)雜。

改進(jìn)的話(huà)可以把創(chuàng)建虛擬Product的這個(gè)事情放到SKU這個(gè)對(duì)象中去做,實(shí)現(xiàn)以下setProduct這個(gè)方法。那么即使Product也有依賴(lài),那Product自己也得有個(gè)setParent的方法,這樣就可以遞歸下去了。(之后想了一下無(wú)法處理多級(jí)關(guān)系,因?yàn)镻roduct的消息沒(méi)來(lái),我們不知道它的parent id,父節(jié)點(diǎn)根本建不出來(lái)。所以思路一只能處理一個(gè)層級(jí)的依賴(lài)。)

總結(jié)一下,思路一是一種不管三七二十一,誰(shuí)也不能阻止我消費(fèi)的路線(xiàn),大不了自下而上的創(chuàng)建虛擬父節(jié)點(diǎn)。

解決思路二

相對(duì)思路一而言,這種思路還是比較優(yōu)雅的,但是優(yōu)雅不等于性能好。

既然SKU是個(gè)孤兒,那么我們先收下來(lái)放孤兒院好了。新建一張孤兒院表:

id parent_type parent_id
101010 Product 1010
101011 Product 1010

上面兩條數(shù)據(jù)就是SKU的,然后為了提升一點(diǎn)性能我們得對(duì)對(duì)象分個(gè)類(lèi),一類(lèi)是有依賴(lài)的,一類(lèi)是無(wú)依賴(lài)的。沒(méi)有依賴(lài)的直接消費(fèi)就好,像Product,SKU這種有依賴(lài)的,都得打上標(biāo)簽(就是對(duì)象里寫(xiě)個(gè)isDependency)。例如一個(gè)SKU(101010)的消息進(jìn)來(lái),worker發(fā)現(xiàn)這是一個(gè)有依賴(lài)的消息,那么先拿parent id (1010)去找Product, 發(fā)現(xiàn)Product找不到就把這個(gè)SKU丟到孤兒院表里去。如果你是用OO的語(yǔ)言,這里其實(shí)可以抽象一下。一個(gè)BaseWorker,一個(gè)SKUWorker,BaseWork負(fù)責(zé)寫(xiě)個(gè)abstract的findParent(),SKUWorker去實(shí)現(xiàn)找Product的邏輯就好了。

public abstract class BaseWorker {
    
    public void handle(T t) {
        if (t.isDependency() && findParent(t) == null) {
            // 送到孤兒院
            takeToOrphanage(t);
            return;
        }
    }
    
    abstract Entity findParent(T t);
    
    protected void takeToOrphanage(T t) {
    }
    
}

消息記錄下來(lái)以后,Worker的工作就終止,等待下一條消息進(jìn)來(lái)。過(guò)了幾分鐘,Product(1010)的消息過(guò)來(lái)了,這時(shí)候我們需要給BaseWorker再添加一些代碼。

public void handle(T t) {
        if (t.isDependency() && findParent(t) == null) {
            // 送到孤兒院
            takeToOrphanage(t);
            return;
        }
    
        // 正常業(yè)務(wù)...
    
        // 正常業(yè)務(wù)處理之后
        if (t.isDependency()) {
            List children = findChildren(t);
            if (children != null) {
                children.forEach(child -> {
                    sendAsMessage(child);
                });
            }
        }
    
    }
    
    abstract List findChildren(T t);

我們?cè)黾右粋€(gè)findChildren方法,讓ProductWorker去實(shí)現(xiàn)具體邏輯。handle()中增加的代碼含義是,當(dāng)Product這個(gè)消息消費(fèi)完了以后,去孤兒院轉(zhuǎn)一圈看看是不是有等待認(rèn)領(lǐng)的孩子,簡(jiǎn)單的利用parent_typeparent_id就能查到。查到以后別直接處理,仍然是以消息的形式發(fā)出,讓SKUWorker自己去handle,然后可以delete/soft-delete孤兒院中的記錄。

可以看到一個(gè)有依賴(lài)的消息我們?cè)谔幚淼倪^(guò)程,會(huì)多一次查詢(xún)操作,性能多少會(huì)受點(diǎn)影響。之前的那次findParent查詢(xún)其實(shí)思路一也有的,目的就是掛靠。

再多一個(gè)層級(jí)看看是不是罩得住,Category --> Product --> SKU 三層。

如果沒(méi)有Category的消息進(jìn)來(lái),孤兒院里是醬紫的。

id parent_type parent_id
101010 Product 1010
101011 Product 1010
1010 Category 10

某一時(shí)刻Category的消息進(jìn)來(lái),CategoryWorker會(huì)先到表里查到一條1010的Product消息,把它send出來(lái)。ProductWorker收到之后再處理,緊接著又找到SKU的2條消息,再send出來(lái),讓SKUWorker去處理??梢钥吹?,自帶遞歸,多層級(jí)只要是單向依賴(lài)的肯定搞的定。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/66305.html

相關(guān)文章

  • 何處理Docker錯(cuò)誤消息:please add——insecure-registry

    摘要:本地安裝時(shí),遇到如下的錯(cuò)誤消息解決方案點(diǎn)擊的菜單點(diǎn)擊標(biāo)簽頁(yè),在里維護(hù)記錄將錯(cuò)誤信息里提到的維護(hù)進(jìn)點(diǎn)擊按鈕重新啟動(dòng)之后錯(cuò)誤消息消失。 本地安裝Kubernetes時(shí),遇到如下的錯(cuò)誤消息: pleade add --insecure-registry gcr.io to daemons arguments showImg(https://segmentfault.com/img/remot...

    jsdt 評(píng)論0 收藏0
  • 白話(huà)RabbitMQ(六): RPC

    摘要:因?yàn)橄M(fèi)消息是在另外一個(gè)進(jìn)程中,我們需要阻塞我們的進(jìn)程直到結(jié)果返回,使用阻塞隊(duì)列是一種非常好的方式,這里我們使用了長(zhǎng)度為的,的功能是檢查消息的的是不是我們之前所發(fā)送的,如果是,將返回值返回到。 推廣 RabbitMQ專(zhuān)題講座 https://segmentfault.com/l/15... CoolMQ開(kāi)源項(xiàng)目 我們利用消息隊(duì)列實(shí)現(xiàn)了分布式事務(wù)的最終一致性解決方案,請(qǐng)大家圍觀??梢詤⒖?..

    KevinYan 評(píng)論0 收藏0
  • 何處理Docker錯(cuò)誤消息request canceled:Docker代理問(wèn)題

    摘要:在本地安裝時(shí),遇到錯(cuò)誤消息這個(gè)原因是應(yīng)用沒(méi)有正確設(shè)置代理。在上設(shè)置代理非常方便選擇即手動(dòng)設(shè)置。設(shè)置完之后,點(diǎn)擊按鈕之后在里使用命令行可以成功把鏡像下載到本地。 在本地安裝Kubernetes時(shí),遇到錯(cuò)誤消息: request canceled while waiting for connection(Client.Timeout exceeded while awaiting head...

    qianfeng 評(píng)論0 收藏0
  • 為Java程序員金三銀四精心挑選300余道Java面試題與答案

    摘要:為程序員金三銀四精心挑選的余道面試題與答案,歡迎大家向我推薦你在面試過(guò)程中遇到的問(wèn)題我會(huì)把大家推薦的問(wèn)題添加到下面的常用面試題清單中供大家參考。 為Java程序員金三銀四精心挑選的300余道Java面試題與答案,歡迎大家向我推薦你在面試過(guò)程中遇到的問(wèn)題,我會(huì)把大家推薦的問(wèn)題添加到下面的常用面試題清單中供大家參考。 前兩天寫(xiě)的以下博客,大家比較認(rèn)可,熱度不錯(cuò),希望可以幫到準(zhǔn)備或者正在參加...

    tomorrowwu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<