Dib u habaynta dhacdooyinka laga helay Kafka

Dib u habaynta dhacdooyinka laga helay Kafka

Haye Habr.

Dhawaan I khibradiisa ayuu la wadaagay ku saabsan waxa ku saabsan halbeegyada aan koox ahaan inta badan u isticmaalno Soo saaraha iyo Macaamilka Kafka si aan ugu dhowaano gaarsiinta dammaanadda ah. Maqaalkan waxaan rabaa in aan kuu sheego sida aan u abaabulnay dib-u-habaynta dhacdo ka timid Kafka taas oo ka dhalatay maqnaanshaha ku-meel-gaadhka ah ee nidaamka dibadda.

Codsiyada casriga ahi waxay ku shaqeeyaan jawi aad u adag. Macquul ganacsi oo ku duuduuban tikniyoolajiyad casri ah, oo ku dhex socota sawirka Docker oo uu maamulo orchestra sida Kubernetes ama OpenShift, iyo la xidhiidhka codsiyada kale ama xalalka ganacsiga iyada oo loo marayo silsilado jiheeyayaal jireed iyo mid muuqaal ah. Deegaankan oo kale, shay ayaa had iyo jeer jebin kara, markaa dib-u-habaynta dhacdooyinka haddii mid ka mid ah nidaamyada dibadda aan la heli karin waa qayb muhiim ah oo ka mid ah hababka ganacsigayaga.

Siday ahayd Kafka ka hor

Horaantii mashruuca waxaan u isticmaalnay IBM MQ gudbinta fariinta aan la wada socon. Haddii wax qalad ah uu dhacay inta lagu guda jiro hawlgalka adeegga, fariinta la helay waxa lagu meelayn karaa saf- dhintay (DLQ) si loo sii kala saaro gacanta. DLQ waxaa la sameeyay agteeda safka soo socda, fariinta waxaa lagu wareejiyay gudaha IBM MQ.

Haddii khaladku ahaa mid ku meel gaar ah oo aan go'aansan karno (tusaale ahaan, ResourceAccessException ee wicitaanka HTTP ama MongoTimeoutException ee codsiga MongoDb), ka dib xeeladda dib-u-dejinta ayaa dhaqan geli doonta. Iyadoo aan loo eegin macquulnimada laanta arjiga, fariinta asalka ah waxaa loo raray mid ka mid ah safka nidaamka ee dirida dib u dhigista, ama codsi gooni ah oo la sameeyay wakhti hore ka hor si dib loogu diro fariimaha. Tan waxa ku jira nambarka dib-u-dirista ee madaxa farriinta, kaas oo ku xidhan muddada daahitaanka ama dhammaadka istiraatijiyadda heerka codsiga. Haddii aan gaadhnay dhamaadka istaraatiijiyadda laakiin nidaamka dibadda weli lama heli karo, markaa farriinta waxaa la gelin doonaa DLQ si loogu kala saaro gacanta.

Xal u helida

Ka raadinta internetka, waxaad ka heli kartaa kuwan soo socda go'aanka. Marka la soo koobo, waxaa la soo jeediyay in la abuuro mawduuc loogu talagalay dhexda dib u dhac kasta iyo hirgelinta codsiyada Macaamiisha ee dhinaca, kuwaas oo akhrin doona fariimaha leh dib u dhigista loo baahan yahay.

Dib u habaynta dhacdooyinka laga helay Kafka

In kasta oo tirada badan ee dib u eegista wanaagsan, waxay iila muuqataa inaan si buuxda u guulaysan. Ugu horreyntii, sababtoo ah horumariyaha, marka lagu daro fulinta shuruudaha ganacsiga, waa inuu waqti badan ku bixiyaa hirgelinta habka lagu sharraxay.

Intaa waxaa dheer, haddii kantaroolka gelitaanka uu awood u yeesho kooxda Kafka, waa inaad waqti ku bixisaa abuurista mawduucyo iyo bixinta marinka lagama maarmaanka u ah iyaga. Tan waxaa dheer, waxaad u baahan doontaa inaad doorato halbeegga saxda ah ee retention.ms mid kasta oo ka mid ah mawduucyada dib-u-dejinta si farriimaha ay u helaan waqti ay ku cadhoodaan oo aanay uga lumin. Hirgelinta iyo codsiga gelitaanka waa in lagu celiyaa adeeg kasta oo jira ama cusub.

