Tachartasan ath-ghiollachd a fhuaireadh bho Kafka

Tachartasan ath-ghiollachd a fhuaireadh bho Kafka

Hi Habr.

O chionn ghoirid bha mi roinn an t-eòlas aige mu na crìochan a bhios sinn mar sgioba mar as trice a’ cleachdadh airson Riochdaire agus Neach-cleachdaidh Kafka gus faighinn nas fhaisge air lìbhrigeadh cinnteach. San artaigil seo tha mi airson innse dhut mar a chuir sinn air dòigh ath-ghiollachd tachartas a fhuaireadh bho Kafka mar thoradh air nach robh an siostam taobh a-muigh ri fhaighinn gu sealach.

Bidh tagraidhean ùr-nodha ag obair ann an àrainneachd gu math toinnte. Loidsig gnìomhachais air a phasgadh ann an stac teicneòlas an latha an-diugh, a ’ruith ann an ìomhaigh Docker air a riaghladh le orcastra mar Kubernetes no OpenShift, agus a’ conaltradh le tagraidhean eile no fuasglaidhean iomairt tro shreath de routers fiosaigeach is brìgheil. Ann an àrainneachd mar sin, faodaidh rudeigin an-còmhnaidh briseadh, agus mar sin tha ath-ghiollachdadh thachartasan mura h-eil aon de na siostaman taobh a-muigh ri fhaighinn na phàirt chudromach de ar pròiseasan gnìomhachais.

Ciamar a bha e mus Kafka

Na bu thràithe sa phròiseact chleachd sinn IBM MQ airson lìbhrigeadh teachdaireachd asyncronach. Ma thachair mearachd sam bith ri linn obrachadh na seirbheis, dh’ fhaodadh an teachdaireachd a fhuaireadh a bhith air a chuir ann an ciudha marbh-litir (DLQ) airson tuilleadh parsadh làimhe. Chaidh an DLQ a chruthachadh ri taobh a’ chiudha a bha a’ tighinn a-steach, chaidh an teachdaireachd a ghluasad taobh a-staigh IBM MQ.

Nam biodh a’ mhearachd sealach agus gum b’ urrainn dhuinn a dhearbhadh (mar eisimpleir, ResourceAccessException air gairm HTTP no MongoTimeoutException air iarrtas MongoDb), thigeadh an ro-innleachd ath-fheuchainn gu buil. A dh’ aindeoin loidsig branrach an tagraidh, chaidh an teachdaireachd tùsail a ghluasad an dàrna cuid gu ciudha an t-siostaim airson dàil a chuir air falbh, no gu tagradh air leth a chaidh a dhèanamh o chionn fhada gus teachdaireachdan a chuir air ais. Tha seo a’ toirt a-steach àireamh ath-chuir ann am bann-cinn na teachdaireachd, a tha ceangailte ris an ùine dàil no deireadh ro-innleachd ìre an tagraidh. Ma tha sinn air deireadh na ro-innleachd a ruighinn ach nach eil an siostam taobh a-muigh fhathast ri fhaighinn, thèid an teachdaireachd a chuir san DLQ airson parsadh làimhe.

Lorg fuasgladh

A 'lorg air an eadar-lìon, gheibh thu na leanas решение. Ann an ùine ghoirid, thathar a 'moladh cuspair a chruthachadh airson gach ùine dàil agus cuir an gnìomh tagraidhean luchd-cleachdaidh air an taobh, a leughas teachdaireachdan leis an dàil a tha a dhìth.

Tachartasan ath-ghiollachd a fhuaireadh bho Kafka

A dh 'aindeoin an àireamh mhòr de lèirmheasan adhartach, tha e coltach riumsa nach eil e gu tur soirbheachail. An toiseach, oir feumaidh an leasaiche, a bharrachd air a bhith a 'buileachadh riatanasan gnìomhachais, tòrr ùine a chaitheamh a' cur an gnìomh an uidheamachd a chaidh a mhìneachadh.

