
Hey Habr.
Le déanaí mé faoi na paraiméadair a úsáideann muid mar fhoireann is minice do Tháirgeoir agus Tomhaltóir Kafka chun teacht níos gaire do sheachadadh ráthaithe. San Airteagal seo ba mhaith liom a insint duit conas a d'eagraíomar athphróiseáil imeacht a fuarthas ó Kafka mar thoradh ar neamh-infhaighteacht shealadach an chórais sheachtraigh.
Feidhmíonn feidhmchláir nua-aimseartha i dtimpeallacht an-chasta. Loighic gnó fillte i stack teicneolaíochta nua-aimseartha, ag rith in íomhá Docker arna bhainistiú ag ceolfhoirneoir cosúil le Kubernetes nó OpenShift, agus cumarsáid a dhéanamh le hiarratais eile nó le réitigh fiontair trí shlabhra ródairí fisiceacha agus fíorúla. I dtimpeallacht den sórt sin, is féidir le rud éigin briseadh i gcónaí, agus mar sin is cuid thábhachtach dár bpróisis ghnó é imeachtaí a athphróiseáil mura bhfuil ceann de na córais sheachtracha ar fáil.
Conas a bhí sé roimh Kafka
Níos luaithe sa tionscadal d'úsáideamar IBM MQ le haghaidh seachadadh teachtaireachta asincrónach. Má tharla earráid ar bith le linn oibriú na seirbhíse, d’fhéadfaí an teachtaireacht a fuarthas a chur i scuaine marbh-litir (DLQ) le haghaidh parsáil láimhe breise. Cruthaíodh an DLQ in aice leis an scuaine ag teacht isteach, aistríodh an teachtaireacht taobh istigh de IBM MQ.
Más rud é go raibh an earráid sealadach agus go bhféadfaimis é a chinneadh (mar shampla, ResourceAccessException ar ghlao HTTP nó MongoTimeoutException ar iarratas MongoDb), bheadh feidhm ag an straitéis atriail. Beag beann ar loighic branchánach an fheidhmchláir, aistríodh an bhunteachtaireacht chuig scuaine an chórais chun moill a chur ar sheoladh, nó chuig iarratas ar leith a rinneadh i bhfad ó shin chun teachtaireachtaí a athsheoladh. Áirítear leis seo uimhir athsheolta i gceanntásc na teachtaireachta, atá ceangailte leis an eatramh moille nó deireadh na straitéise ar leibhéal an fheidhmchláir. Má tá deireadh na straitéise sroichte againn ach nach bhfuil an córas seachtrach ar fáil fós, cuirfear an teachtaireacht sa DLQ le haghaidh parsáil láimhe.
Cuardach réitigh
, is féidir leat teacht ar an méid seo a leanas . I mbeagán focal, tá sé beartaithe ábhar a chruthú do gach eatramh moille agus feidhmchláir Tomhaltóirí a chur i bhfeidhm ar an taobh, a léifidh teachtaireachtaí leis an moill is gá.