Aynu hadda aragno hababka gu'ga guud ahaan iyo gaar ahaan gu'ga-kafka na siiya dib-u-habaynta fariinta. Spring-kafka waxay leedahay ku-tiirsanaanta ku-meel-gaadhka ah ee dib-u-isku-dayga gu'ga, kaas oo bixiya faa'iidooyin maaraynta BackOffPolicies kala duwan. Kani waa aalad si cadaalad ah u dabacsanaan karta, laakiin cilladdeeda weyni waa kaydinta fariimaha dib loogu diro xusuusta codsiga. Tani waxay ka dhigan tahay in codsiga dib loo bilaabo iyada oo ay ugu wacan tahay cusboonaysiinta ama qaladka hawlgelinta waxay keeni doontaa luminta dhammaan fariimaha dib u habaynta. Maadaama qodobkani uu yahay mid muhiim u ah nidaamkayaga, ma aanan sii fiirsan.

spring-kafka lafteedu waxay bixisaa dhowr dhaqan gelinta ContainerAwareErrorHandler, tusaale ahaan SeekToCurrentErrorHandler, kaas oo aad ku socodsiin karto fariinta hadhow adiga oo aan waxba ka beddelin haddii ay dhacdo qalad. Laga bilaabo nooca guga-kafka 2.3, waxa suurtagal noqotay in la dejiyo BackOffPolicy.

Habkani wuxuu ogolaanayaa fariimaha dib loo habeeyey si ay uga badbaadaan dib u bilaabashada codsiga, laakiin weli ma jiro hab DLQ ah. Waxaan dooranay doorashadan bilawga sanadka 2019, anagoo si niyadsami ah u aaminsan in DLQ aan loo baahnayn (nasiib ayaanu ahayn oo runtii uma baahnin dhawr bilood ka dib markii aan ku shaqaynaynay arjiga nidaamka dib u habaynta). Khaladaadka ku meel gaarka ah ayaa sababay in SeekToCurrentErrorHandler uu shido. Khaladaadka soo haray waxaa lagu daabacay log-ka, taasoo keentay in la dhimo, iyo habaynta ayaa lagu sii waday fariinta xigta.

Go'aanka kama dambaysta ah

Hirgelinta ku salaysan SeekToCurrentErrorHandler ayaa nagu kalliftay inaan horumarinno habkayaga dib-u-diridda fariimaha.

Ugu horreyntii, waxaan rabnay inaan isticmaalno waayo-aragnimada jirta oo aan ballaarinno iyadoo ku xiran nooca macquulka ah ee codsiga. Codsiga macquulka ah ee tooska ah, waxa ay u fiicnaan lahayd in la joojiyo akhrinta fariimaha cusub muddo gaaban oo lagu qeexay istiraatijiyadda dib-u-dejinta. Codsiyada kale, waxaan rabay in aan haysto hal dhibic oo xoojin doonta istiraatijiyadda isku-dayga. Intaa waxaa dheer, hal dhibic waa in ay lahaataa shaqeynta DLQ ee labada waji.

Xeeladda dib-u-isku-dayga lafteeda waa in lagu kaydiyaa arjiga, taas oo mas'uul ka ah soo celinta muddada soo socota marka khalad ku-meel-gaar ah dhaco.

Joojinta Macaamilka ee Codsiga macquulka ah ee toosan

Markaad la shaqaynayso spring-kafka, koodka joojinta Macaamilka wuxuu u ekaan karaa wax sidan oo kale ah:

public void pauseListenerContainer(MessageListenerContainer listenerContainer, 
                                   Instant retryAt) {
        if (nonNull(retryAt) && listenerContainer.isRunning()) {
            listenerContainer.stop();
            taskScheduler.schedule(() -> listenerContainer.start(), retryAt);
            return;
        }
        // to DLQ
    }

Tusaalaha, retryAt waa wakhtiga dib loo bilaabo MessageListenerContainer haddii uu wali socdo. Dib u bilaabashadu waxay ku dhici doontaa dun gaar ah oo laga bilaabay TaskScheduler, hirgelinta kaas oo sidoo kale uu bixiyo gu'ga.