A bharrachd air an sin, ma tha smachd ruigsinneachd air a chomasachadh air cruinneachadh Kafka, feumaidh tu beagan ùine a chaitheamh a ’cruthachadh chuspairean agus a’ toirt seachad an ruigsinneachd riatanach dhaibh. A bharrachd air an seo, feumaidh tu am paramadair glèidhidh.ms ceart a thaghadh airson gach cuspair ath-fheuchainn gus am bi ùine aig teachdaireachdan a bhith air an cur an grèim agus nach tèid iad à bith bhuaithe. Feumaidh buileachadh agus iarrtas ruigsinneachd a bhith air ath-aithris airson gach seirbheis a tha ann no seirbheis ùr.

Chì sinn a-nis dè na h-innealan a tha an t-earrach san fharsaingeachd agus spring-kafka gu sònraichte a’ toirt dhuinn airson ath-ghiollachd theachdaireachdan. Tha eisimeileachd thar-ghluasadach aig Spring-kafka air ath-thilleadh earraich, a bheir seachad tarraingean airson a bhith a’ riaghladh diofar Phoileasaidhean BackOff. Is e inneal gu math sùbailte a tha seo, ach is e an tarraing mhòr a th’ ann teachdaireachdan a stòradh airson an toirt air ais ann an cuimhne tagraidh. Tha seo a’ ciallachadh gun caillear a h-uile teachdaireachd a’ feitheamh ath-ghiollachd nuair a thèid an tagradh ath-thòiseachadh mar thoradh air ùrachadh no mearachd obrachaidh. Leis gu bheil a’ phuing seo deatamach don t-siostam againn, cha do bheachdaich sinn air tuilleadh.

Tha spring-kafka fhèin a’ toirt seachad grunn bhuileachadh de ContainerAwareErrorHandler, mar eisimpleir Làimhseachadh mearachd SeekToCurrent, leis an urrainn dhut an teachdaireachd a phròiseasadh nas fhaide air adhart gun a bhith a’ gluasad dheth gun fhios nach bi mearachd ann. A’ tòiseachadh le dreach de spring-kafka 2.3, bha e comasach BackOffPolicy a shuidheachadh.

Tha an dòigh-obrach seo a’ leigeil le teachdaireachdan ath-ghiollachdaichte a bhith beò ann an ath-thòiseachadh tagraidh, ach chan eil uidheamachd DLQ ann fhathast. Thagh sinn an roghainn seo aig toiseach 2019, le dòchas dòchasach nach biodh feum air DLQ (bha sinn fortanach agus gu dearbh cha robh feum againn air às deidh grunn mhìosan de bhith ag obrachadh an tagraidh le siostam ath-ghiollachd mar sin). Dh'adhbhraich mearachdan sealach SeekToCurrentErrorHandler na theine. Chaidh na mearachdan a bha air fhàgail a chlò-bhualadh sa loga, agus mar thoradh air sin chaidh a chothromachadh, agus lean an giullachd leis an ath theachdaireachd.

Co-dhùnadh deireannach

Bhrosnaich am buileachadh stèidhichte air SeekToCurrentErrorHandler sinn gus an uidheamachd againn fhèin a leasachadh airson teachdaireachdan a chuir air ais.

An toiseach, bha sinn airson an t-eòlas a th’ ann a chleachdadh agus a leudachadh a rèir loidsig an tagraidh. Airson tagradh loidsig sreathach, bhiodh e na b’ fheàrr stad a chuir air teachdaireachdan ùra a leughadh airson ùine ghoirid a tha air a shònrachadh leis an ro-innleachd retry. Airson tagraidhean eile, bha mi airson aon phuing a bhith agam a chuireadh an gnìomh an ro-innleachd ath-thagradh. A bharrachd air an sin, feumaidh comas DLQ a bhith aig a’ phuing shingilte seo airson an dà dhòigh-obrach.

Feumaidh an ro-innleachd retry fhèin a bhith air a stòradh san tagradh, air a bheil uallach airson an ath eadar-ama fhaighinn air ais nuair a thachras mearachd sealach.

A 'stad an neach-cleachdaidh airson tagradh loidsig sreathach

Nuair a bhios tu ag obair le spring-kafka, is dòcha gum bi an còd gus stad a chuir air an neach-cleachdaidh a’ coimhead rudeigin mar seo:

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