In ainneoin líon mór na n-athbhreithnithe dearfacha, feictear dom nár éirigh go hiomlán leo. Ar an gcéad dul síos, toisc go gcaithfidh an forbróir, chomh maith le ceanglais ghnó a chur i bhfeidhm, go leor ama a chaitheamh ag cur an mheicníocht a thuairiscítear i bhfeidhm.
Ina theannta sin, má tá rialú rochtana cumasaithe ar bhraisle Kafka, beidh ort roinnt ama a chaitheamh ag cruthú topaicí agus ag soláthar an rochtain riachtanach dóibh. Ina theannta sin, beidh ort an paraiméadar coinneála ceart a roghnú do gach ceann de na topaicí atriail ionas go mbeidh am ag teachtaireachtaí a bheith athsheolta agus nach n-imíonn siad uaidh. Ní mór cur chun feidhme agus iarratas rochtana a dhéanamh arís i gcás gach seirbhíse atá ann cheana nó gach seirbhís nua.
Feicfimid anois cad iad na meicníochtaí a sholáthraíonn earrach go ginearálta agus spring-kafka go háirithe dúinn le haghaidh athphróiseáil teachtaireachtaí. Tá Spring-kafka ag brath go haistrithe ar athtriail earraigh, a sholáthraíonn astarraingtí chun Polasaithe BackOff éagsúla a bhainistiú. Is uirlis measartha solúbtha í seo, ach is é an míbhuntáiste suntasach atá aige ná teachtaireachtaí a stóráil le cur i gcuimhne feidhmchláir. Ciallaíonn sé seo go gcaillfear gach teachtaireacht ar feitheamh athphróiseála má atosaítear an feidhmchlár de bharr nuashonraithe nó earráid oibriúcháin. Ós rud é go bhfuil an pointe seo ríthábhachtach dár gcóras, níor bhreithnigh muid é a thuilleadh.
Soláthraíonn spring-kafka féin roinnt feidhmiúcháin de ContainerAwareErrorHandler, mar shampla , leis ar féidir leat an teachtaireacht a phróiseáil níos déanaí gan fritháireamh a aistriú i gcás earráide. Ag tosú le leagan spring-kafka 2.3, bhíothas in ann BackOffPolicy a shocrú.
Ligeann an cur chuige seo do theachtaireachtaí athphróiseáilte teacht slán ó atosú feidhmchlár, ach níl aon mheicníocht DLQ ann fós. Roghnaigh muid an rogha seo ag tús 2019, ag creidiúint go dóchasach nach mbeadh gá le DLQ (bhí an t-ádh linn agus ní raibh sé de dhíth orainn i ndáiríre tar éis roinnt míonna tar éis an feidhmchlár a oibriú le córas athphróiseála den sórt sin). Earráidí sealadacha ba chúis le SeekToCurrentErrorHandler a thine. Cuireadh na hearráidí a bhí fágtha i gcló sa loga, rud a d'eascair fritháireamh, agus leanadh den phróiseáil leis an gcéad teachtaireacht eile.
Cinneadh deiridh
Spreag an cur i bhfeidhm bunaithe ar SeekToCurrentErrorHandler sinn chun ár meicníocht féin a fhorbairt chun teachtaireachtaí a athsheoladh.
Ar an gcéad dul síos, bhíomar ag iarraidh an taithí atá ann cheana féin a úsáid agus é a leathnú ag brath ar loighic an iarratais. I gcás feidhmchlár líneach loighce, b’fhearr stop a chur le teachtaireachtaí nua a léamh ar feadh tréimhse ghearr ama a shonraítear sa straitéis athiarrachta. I gcás feidhmeanna eile, theastaigh uaim pointe amháin a bheith ann a chuirfeadh an straitéis athiarracht i bhfeidhm. Ina theannta sin, ní mór feidhmiúlacht DLQ a bheith ag an bpointe aonair seo don dá chur chuige.
Ní mór an straitéis atriail féin a stóráil san fheidhmchlár, atá freagrach as an chéad eatramh eile a aisghabháil nuair a tharlaíonn earráid shealadach.
An Tomhaltóir a Stopadh le haghaidh Feidhmchlár Loighic Líneach
Agus tú ag obair le spring-kafka, d’fhéadfadh go mbeadh cuma rud éigin mar seo ar an gcód chun an Tomhaltóir a stopadh:
public void pauseListenerContainer(MessageListenerContainer listenerContainer,
Instant retryAt) {
if (nonNull(retryAt) && listenerContainer.isRunning()) {
listenerContainer.stop();
taskScheduler.schedule(() -> listenerContainer.start(), retryAt);
return;
}
// to DLQ
}Sa sampla, is é retryAt an t-am chun an MessageListenerContainer a atosú má tá sé fós ag rith. Tarlóidh an t-athsheoladh i snáithe ar leith a sheolfar in TaskScheduler, a soláthraítear a chur chun feidhme faoin earrach freisin.
Faighimid an luach retryAt ar an mbealach seo a leanas:
- Breathnaítear suas ar luach an chuntar athghlao.
- Bunaithe ar an gcuntar luach, déantar an t-eatramh moille reatha sa straitéis atriail a chuardach. Dearbhaítear an straitéis san iarratas féin; roghnaigh muid an fhormáid JSON chun é a stóráil.
- Tá líon na soicind san eatramh a aimsítear san eagar JSON agus beidh gá le próiseáil a dhéanamh arís ina dhiaidh sin. Cuirtear an líon soicind seo leis an am reatha chun luach retryAt a fhoirmiú.
- Mura bhfaightear an t-eatramh, is é an luach retryAt ar neamhní agus seolfar an teachtaireacht chuig DLQ le haghaidh parsáil láimhe.
Leis an gcur chuige seo, níl fágtha ach líon na nglaonna arís agus arís eile a shábháil ar gach teachtaireacht atá á próiseáil faoi láthair, mar shampla i gcuimhne feidhmchláir. Níl sé ríthábhachtach an t-áiritheoir athiarrachta a choinneáil i gcuimhne don chur chuige seo, toisc nach féidir le feidhmchlár líneach loighce an phróiseáil ina hiomláine a láimhseáil. Murab ionann agus spring-retry, ní bheidh atosú ar an bhfeidhmchlár ina chúis le gach teachtaireacht a cailleadh a athphróiseáil, ach beidh sé a atosú ar an straitéis.
Cuidíonn an cur chuige seo leis an ualach a bhaint den chóras seachtrach, rud a d’fhéadfadh a bheith gan a bheith ar fáil mar gheall ar ualach an-trom. I bhfocail eile, chomh maith le hathphróiseáil, bhaineamar amach cur i bhfeidhm an phhatrún .
Is é ár gcás, níl an tairseach earráide ach 1, agus chun aga neamhfhónaimh an chórais a íoslaghdú mar gheall ar bhristeacha líonra sealadacha, bainimid úsáid as straitéis atriallta an-ghráiníneach le tréimhsí fola beaga. D'fhéadfadh sé nach mbeadh sé seo oiriúnach do gach feidhmchlár grúpa, mar sin ní mór an gaol idir an tairseach earráide agus an luach eatramh a roghnú bunaithe ar shaintréithe an chórais.
Feidhmchlár ar leith chun teachtaireachtaí a phróiseáil ó fheidhmchláir a bhfuil loighic neamhchinntitheach acu
Seo sampla de chód a sheolann teachtaireacht chuig a leithéid d’fheidhmchlár (Retryer), a athsheolfaidh chuig an topaic DESTINATION nuair a bheidh an t-am RETRY_AT sroichte:
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);
}Léiríonn an sampla go dtarchuirtear go leor faisnéise i gceanntásca. Faightear luach RETRY_AT ar an mbealach céanna agus a fhaightear don mheicníocht atriail tríd an stad Tomhaltóra. Chomh maith le DESTINATION agus RETRY_AT pasaimid:
- GROUP_ID, trína ndéanaimid teachtaireachtaí a ghrúpáil le haghaidh anailíse láimhe agus cuardach simplithe.
- ORIGINAL_PARTITION chun iarracht a dhéanamh an Tomhaltóir céanna a choinneáil le haghaidh athphróiseála. Is féidir an paraiméadar seo a bheith ar neamhní, agus sa chás sin gheobhaidh tú an deighilt nua trí úsáid a bhaint as eochair record.key() den bhunteachtaireacht.
- Luach COUNTER nuashonraithe chun an straitéis atriail a leanúint.
- Is tairiseach é SEND_TO a chuireann in iúl cé acu an seoltar an teachtaireacht le haghaidh athphróiseála nuair a shroicheann sé RETRY_AT nó má chuirtear in DLQ í.
- CÚIS - an chúis ar cuireadh isteach ar phróiseáil teachtaireachta.
Stórálann Retryer teachtaireachtaí le haghaidh athsheolta agus parsála láimhe in PostgreSQL. Tosaíonn an t-amadóir tasc a aimsíonn teachtaireachtaí le RETRY_AT agus a sheolann ar ais chuig an deighilt ORIGINAL_PARTITION den topaic DESTINATION leis an taifead eochrach. eochair().
Nuair a sheoltar iad, scriostar teachtaireachtaí ó PostgreSQL. Déantar teachtaireachtaí a pharsáil de láimh in Chomhéadain Chomhéadain shimplí a idirghníomhaíonn le Retryer trí REST API. Is iad na príomhghnéithe atá aige ná teachtaireachtaí a athsheoladh nó a scriosadh ó DLQ, féachaint ar fhaisnéis earráide agus cuardach a dhéanamh ar theachtaireachtaí, mar shampla de réir ainm earráide.
Ós rud é go bhfuil rialú rochtana cumasaithe ar ár mbraislí, is gá freisin rochtain a iarraidh ar an ábhar a bhfuil Retryer ag éisteacht leis, agus ligean do Retryer scríobh chuig an topaic DESTINATION. Tá sé seo deacair, ach, murab ionann agus an cur chuige maidir le topaicí eatramh, tá DLQ agus UI iomlán againn chun é a bhainistiú.
Tá cásanna ann nuair a léann go leor grúpaí tomhaltóirí éagsúla topaic ag teacht isteach, a gcuireann a bhfeidhmchláir loighic dhifriúil i bhfeidhm. Má dhéantar teachtaireacht a athphróiseáil trí Retryer do cheann de na feidhmchláir seo, beidh dúblach ar an taobh eile. Chun cosaint a thabhairt dó seo, cruthaímid ábhar ar leith le haghaidh athphróiseála. Is féidir leis an Tomhaltóir céanna na topaicí isteach agus atriail a léamh gan aon srianta.