Waxaan ku helnaa dib-u-isku-dayga qiimaha sida soo socota:

  1. Qiimaha miiska dib-u- wacitaanka waa la eegay.
  2. Iyada oo ku saleysan qiimaha counter-counter-ka, inta u dhaxaysa daahitaanka ee istiraatijiyadda dib-u-dejinta waa la raadiyaa. Istaraatiijiyada waxaa lagu caddeeyey arjiga laftiisa; waxaanu dooranay qaabka JSON si aanu u kaydino.
  3. Muddada u dhaxeeysa ee laga helay shaxda JSON waxa ay ka kooban tahay tirada ilbiriqsi ka bacdi ka dib markii habayntu ay u baahan doonto in lagu celiyo. Tiradan sekan waxa lagu daraa wakhtiga hadda la joogo si loo sameeyo qiimaha dib-u-jajabintaAt.
  4. Haddi inta udhaxaysa aan la helin, markaa qiimihii retryAt waa bura oo fariinta waxa loo diri doona DLQ si loo kala saaro gacanta.

Habkan, waxa hadhay oo dhan waa in la kaydiyo tirada soo noqnoqda ee fariin kasta oo hadda la farsameeyo, tusaale ahaan xusuusta codsiga. Ku-haynta tirinta dib-u-isku-dayga ee xusuusta maaha mid muhiim u ah habkan, maadaama codsiga macquulka ah uusan xamili karin habka guud ahaan. Si ka duwan dib-u-isku-dayga guga, dib-u-kicinta arjigu ma keenayso in dhammaan fariimaha lumaan in dib loo habeeyo, laakiin waxay si fudud dib u bilaabi doontaa xeeladda.

Habkani wuxuu caawiyaa in culeyska laga saaro nidaamka dibadda, kaas oo laga yaabo in aan la heli karin sababtoo ah culeys aad u culus. Si kale haddii loo dhigo, marka lagu daro dib-u-habeynta, waxaan gaarnay hirgelinta qaabka jabiyaha wareega.

Xaaladeena, marinka khaladku waa 1 kaliya, iyo si loo yareeyo nidaamka hoos u dhaca sababtoo ah go'itaanka shabakada ku meel gaadhka ah, waxaanu isticmaalnaa istiraatijiyad dib-u-eegis ah oo aad u weyn oo leh waqtiyo daahitaanno yar. Tani waxaa laga yaabaa inaysan ku habooneyn dhammaan codsiyada kooxda, markaa xiriirka ka dhexeeya marinka qaladka iyo qiimaha dhexda waa in lagu doortaa iyadoo lagu saleynayo sifooyinka nidaamka.

Codsi gaar ah oo loogu talagalay socodsiinta fariimaha codsiyada oo leh caqli-gal aan go'aamin lahayn

Waa kan tusaale koodka fariinta u soo diraya arjigan (Retryer), kaas oo dib ugu diri doona mawduuca DESTINATION marka wakhtiga RETRY_AT la gaadho:


public <K, V> void retry(ConsumerRecord<K, V> record, String retryToTopic, 
                         Instant retryAt, String counter, String groupId, Exception e) {
        Headers headers = ofNullable(record.headers()).orElse(new RecordHeaders());
        List<Header> arrayOfHeaders = 
            new ArrayList<>(Arrays.asList(headers.toArray()));
        updateHeader(arrayOfHeaders, GROUP_ID, groupId::getBytes);
        updateHeader(arrayOfHeaders, DESTINATION, retryToTopic::getBytes);
        updateHeader(arrayOfHeaders, ORIGINAL_PARTITION, 
                     () -> Integer.toString(record.partition()).getBytes());
        if (nonNull(retryAt)) {
            updateHeader(arrayOfHeaders, COUNTER, counter::getBytes);
            updateHeader(arrayOfHeaders, SEND_TO, "retry"::getBytes);
            updateHeader(arrayOfHeaders, RETRY_AT, retryAt.toString()::getBytes);
        } else {
            updateHeader(arrayOfHeaders, REASON, 
                         ExceptionUtils.getStackTrace(e)::getBytes);
            updateHeader(arrayOfHeaders, SEND_TO, "backout"::getBytes);
        }
        ProducerRecord<K, V> messageToSend =
            new ProducerRecord<>(retryTopic, null, null, record.key(), record.value(), arrayOfHeaders);
        kafkaTemplate.send(messageToSend);
    }

Tusaalaha wuxuu muujinayaa in macluumaad badan lagu kala qaado madaxyada. Qiimaha RETRY_AT waxaa lagu helaa si la mid ah habka dib-u-isku-dayga ee joogsiga Macaamilka. Waxa u dheer DESTINATION iyo RETRY_AT waanu gudubnay:

  • GROUP_ID, kaas oo aanu ku kooxeyno fariimaha si loo baadho gacanta iyo raadinta la fududeeyay.
  • ORIGINAL_PARTITION in la isku dayo in la sii hayo isla Macaamilka dib u habaynta Halbeeggani waxa uu noqon karaa mid aan waxba ka jirin, taas oo ay dhacdo in qaybta cusub lagu heli doono iyada oo la isticmaalayo record.key() furaha fariinta asalka ah.
  • La cusboonaysiiyay qiimaha COUNTER si loo raaco istiraatijiyadda dib-u-dayga
  • SEND_TO waa mid joogto ah oo tusinaysa in fariinta loo diray dib u habaynta marka la gaadho RETRY_AT ama la dhigo DLQ.
  • SABABTA - sababta fariinta habaynta loo hakiyay.