San eisimpleir, is e retryAt an t-àm airson an MessageListenerContainer ath-thòiseachadh ma tha e fhathast a’ ruith. Bidh an ath-chur air bhog a’ tachairt ann an snàithlean air leth a chaidh a chuir air bhog ann an TaskScheduler, agus tha am buileachadh cuideachd air a thoirt seachad ron earrach.

Lorgaidh sinn an luach retryAt san dòigh a leanas:

  1. Thathas a’ coimhead suas luach a’ chunntair ath-ghairm.
  2. Stèidhichte air a’ chunntair, thathas a’ sgrùdadh an ùine dàil a th’ ann an-dràsta san ro-innleachd ath-thilleadh. Tha an ro-innleachd air ainmeachadh san tagradh fhèin; thagh sinn an cruth JSON airson a stòradh.
  3. Anns an eadar-ama a lorgar ann an sreath JSON tha an àireamh de dhiogan agus feumar ath-aithris às deidh a’ ghiollachd. Tha an àireamh seo de dhiogan air a chur ris an ùine làithreach gus an luach airson retryAt a chruthachadh.
  4. Mura lorgar an eadar-ama, tha luach retryAt null agus thèid an teachdaireachd a chuir gu DLQ airson parsadh làimhe.

Leis an dòigh-obrach seo, chan eil air fhàgail ach an àireamh de ghlaodhan a-rithist a shàbhaladh airson gach teachdaireachd a thathas a’ giullachd an-dràsta, mar eisimpleir ann an cuimhne an tagraidh. Chan eil e riatanach don dòigh-obrach seo a bhith a’ cumail a’ chunntais ath-fheuchainn mar chuimhneachan, leis nach urrainn do thagradh loidsig sreathach a’ ghiollachd gu h-iomlan a làimhseachadh. Eu-coltach ri spring-retry, cha bhith ath-thòiseachadh an tagraidh ag adhbhrachadh gun tèid a h-uile teachdaireachd a chall ath-phròiseasadh, ach dìreach ath-thòiseachadh an ro-innleachd.

Tha an dòigh-obrach seo a’ cuideachadh le bhith a’ toirt an luchd far an t-siostam a-muigh, rud a dh’ fhaodadh a bhith neo-riatanach air sgàth luchdan trom. Ann am faclan eile, a bharrachd air ath-ghiollachd, choilean sinn buileachadh a’ phàtrain brisidh cuairt.

Anns a’ chùis againn, chan eil an stairsneach mearachd ach 1, agus gus an ùine downt san t-siostam a lughdachadh mar thoradh air briseadh lìonra sealach, bidh sinn a’ cleachdadh ro-innleachd ath-dhèanamh granular le amannan latency beaga. Is dòcha nach bi seo freagarrach airson a h-uile tagradh buidhne, agus mar sin feumar an dàimh eadar stairsneach na mearachd agus an luach eadar-ama a thaghadh a rèir feartan an t-siostaim.

Iarrtas air leth airson teachdaireachdan a ghiullachd bho thagraidhean le loidsig neo-chinnteach

Seo eisimpleir de chòd a chuireas teachdaireachd gu aplacaid mar seo (Retryer), a chuireas a-rithist chun chuspair DESTINATION nuair a ruigeas an ùine RETRY_AT:


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);
    }

Tha an eisimpleir a’ sealltainn gu bheil tòrr fiosrachaidh ga sgaoileadh ann an cinn-cinn. Lorgar luach RETRY_AT san aon dòigh ’s a tha e airson an uidheamachd ath-fheuchainn tro stad an neach-cleachdaidh. A bharrachd air DESTINATION agus RETRY_AT thèid sinn seachad air:

  • GROUP_ID, leis am bi sinn a' cur teachdaireachdan còmhla airson mion-sgrùdadh làimhe agus rannsachadh nas sìmplidhe.
  • ORIGINAL_PARTITION gus feuchainn ris an aon chleachdaiche a chumail airson ath-ghiollachd. Faodaidh am paramadair seo a bhith null, agus sa chùis sin gheibhear an sgaradh ùr le bhith a’ cleachdadh iuchair record.key() den teachdaireachd thùsail.
  • Luach COUNTER ùrachadh gus an ro-innleachd ath-fheuchainn a leantainn.
  • Tha SEND_TO seasmhach a' sònrachadh an tèid am brath a chur airson ath-ghiollachdachadh nuair a ruigeas tu RETRY_AT neo a thèid a chur ann an DLQ.
  • CÙIS - an adhbhar gun deach stad a chuir air giollachd teachdaireachd.