De réir réamhshocraithe ní sholáthraíonn an cur chuige seo feidhmiúlacht scoradáin chiorcaid, ach is féidir é a chur leis an bhfeidhmchlár ag baint úsáide as nó nua , na háiteanna ina dtugtar seirbhísí seachtracha a chuimsiú i astarraingtí cuí. Ina theannta sin, bíonn sé indéanta straitéis a roghnú le haghaidh patrún, is féidir a bheith úsáideach freisin. Mar shampla, san earrach-scamall-netflix d'fhéadfadh sé seo a bheith ina linn snáithe nó ina shemaphore.
Aschur
Mar thoradh air sin, tá feidhmchlár ar leith againn a ligeann dúinn próiseáil teachtaireachtaí a dhéanamh arís mura bhfuil aon chóras seachtrach ar fáil go sealadach.
Ceann de phríomhbhuntáistí an iarratais ná gur féidir le córais sheachtracha a ritheann ar an gcnuasach Kafka céanna é a úsáid, gan modhnuithe suntasacha ar a thaobh! Ní bheidh ar iarratas den sórt sin ach rochtain a fháil ar an topaic atriail, líon isteach cúpla ceanntásc Kafka agus seol teachtaireacht chuig an Retryer. Ní gá aon bhonneagar breise a ardú. Agus d'fhonn líon na dteachtaireachtaí a aistrítear ón bhfeidhmchlár go Retryer agus ar ais a laghdú, d'aithníomar feidhmchláir le loighic líneach agus rinneamar iad a athphróiseáil tríd an stad Tomhaltóirí.
Foinse: will.com