Retryer waxa uu kaydiyaa fariimaha dib u dirida iyo falanqaynta gacanta ee PostgreSQL. Waqti-xiruhu wuxuu bilaabaa hawl uu ku helo fariimaha RETRY_AT oo dib ugu soo celi ORIGINAL_PARTITION ee mawduuca DESTINATION oo wata diiwaanka furaha ah.furaha().

Marka la diro, fariimaha waa laga tirtiraa PostgreSQL. Farriimaha gacanta ee farriimaha waxay ku dhacdaa UI fudud oo la falgala Retryer iyada oo loo marayo REST API. Sifooyinkeeda ugu muhiimsan waa dib u dirida ama tirtirida fariimaha DLQ, daawashada macluumaadka qaladka iyo raadinta fariimaha, tusaale ahaan magaca qaladka.

Maaddaama kantaroolka gelitaanka uu awood u leeyahay kooxaheenna, waxaa lagama maarmaan ah in si dheeraad ah loo codsado gelitaanka mawduuca uu Dib-u-isku-dayuhu dhegaysanayo, oo loo oggolaado dib-u-isku-dayga inuu wax u qoro mawduuca DESTINATION. Tani waa wax aan fiicneyn, laakiin, si ka duwan habka mawduuca u dhexeeya, waxaan haysanaa DLQ iyo UI dhamaystiran si loo maareeyo.

Waxaa jira kiisas marka mawduuc soo socda ay akhriyaan kooxo badan oo kala duwan oo macaamiisha ah, kuwaas oo codsiyadoodu ay hirgeliyaan caqliyo kala duwan. Dib u habaynta fariinta iyada oo loo marayo Retryer mid ka mid ah codsiyadan waxay ku dambayn doontaa kan kale nuqul ka mid ah. Si aan taas uga hortagno, waxaan abuurnaa mowduuc gaar ah oo dib-u-habayn loogu sameeyo. Mawduucyada soo galaya iyo dib u tijaabinta waxaa akhrin kara isla Macaamilka iyada oo aan wax xannibin ah lahayn.

Dib u habaynta dhacdooyinka laga helay Kafka

Sida caadiga ah habkani ma bixiyo shaqeynta wareegga wareegga, si kastaba ha ahaatee waxaa lagu dari karaa codsiga iyadoo la isticmaalayo guga-daruur-netflix ama cusub guga Cloud circuit breaker, ku duubida meelaha adeegyada dibadda loogu yeero qoraalo ku habboon. Intaa waxaa dheer, waxay noqoneysaa suurtagal in la doorto istiraatiijiyad madax weyn qaabka, kaas oo sidoo kale faa'iido yeelan kara. Tusaale ahaan, guga-cloud-netflix tani waxay noqon kartaa barkad dun ah ama semaphore.

gunaanad

Natiijo ahaan, waxaan haysanaa codsi gooni ah oo noo ogolaanaya inaan ku celino habka fariinta haddii nidaam ka baxsan si ku meel gaar ah aan loo heli karin.

Mid ka mid ah faa'iidooyinka ugu muhiimsan ee arjiga ayaa ah in loo isticmaali karo nidaamyada dibadda ee ku shaqeeya isla kooxda Kafka, iyada oo aan wax isbeddel ah laga helin dhinacooda! Codsiga noocan oo kale ah wuxuu u baahan doonaa oo kaliya inuu galo mawduuca dib-u-isku-dayga, buuxi dhowr madax-madaxeedka Kafka oo farriin u diro Dib-u-isku-dayga. Looma baahna in kor loo qaado kaabayaasha dheeraadka ah. Iyo si loo yareeyo tirada fariimaha laga soo wareejiyay codsiga oo loo gudbiyay Retryer iyo gadaal, waxaanu aqoonsanay codsiyada leh caqli-gal toosan oo dib-u-habayn lagu sameeyay iyada oo loo marayo joogsiga macaamiisha.

Source: www.habr.com

Add a comment