Bidh Retryer a’ stòradh teachdaireachdan airson ath-chur agus parsadh làimhe ann am PostgreSQL. Tòisichidh timer gnìomh a lorgas teachdaireachdan le RETRY_AT agus a chuireas air ais iad chun a’ phàirt ORIGINAL_PARTITION den chuspair DESTINATION leis an iuchair record.key().

Nuair a thèid an cur, thèid teachdaireachdan a sguabadh às PostgreSQL. Bidh parsadh làimhe de theachdaireachdan a’ tachairt ann an UI sìmplidh a bhios ag eadar-obrachadh le Retryer tro REST API. Is e na prìomh fheartan aige teachdaireachdan a chuir air ais no a dhubhadh às bho DLQ, coimhead air fiosrachadh mearachd agus lorg teachdaireachdan, mar eisimpleir le ainm mearachd.

Leis gu bheil smachd ruigsinneachd air a chomasachadh air na cruinneachaidhean againn, feumar cuideachd ruigsinneachd iarraidh air a’ chuspair air a bheil Retryer ag èisteachd, agus leigeil le Retryer sgrìobhadh chun chuspair DESTINATION. Tha seo mì-ghoireasach, ach, eu-coltach ris an dòigh-obrach cuspair eadar-ama, tha DLQ agus UI làn-chuimseach againn airson a riaghladh.

Tha cùisean ann nuair a thèid cuspair a tha a’ tighinn a-steach a leughadh le grunn bhuidhnean luchd-cleachdaidh eadar-dhealaichte, aig a bheil tagraidhean a’ cur an gnìomh diofar loidsig. Mar thoradh air ath-ghiollachd teachdaireachd tro Retryer airson aon de na tagraidhean sin bidh dùblachadh air an taobh eile. Gus dìon an aghaidh seo, bidh sinn a 'cruthachadh cuspair fa leth airson ath-ghiollachdadh. Faodaidh an aon neach-cleachdaidh na cuspairean a tha a’ tighinn a-steach agus a-rithist a leughadh gun bhacadh sam bith.

Tachartasan ath-ghiollachd a fhuaireadh bho Kafka

Gu gnàthach chan eil an dòigh-obrach seo a’ toirt seachad comas brisidh cuairteachaidh, ach faodar a chuir ris an tagradh a’ cleachdadh earrach-sgòth-netflix no ùr inneal-brisidh sgòthan earraich, a’ cuairteachadh nan àiteachan far a bheilear a’ gairm seirbheisean bhon taobh a-muigh gu tarraingean iomchaidh. A bharrachd air an sin, bidh e comasach ro-innleachd a thaghadh airson mòr-cheann pàtran, a dh'fhaodas a bhith feumail cuideachd. Mar eisimpleir, as t-earrach-cloud-netflix dh'fhaodadh seo a bhith na amar snàthainn no semaphore.

co-dhùnadh

Mar thoradh air an sin, tha tagradh air leth againn a leigeas leinn giullachd teachdaireachd a-rithist mura h-eil siostam taobh a-muigh sam bith ri fhaighinn rè ùine.

Is e aon de phrìomh bhuannachdan an tagraidh gum faod e a bhith air a chleachdadh le siostaman bhon taobh a-muigh a tha a’ ruith air an aon bhuidheann Kafka, gun atharrachaidhean mòra air an taobh aca! Cha bhith feum aig tagradh mar seo ach faighinn chun chuspair retry, lìon a-steach beagan chinn Kafka agus cuir teachdaireachd chun Retryer. Chan eil feum air bun-structar a bharrachd a thogail. Agus gus an àireamh de theachdaireachdan a chaidh a ghluasad bhon tagradh gu Retryer agus air ais a lughdachadh, chomharraich sinn tagraidhean le loidsig sreathach agus rinn sinn ath-ghiollachd orra tro stad an neach-cleachdaidh.

Source: www.habr.com

Cuir beachd ann