{"id":30778,"date":"2019-10-31T21:37:23","date_gmt":"2019-10-31T18:37:23","guid":{"rendered":"https:\/\/prohoster.info\/blog\/opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka\/"},"modified":"2019-10-31T21:37:23","modified_gmt":"2019-10-31T18:37:23","slug":"opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka","title":{"rendered":"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Mi k\u00e9sztethet egy akkora c\u00e9get, mint a Lamoda, amelynek j\u00f3l bev\u00e1lt folyamatai \u00e9s tucatnyi k\u00f6lcs\u00f6n\u00f6sen \u00f6sszef\u00fcgg\u0151 szolg\u00e1ltat\u00e1sa van, hogy drasztikus m\u00f3don megv\u00e1ltoztassa a megk\u00f6zel\u00edt\u00e9s\u00e9t? A motiv\u00e1ci\u00f3 teljesen elt\u00e9r\u0151 lehet: a jogi el\u0151\u00edr\u00e1sokt\u00f3l kezdve a programoz\u00f3kra jellemz\u0151 k\u00eds\u00e9rletez\u00e9si v\u00e1gyig.<\/p>\n<p>De ez egy\u00e1ltal\u00e1n nem jelenti azt, hogy ne sz\u00e1m\u00edthatn\u00e1nk tov\u00e1bbi el\u0151ny\u00f6kre. Konkr\u00e9tan miben lehet nyerni, ha bevezetj\u00fck az esem\u00e9nyalap\u00fa API-t Kafka seg\u00edts\u00e9g\u00e9vel, arr\u00f3l Szergiej Zaika besz\u00e9l majd (<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/fewald\/\" class=\"user_link\">fewald<\/a><\/noindex>). K\u00f6telez\u0151ek lesznek a tapasztalataink \u00e9s a \u00e9rdekes felfedez\u00e9sek is \u2013 nem lehet k\u00eds\u00e9rlet n\u00e9lk\u00fcl\u00fck.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/7ab959ab45ec5c6565b35b18b361c0ea.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<em>Megjegyz\u00e9s: Ez a cikk a Szergiej \u00e1ltal 2018 november\u00e9ben a HighLoad++ sor\u00e1n tartott meetup anyagain alapul. A Lamoda Kafka-val kapcsolatos tapasztalata \u00e9l\u00e9nken vonzotta a hallgat\u00f3s\u00e1got, hiszen a t\u00f6bbi el\u0151ad\u00e1s is nagy \u00e9rdekl\u0151d\u00e9st keltett. \u00dagy v\u00e9lj\u00fck, ez egy nagyszer\u0171 p\u00e9lda arra, hogy mindig lehet \u00e9s kell is keresni az egyet\u00e9rt\u0151 feleket, \u00e9s a HighLoad++ szervez\u0151i a j\u00f6v\u0151ben is igyekezni fognak olyan l\u00e9gk\u00f6rt teremteni, amely ezt el\u0151seg\u00edti.<\/em><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>A folyamatr\u00f3l<\/h2>\n<p>\nA Lamoda egy nagy e-kereskedelmi platform, amely rendelkezik saj\u00e1t \u00fcgyf\u00e9lszolg\u00e1lat\u00e1val, sz\u00e1ll\u00edt\u00f3 szolg\u00e1ltat\u00e1ssal (\u00e9s sz\u00e1mos partnerrel), fot\u00f3st\u00fadi\u00f3val, hatalmas rakt\u00e1rral, \u00e9s mindez a saj\u00e1t szoftver\u00e9n m\u0171k\u00f6dik. Sz\u00e1mtalan fizet\u00e9si m\u00f3d \u00e9s b2b-partner van, akik haszn\u00e1lhatj\u00e1k ezeket a szolg\u00e1ltat\u00e1sokat, \u00e9s szeretn\u00e9k tudni a legfrissebb inform\u00e1ci\u00f3kat term\u00e9keikr\u0151l. R\u00e1ad\u00e1sul a Lamoda h\u00e1rom orsz\u00e1gban is m\u0171k\u00f6dik az orosz F\u00f6der\u00e1ci\u00f3n k\u00edv\u00fcl, ahol minden kicsit m\u00e1sk\u00e9nt t\u00f6rt\u00e9nik. \u00d6sszess\u00e9g\u00e9ben t\u00f6bb mint sz\u00e1z m\u00f3dja l\u00e9tezik egy \u00faj rendel\u00e9s konfigur\u00e1l\u00e1s\u00e1nak, amelyeket k\u00fcl\u00f6nb\u00f6z\u0151k\u00e9ppen kell feldolgozni. Mindez t\u00f6bb tucat szolg\u00e1ltat\u00e1ssal m\u0171k\u00f6dik, amelyek n\u00e9ha nem nyilv\u00e1nval\u00f3 m\u00f3don kommunik\u00e1lnak egym\u00e1ssal. Van egy k\u00f6zponti rendszer is, amelynek f\u0151 feladata a rendel\u00e9s st\u00e1tusz\u00e1nak kezel\u00e9se. Ezt BOB-nak h\u00edvjuk, \u00e9n dolgozom vele.<\/p>\n<h2>Visszat\u00e9r\u00edt\u00e9si eszk\u00f6z esem\u00e9nyalap\u00fa API-val <\/h2>\n<p>\nAz esem\u00e9nyalap\u00fa kifejez\u00e9s el\u00e9g elcs\u00e9pelt, kicsit k\u00e9s\u0151bb r\u00e9szletesebben meghat\u00e1rozzuk, mit is \u00e9rt\u00fcnk ez alatt. Azt a kontextust szeretn\u00e9m bemutatni, amelyben eld\u00f6nt\u00f6tt\u00fck, hogy kipr\u00f3b\u00e1ljuk az esem\u00e9nyalap\u00fa API megk\u00f6zel\u00edt\u00e9st a Kafka haszn\u00e1lat\u00e1val. <\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/3bfdce47dd8420fc63d84645e76de647.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nB\u00e1rmely boltban, a megrendel\u00e9sek mellett, amelyek ut\u00e1n a v\u00e1s\u00e1rl\u00f3k fizetnek, vannak olyan pillanatok is, amikor a boltt\u00f3l azt v\u00e1rj\u00e1k el, hogy visszat\u00e9r\u00edtse a p\u00e9nzt, mert az \u00fcgyf\u00e9lnek nem felelt meg a term\u00e9k. Ez a viszonylag r\u00f6vid folyamat: sz\u00fcks\u00e9g eset\u00e9n tiszt\u00e1zzuk az inform\u00e1ci\u00f3kat, majd elind\u00edtjuk a visszat\u00e9r\u00edt\u00e9st. <\/p>\n<p>A visszat\u00e9r\u00edt\u00e9si folyamat bonyolultabb\u00e1 v\u00e1lt a jogszab\u00e1lyi v\u00e1ltoz\u00e1sok miatt, \u00e9s k\u00f6telez\u0151v\u00e9 v\u00e1lt, hogy egy k\u00fcl\u00f6n mikroszolg\u00e1ltat\u00e1st val\u00f3s\u00edtsunk meg ennek megfelel\u0151en.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/0e358df5476e7448976e0f1147a103fb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMotiv\u00e1ci\u00f3nk:<\/p>\n<ol>\n<li><strong>54. sz\u00e1m\u00fa t\u00f6rv\u00e9ny<\/strong>\u00a0\u2014 r\u00f6viden, a t\u00f6rv\u00e9ny megk\u00f6veteli, hogy minden p\u00e9nz\u00fcgyi tranzakci\u00f3r\u00f3l, legyen az visszat\u00e9r\u00edt\u00e9s vagy bev\u00e9tel, r\u00f6vid SLA keret\u00e9ben, p\u00e1r percen bel\u00fcl t\u00e1j\u00e9koztassuk az ad\u00f3hat\u00f3s\u00e1got. Mi, mint e-kereskedelmi v\u00e1llalat, sz\u00e1mos tranzakci\u00f3t bonyol\u00edtunk. Technikai \u00e9rtelemben ez \u00faj felel\u0151ss\u00e9get jelent (teh\u00e1t \u00faj szolg\u00e1ltat\u00e1st) \u00e9s fejleszt\u00e9seket a kapcsol\u00f3d\u00f3 rendszerekben.<\/li>\n<li><strong>BOB split<\/strong>\u00a0\u2014 a c\u00e9g bels\u0151 projektje, amelynek c\u00e9lja BOB-t\u00f3l a nem f\u0151bb feladatok elt\u00e1vol\u00edt\u00e1sa \u00e9s \u00f6sszetetts\u00e9g\u00e9nek cs\u00f6kkent\u00e9se.<\/li>\n<\/ol>\n<p>\n<img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/d3ecf9961bdb372fc5f84ee9389f73ef.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEzen a diagramon a Lamoda f\u0151bb rendszerei l\u00e1that\u00f3k. Jelenleg ezek t\u00f6bbs\u00e9ge ink\u00e1bb <strong>5-10 mikroszolg\u00e1ltat\u00e1sb\u00f3l \u00e1ll\u00f3 csillaghalmazk\u00e9nt funkcion\u00e1l a cs\u00f6kken\u0151 monolit k\u00f6r\u00fcl.<\/strong>Fokozatosan n\u0151nek, de pr\u00f3b\u00e1ljuk \u0151ket kisebbre venni, mert f\u00e9lelmetes egy k\u00f6z\u00e9ps\u0151 r\u00e9szt telep\u00edteni \u2014 nem engedhetj\u00fck meg, hogy le\u00e1lljon. Minden adatcsere (nyilak) eset\u00e9n tartal\u00e9kolnunk kell, mert b\u00e1rmelyik\u00fck el\u00e9rhetetlenn\u00e9 v\u00e1lhat.<\/p>\n<p>A BOB-ban is el\u00e9g sok adatcsere van: fizet\u00e9si, sz\u00e1ll\u00edt\u00e1si rendszerek, \u00e9rtes\u00edt\u00e9sek stb. <\/p>\n<p>Technikailag a BOB a k\u00f6vetkez\u0151kb\u0151l \u00e1ll:<\/p>\n<ul>\n<li>~150k sor k\u00f3d + ~100k sor teszt;<\/li>\n<li>php7.2 + Zend 1 &amp; Symfony Components 3;<\/li>\n<li>&gt;100 API &amp; ~50 kimen\u0151 integr\u00e1ci\u00f3;<\/li>\n<li>4 orsz\u00e1g a saj\u00e1t \u00fczleti logik\u00e1j\u00e1val. <\/li>\n<\/ul>\n<p>\nA BOB telep\u00edt\u00e9se dr\u00e1ga \u00e9s f\u00e1jdalmas, a k\u00f3d mennyis\u00e9ge \u00e9s az \u00e1ltala megoldott feladatok olyannyira komplexek, hogy senki sem k\u00e9pes minden r\u00e9szlet\u00e9t teljesen \u00e1tl\u00e1tni. \u00d6sszess\u00e9g\u00e9ben sok ok van a leegyszer\u0171s\u00edt\u00e9s\u00e9re.<\/p>\n<h2>A visszat\u00e9r\u00edt\u00e9si folyamat<\/h2>\n<p>\nKezdetben k\u00e9t rendszer van bevonva a folyamatba: BOB \u00e9s Payment. Most m\u00e1r \u00fajabb kett\u0151 is csatlakozik:<\/p>\n<ul>\n<li>Fiscalization Service, amely \u00e1tv\u00e1llalja a fiskaliz\u00e1l\u00e1si probl\u00e9m\u00e1kat \u00e9s a k\u00fcls\u0151 szolg\u00e1ltat\u00e1sokkal val\u00f3 kommunik\u00e1ci\u00f3t.<\/li>\n<li>Refund Tool, amely lehet\u0151v\u00e9 teszi az \u00faj adatcser\u00e9k kiemel\u00e9s\u00e9t, hogy ne b\u0151v\u00edts\u00fck tov\u00e1bb a BOB-ot.<\/li>\n<\/ul>\n<p>\nMost a folyamat \u00edgy n\u00e9z ki:<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/13c02975881ad35c61304053c604cda3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ol>\n<li>A BOB-hoz \u00e9rkezik egy k\u00e9r\u00e9s a p\u00e9nz visszat\u00e9r\u00edt\u00e9s\u00e9re.<\/li>\n<li>A BOB t\u00e1j\u00e9koztatja err\u0151l a Refund Tool-t.<\/li>\n<li>A Refund Tool azt mondja a Payment-nek: \u201eItt a p\u00e9nz visszat\u00e9r\u00edt\u00e9se\u201d.<\/li>\n<li>A Payment visszat\u00e9r\u00edti a p\u00e9nzt.<\/li>\n<li>A Refund Tool \u00e9s a BOB szinkroniz\u00e1lj\u00e1k az \u00e1llapotokat, mert egyel\u0151re mindkett\u0151nek sz\u00fcks\u00e9ge van r\u00e1. M\u00e9g nem vagyunk teljesen k\u00e9szen a Refund Tool-ra val\u00f3 \u00e1tt\u00e9r\u00e9shez, mivel a BOB-nak van UI-ja, k\u00f6nyvel\u00e9si jelent\u00e9sek \u00e9s sok olyan adat, amelyet \u00edgy nem lehet egyszer\u0171en \u00e1thelyezni. K\u00e9t sz\u00e9k k\u00f6z\u00f6tt kell egyens\u00falyozni.<\/li>\n<li>K\u00e9rd\u00e9s k\u00fcld\u00e9se a fiskaliz\u00e1l\u00e1sra.<\/li>\n<\/ol>\n<p>\nA v\u00e9geredm\u00e9ny az lett, hogy l\u00e9trehoztunk egy esem\u00e9nybuszt a Kafk\u00e1n, amire minden \u00e9p\u00fclt. Hurr\u00e1, most van egy k\u00f6zponti hibapontunk (ir\u00f3nia).<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/674edd7972998b4985071f5250612c7e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA pozit\u00edvumok \u00e9s negat\u00edvumok egy\u00e9rtelm\u0171ek. L\u00e9trehoztunk egy buszt, \u00edgy most minden szolg\u00e1ltat\u00e1s t\u0151le f\u00fcgg. Ez leegyszer\u0171s\u00edti a tervez\u00e9st, de egy k\u00f6zponti hibapontot is bevezet a rendszerbe. Ha a Kafka le\u00e1ll, a folyamat meg\u00e1ll.<\/p>\n<h2>Mi az esem\u00e9nyalap\u00fa API? <\/h2>\n<p>\nEgy j\u00f3 v\u00e1lasz erre a k\u00e9rd\u00e9sre Martin Fowler (GOTO 2017) el\u0151ad\u00e1s\u00e1ban tal\u00e1lhat\u00f3. <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/STKCRSUsyPO\">Az Esem\u00e9nyalap\u00fa Architekt\u00fara Sok Jelent\u00e9se<\/a><\/noindex>. <\/p>\n<p>R\u00f6viden, amit csin\u00e1ltunk:<\/p>\n<ol>\n<li>K\u00f6zpontos\u00edtott\u00e1 tett\u00fck az \u00f6sszes aszinkron cser\u00e9t <strong>esem\u00e9nyt\u00e1rol\u00f3 r\u00e9v\u00e9n.<\/strong>Ahelyett, hogy a h\u00e1l\u00f3zaton minden \u00e9rdekelt fogyaszt\u00f3t \u00e9rtes\u00edten\u00e9nk az \u00e1llapotv\u00e1ltoz\u00e1sr\u00f3l, \u00edrtunk egy esem\u00e9nyt a k\u00f6zpontos\u00edtott t\u00e1rol\u00f3ba az \u00e1llapotv\u00e1ltoz\u00e1sr\u00f3l, \u00e9s az \u00e9rdekeltek olvasnak mindent, ami megjelenik ott.<\/li>\n<li>Az esem\u00e9ny egy \u00e9rtes\u00edt\u00e9s (<strong>\u00e9rtes\u00edt\u00e9sek<\/strong>) arr\u00f3l, hogy valami megv\u00e1ltozott valahol. P\u00e9ld\u00e1ul megv\u00e1ltozott a rendel\u00e9s st\u00e1tusza. A fogyaszt\u00f3, akinek fontosak a st\u00e1tuszm\u00f3dos\u00edt\u00e1shoz kapcsol\u00f3d\u00f3 adatok, amit az \u00e9rtes\u00edt\u00e9s nem tartalmaz, mag\u00e1nak tudhatja meg azok \u00e1llapot\u00e1t.<\/li>\n<li>A maxim\u00e1lis vari\u00e1ci\u00f3 a teljes esem\u00e9nyforr\u00e1s haszn\u00e1lata, <strong>\u00e1llapot\u00e1tvitel<\/strong>, amelyben az esem\u00e9ny minden inform\u00e1ci\u00f3t tartalmaz, ami a feldolgoz\u00e1shoz sz\u00fcks\u00e9ges: honnan \u00e9s milyen st\u00e1tuszba ker\u00fcltek, hogyan v\u00e1ltoztak az adatok stb. Csak a c\u00e9lszer\u0171s\u00e9g \u00e9s az inform\u00e1ci\u00f3k mennyis\u00e9ge a k\u00e9rd\u00e9s, amit megengedhet\u00fcnk magunknak t\u00e1rolni.<\/li>\n<\/ol>\n<p>\nA Refund Tool bevezet\u00e9se sor\u00e1n a harmadik v\u00e1ltozatot haszn\u00e1ltuk. Ez megk\u00f6nny\u00edtette az esem\u00e9nyek feldolgoz\u00e1s\u00e1t, mivel nem kellett r\u00e9szletes inform\u00e1ci\u00f3t kinyerni, \u00e9s kiz\u00e1rta azon forgat\u00f3k\u00f6nyvet, amikor minden \u00faj esem\u00e9ny \u00fajabb tiszt\u00e1z\u00f3 get-k\u00e9r\u00e9seket gener\u00e1l a fogyaszt\u00f3kt\u00f3l.<\/p>\n<p>A Refund Tool szolg\u00e1ltat\u00e1s <strong>nem terhelt<\/strong>, ez\u00e9rt a Kafka ott ink\u00e1bb egy pr\u00f3b\u00e1lkoz\u00e1s, mint sz\u00fcks\u00e9gszer\u0171s\u00e9g. Nem hiszem, hogy a visszat\u00e9r\u00edt\u00e9si szolg\u00e1ltat\u00e1s highload projektt\u00e9 v\u00e1lt volna, az \u00fczlet \u00f6r\u00fclt volna.<\/p>\n<h4>Aszinkron csere JELENLEG<\/h4>\n<p>\nAszinkron cser\u00e9khez a PHP oszt\u00e1ly \u00e1ltal\u00e1ban RabbitMQ-t haszn\u00e1l. \u00d6sszegy\u0171jt\u00f6tt\u00fck az adatokat a k\u00e9r\u00e9shez, beraktuk a sorba, \u00e9s a fogyaszt\u00f3 ugyanonnan kiolvasta \u00e9s elk\u00fcldte (vagy nem k\u00fcldte el). Mag\u00e1hoz az API-hoz a Lamoda akt\u00edvan haszn\u00e1lja a Swagger-t. Megtervezz\u00fck az API-t, le\u00edrjuk a Swaggerben, \u00e9s gener\u00e1lunk kliens- \u00e9s szerverk\u00f3dot. Ezen k\u00edv\u00fcl egy kicsit kiterjesztett JSON RPC 2.0-t is haszn\u00e1lunk. <\/p>\n<p>N\u00e9h\u00e1ny helyen esb buszokat haszn\u00e1lnak, m\u00e1sok activeMQ-n \u00e9lnek, de \u00f6sszess\u00e9g\u00e9ben, <strong>RabbitMQ - szabv\u00e1ny<\/strong>.<\/p>\n<h4>Async exchange TO BE<\/h4>\n<p>\nAz esem\u00e9ny buszra t\u00f6rt\u00e9n\u0151 cser\u00e9k tervez\u00e9se sor\u00e1n anal\u00f3gi\u00e1t vonhatunk. Hasonl\u00f3 m\u00f3don \u00edrjuk le az adatcser\u00e9t az esem\u00e9nyek szerkezet\u00e9nek le\u00edr\u00e1sa r\u00e9v\u00e9n. A YAML form\u00e1tum\u00fa k\u00f3dgener\u00e1l\u00e1st magunknak kellett megval\u00f3s\u00edtanunk, a specifik\u00e1ci\u00f3nak megfelel\u0151en a gener\u00e1tor DTO-t hoz l\u00e9tre, \u00e9s megtan\u00edtja az \u00fcgyfeleknek \u00e9s a szervereknek, hogyan dolgozzanak vele. A gener\u00e1l\u00e1s k\u00e9t nyelven t\u00f6rt\u00e9nik - <strong>golang \u00e9s php<\/strong>. Ez lehet\u0151v\u00e9 teszi, hogy a k\u00f6nyvt\u00e1rak \u00f6sszhangban maradjanak. A gener\u00e1tort golang nyelven \u00edrt\u00e1k, ez\u00e9rt gogi nevet kapta.<\/p>\n<p>Az esem\u00e9nyforr\u00e1s Kafka seg\u00edts\u00e9g\u00e9vel - tipikus dolog. Van megold\u00e1s a f\u0151 v\u00e1llalati verzi\u00f3t\u00f3l, a Kafka Confluentt\u0151l, van <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/nakadi\">nakadi<\/a><\/noindex>, a Zalando domain ter\u00fclet\u00e9n l\u00e9v\u0151 'testv\u00e9reink' megold\u00e1sa. A motiv\u00e1ci\u00f3nk, hogy a vanilla Kafk\u00e1val kezdj\u00fcnk, <strong>az, hogy a megold\u00e1s ingyenes maradjon, am\u00edg v\u00e9glegesen el nem d\u00f6ntj\u00fck, hogy sz\u00e9les k\u00f6rben haszn\u00e1lni fogjuk, \u00e9s hogy legyen mozg\u00e1ster\u00fcnk a fejleszt\u00e9sre: t\u00e1mogatni szeretn\u00e9nk a saj\u00e1t<\/strong>\u00a0JSON RPC 2.0 <strong>, gener\u00e1torokat k\u00e9t nyelvhez, \u00e9s megn\u00e9zz\u00fck, mi m\u00e9g.<\/strong>Ironikus, hogy m\u00e9g egy ilyen boldog helyzetben is, ahol van k\u00f6r\u00fclbel\u00fcl hasonl\u00f3 \u00fczlet, mint a Zalando, amely hasonl\u00f3 megold\u00e1st m\u0171k\u00f6dtetett, nem tudjuk hat\u00e9konyan kihaszn\u00e1lni. <\/p>\n<p>Architektur\u00e1lisan a futtat\u00e1skor a minta a k\u00f6vetkez\u0151: k\u00f6zvetlen\u00fcl olvasunk a Kafk\u00e1b\u00f3l, de csak az esem\u00e9ny buszon kereszt\u00fcl \u00edrunk. Sz\u00e1mos m\u00e1r megl\u00e9v\u0151 megold\u00e1s van a Kafka olvas\u00e1s\u00e1ra: br\u00f3kerek, terhel\u00e9seloszt\u00f3k, melyek t\u00f6bb\u00e9-kev\u00e9sb\u00e9 felk\u00e9sz\u00fcltek a v\u00edzszintes sk\u00e1l\u00e1z\u00e1sra, ezt meg akartuk \u0151rizni. Az \u00edr\u00e1s azonban \u00e1tkonfigur\u00e1lva, egy Gateway-n kereszt\u00fcl t\u00f6rt\u00e9nik, m\u00e1s n\u00e9ven Events-bus, \u00e9s ez az oka. <\/p>\n<p>Events-bus<\/p>\n<h3>Vagy esem\u00e9ny busz. Ez egy egyszer\u0171 stateless HTTP gateway, amely t\u00f6bb fontos szerepet v\u00e1llal:<\/h3>\n<p>\nA gy\u00e1rt\u00e1s \u00e9rv\u00e9nyes\u00edt\u00e9se<\/p>\n<ul>\n<li><strong>ellen\u0151rizz\u00fck, hogy az esem\u00e9nyek megfelelnek-e a specifik\u00e1ci\u00f3nknak.<\/strong>\u00a0Esem\u00e9nyek f\u0151 rendszer<\/li>\n<li><strong>, ez az egyetlen rendszer a c\u00e9gen bel\u00fcl, amely v\u00e1laszol azokra a k\u00e9rd\u00e9sekre, hogy mely esem\u00e9nyek \u00e9s milyen szerkezetek sz\u00e1m\u00edtanak \u00e9rv\u00e9nyesnek. Az \u00e9rv\u00e9nyes\u00edt\u00e9s mag\u00e1ban foglalja az adatt\u00edpusokat \u00e9s az enumokat a tartalom szigor\u00fa specifik\u00e1ci\u00f3j\u00e1ra.<\/strong>Hash-funkci\u00f3 <\/li>\n<li><strong>a sharding sz\u00e1m\u00e1ra - a Kafka \u00fczenetszerkezete kulcs-\u00e9rt\u00e9k p\u00e1r, \u00e9s a kulcs hash-e alapj\u00e1n sz\u00e1m\u00edt\u00f3dik, hov\u00e1 kell ezt elhelyezni.<\/strong> Mi\u00e9rt<\/li>\n<\/ul>\n<p><\/p>\n<h3>Egy nagy c\u00e9gn\u00e9l dolgozunk, amelynek j\u00f3l bej\u00e1ratott folyamata van. Mi\u00e9rt kellene b\u00e1rmit is megv\u00e1ltoztatni?<\/h3>\n<p>\nEz egy k\u00eds\u00e9rlet <strong>, \u00e9s sz\u00e1m\u00edtunk arra, hogy t\u00f6bb el\u0151nyt szerz\u00fcnk.<\/strong>1:n+1 cser\u00e9k (egy a sokhoz)<\/p>\n<h4>A Kafk\u00e1val nagyon k\u00f6nny\u0171 \u00faj fogyaszt\u00f3kat csatlakoztatni az API-hoz.<\/h4>\n<p>\nA Kafka seg\u00edts\u00e9g\u00e9vel nagyon k\u00f6nnyen csatlakoztathatunk \u00faj fogyaszt\u00f3kat az API-hoz. <\/p>\n<p>Tegy\u00fck fel, hogy van egy adatb\u00e1zis, amelyet t\u00f6bb rendszert egyszerre kell friss\u00edteni (\u00e9s \u00faj rendszerekben is). Kor\u00e1bban l\u00e9trehoztunk egy bundle-t, amely megval\u00f3s\u00edtotta a set API-t, \u00e9s a f\u0151rendszernek jelezt\u00fck a fogyaszt\u00f3k c\u00edm\u00e9t. Most a f\u0151rendszer friss\u00edt\u00e9seket k\u00fcld a t\u00e9m\u00e1ba, \u00e9s mindenki, akit ez \u00e9rdekel, elolvassa. Megjelent egy \u00faj rendszer \u2014 a t\u00e9m\u00e1ra feliratkoztunk. Igen, ugyanaz a bundle, de egyszer\u0171bb.<\/p>\n<p>A refund-tool eset\u00e9ben, amely l\u00e9nyeg\u00e9ben a BOB egy r\u00e9sze, k\u00e9nyelmes, ha a Kafka seg\u00edts\u00e9g\u00e9vel tartjuk \u0151ket szinkronban. A Payment azt mondja, hogy a p\u00e9nz vissza lett t\u00e9r\u00edtve: a BOB, a RT err\u0151l \u00e9rtes\u00fclt, statusaikat megv\u00e1ltoztatt\u00e1k, a Fiscalization Service is tudom\u00e1st szerzett r\u00f3la, \u00e9s ki\u00e1ll\u00edtotta a blokkot.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/b01b22a333b58e87aeef0c52d40e6960.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTervezz\u00fck, hogy l\u00e9trehozunk egy egys\u00e9ges Notifications Service-t, amely \u00e9rtes\u00edti az \u00fcgyfelet a rendel\u00e9seivel\/visszat\u00e9r\u00edt\u00e9seivel kapcsolatos h\u00edrekr\u0151l. Jelenleg ez a felel\u0151ss\u00e9g sz\u00e9tsz\u00f3rva van a rendszerek k\u00f6z\u00f6tt. El\u00e9g, ha megtan\u00edtjuk a Notifications Service-t, hogy a Kafka-b\u00f3l relev\u00e1ns inform\u00e1ci\u00f3kat sz\u0171rj\u00f6n ki \u00e9s reag\u00e1ljon ezekre (\u00e9s le\u00e1ll\u00edtjuk a t\u00f6bbi rendszeren ezeket az \u00e9rtes\u00edt\u00e9seket). Nincs sz\u00fcks\u00e9g \u00faj k\u00f6zvetlen cser\u00e9k kialak\u00edt\u00e1s\u00e1ra.<\/p>\n<h4>Adatok vez\u00e9relt<\/h4>\n<p>\nAz inform\u00e1ci\u00f3k \u00e1tl\u00e1that\u00f3v\u00e1 v\u00e1lnak a rendszerek k\u00f6z\u00f6tt \u2014 b\u00e1rmilyen \u201ev\u00e9rz\u0151 v\u00e1llalat\u201d is \u00e1lljon a h\u00e1tt\u00e9rben, \u00e9s ak\u00e1rmilyen vastag legyen a backlog-otok. A Lamod\u00e1n\u00e1l van egy Data Analytics oszt\u00e1ly, amely adatokat gy\u0171jt a rendszerekb\u0151l, \u00e9s \u00fajrahaszn\u00e1lhat\u00f3 form\u00e1ba rendezi \u0151ket, mind az \u00fczlet, mind az intelligens rendszerek sz\u00e1m\u00e1ra. A Kafka lehet\u0151v\u00e9 teszi, hogy gyorsan sok adatot biztos\u00edtsunk sz\u00e1mukra, \u00e9s folyamatosan naprak\u00e9szen tartsuk ezt az inform\u00e1ci\u00f3s \u00e1raml\u00e1st.<\/p>\n<h4>Replik\u00e1ci\u00f3s napl\u00f3<\/h4>\n<p>\nAz \u00fczenetek nem t\u0171nnek el az olvas\u00e1s ut\u00e1n, mint a RabbitMQ-ban. Amikor az esem\u00e9ny elegend\u0151 inform\u00e1ci\u00f3t tartalmaz a feldolgoz\u00e1shoz, rendelkez\u00e9s\u00fcnkre \u00e1ll az objektum utols\u00f3 v\u00e1ltoz\u00e1sainak t\u00f6rt\u00e9nete, \u00e9s ha akarjuk, lehet\u0151s\u00e9g\u00fcnk van ezeket a v\u00e1ltoz\u00e1sokat alkalmazni.<\/p>\n<p>A replik\u00e1ci\u00f3s napl\u00f3 t\u00e1rol\u00e1si ideje a t\u00e9ma \u00edr\u00e1si intenzit\u00e1s\u00e1t\u00f3l f\u00fcgg, a Kafka lehet\u0151v\u00e9 teszi, hogy rugalmasan be\u00e1ll\u00edtsuk a t\u00e1rol\u00e1si id\u0151korl\u00e1tokat \u00e9s az adatmennyis\u00e9get. Intenz\u00edv t\u00e9m\u00e1k eset\u00e9n fontos, hogy minden fogyaszt\u00f3 id\u0151ben el tudja olvasni az inform\u00e1ci\u00f3t, miel\u0151tt az elt\u0171nik, m\u00e9g akkor is, ha \u00e1tmeneti le\u00e1ll\u00e1s van. \u00c1ltal\u00e1ban siker\u00fcl az adatokat a\u00a0<strong>napok egys\u00e9geiig<\/strong>, ami teljesen elegend\u0151 a t\u00e1mogat\u00e1s sz\u00e1m\u00e1ra. <\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/0e08dd384155289123ebee96430c2370.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKicsit m\u00e9g a dokument\u00e1ci\u00f3 \u00e1t\u00edr\u00e1sa, azok sz\u00e1m\u00e1ra, akik nem ismerik a Kafk\u00e1t (a k\u00e9p szint\u00e9n a dokument\u00e1ci\u00f3b\u00f3l sz\u00e1rmazik)<\/p>\n<p>Az AMQP-ban vannak sorok: \u00fczeneteket \u00edrunk a fogyaszt\u00f3 sor\u00e1ba. \u00c1ltal\u00e1ban egy sorral egy rendszer foglalkozik, amelynek ugyanaz a \u00fczleti logik\u00e1ja. Ha t\u00f6bb rendszert kell \u00e9rtes\u00edteni, az alkalmaz\u00e1st meg lehet tan\u00edtani, hogy t\u00f6bb sorba \u00edrjon, vagy be\u00e1ll\u00edthatunk egy exchange-et fanout mechanizmussal, amely saj\u00e1t mag\u00e1t kl\u00f3nozza.<\/p>\n<p>A Kafka hasonl\u00f3 absztrakci\u00f3val rendelkezik <em>t\u00e9ma<\/em>, ahov\u00e1 \u00fczeneteket \u00edr, de azok nem t\u0171nnek el az olvas\u00e1s ut\u00e1n. Alap\u00e9rtelmez\u00e9s szerint, amikor csatlakozik a Kafk\u00e1hoz, megkapja az \u00f6sszes \u00fczenetet, \u00e9s van lehet\u0151s\u00e9ge meg\u0151rizni azt a helyet, ahol abbahagyta. Teh\u00e1t folyamatosan olvas, nem kell megjel\u00f6lnie az \u00fczenetet olvasottk\u00e9nt, de meg\u0151rizheti az id-t, ahonnan folytatja az olvas\u00e1st. Az id, ahol meg\u00e1llt, offset-nek (eltol\u00e1s) nevezz\u00fck, a mechanizmus pedig commit offset. <\/p>\n<p>Ennek megfelel\u0151en k\u00fcl\u00f6nb\u00f6z\u0151 logik\u00e1t lehet megval\u00f3s\u00edtani. P\u00e9ld\u00e1ul a BOB n\u00e9gy p\u00e9ld\u00e1nyban l\u00e9tezik k\u00fcl\u00f6nb\u00f6z\u0151 orsz\u00e1gok sz\u00e1m\u00e1ra \u2013 a Lamoda Oroszorsz\u00e1gban, Kazahszt\u00e1nban, Ukrajn\u00e1ban \u00e9s Feh\u00e9roroszorsz\u00e1gban el\u00e9rhet\u0151. Mivel k\u00fcl\u00f6n telep\u00edtik \u0151ket, kicsit elt\u00e9r\u0151 konfigur\u00e1ci\u00f3ik \u00e9s saj\u00e1t \u00fczleti logik\u00e1juk van. Az \u00fczenetben megadjuk, hogy melyik orsz\u00e1ghoz tartozik. Minden egyes BOB fogyaszt\u00f3 minden orsz\u00e1gban k\u00fcl\u00f6nb\u00f6z\u0151 groupId-kkal olvas, \u00e9s ha az \u00fczenet nem a saj\u00e1t orsz\u00e1g\u00e1hoz tartozik, akkor \u00e1tugorja azt, teh\u00e1t azonnal commitolja az offset +1-et. Ha ugyanaz a t\u00e9ma olvassa a Payment Service-t, akkor k\u00fcl\u00f6n csoporttal csin\u00e1lja, \u00edgy az offset-ek nem metszik egym\u00e1st.<\/p>\n<p><b>Az esem\u00e9nyekre vonatkoz\u00f3 k\u00f6vetelm\u00e9nyek:<\/b><\/p>\n<ul>\n<li><strong>Az adatok teljess\u00e9ge. <\/strong>Szeretn\u00e9nk, ha az esem\u00e9nyben elegend\u0151 adat lenne ahhoz, hogy feldolgozhat\u00f3 legyen. <\/li>\n<\/ul>\n<p><\/p>\n<ul>\n<li><strong>Integrit\u00e1s. <\/strong>Az Events-busra b\u00edzzuk, hogy ellen\u0151rizze, hogy az esem\u00e9ny k\u00f6vetkezetes-e, \u00e9s hogy k\u00e9pes-e azt feldolgozni.<\/li>\n<li><strong>Fontos a sorrend. <\/strong>Visszat\u00e9r\u00e9s eset\u00e9n k\u00e9nytelenek vagyunk a t\u00f6rt\u00e9nelemmel dolgozni. Az \u00e9rtes\u00edt\u00e9sek eset\u00e9ben a sorrend nem fontos, ha homog\u00e9n \u00e9rtes\u00edt\u00e9sekr\u0151l van sz\u00f3, az e-mail azonos lesz, f\u00fcggetlen\u00fcl att\u00f3l, hogy melyik rendel\u00e9s \u00e9rkezett el\u0151bb. Visszat\u00e9r\u00e9s eset\u00e9n vil\u00e1gos folyamat van, ha megv\u00e1ltoztatjuk a sorrendet, akkor kiv\u00e9telek l\u00e9phetnek fel, a refund nem j\u00f6n l\u00e9tre vagy nem ker\u00fcl feldolgoz\u00e1sra \u2013 m\u00e1s \u00e1llapotba ker\u00fcl\u00fcnk.<\/li>\n<li><strong>Konzisztencia. <\/strong>Van egy t\u00e1rol\u00f3nk, \u00e9s most esem\u00e9nyeket hozunk l\u00e9tre API helyett. Sz\u00fcks\u00e9g\u00fcnk van egy m\u00f3dra, hogy gyorsan \u00e9s olcs\u00f3n tov\u00e1bb\u00edtsuk a szolg\u00e1ltat\u00e1sainkba az \u00faj esem\u00e9nyekr\u0151l \u00e9s a m\u00e1r megl\u00e9v\u0151 v\u00e1ltoz\u00e1sokr\u00f3l sz\u00f3l\u00f3 inform\u00e1ci\u00f3kat. Ezt egy k\u00f6z\u00f6s specifik\u00e1ci\u00f3val \u00e9rj\u00fck el egy k\u00fcl\u00f6n git-reposzitoriumban \u00e9s k\u00f3dgener\u00e1torok seg\u00edts\u00e9g\u00e9vel. \u00cdgy az \u00fcgyfelek \u00e9s a szerverek a k\u00fcl\u00f6nb\u00f6z\u0151 szolg\u00e1ltat\u00e1sokban \u00f6ssze vannak hangolva.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Kafka a Lamod\u00e1ban<\/h2>\n<p>\nH\u00e1rom Kafka telep\u00edt\u00e9s\u00fcnk van: <\/p>\n<ol>\n<li>Napl\u00f3k;<\/li>\n<li>R&amp;D;<\/li>\n<li>Esem\u00e9ny-busz.<\/li>\n<\/ol>\n<p>\nMa csak az utols\u00f3 pontr\u00f3l fogunk besz\u00e9lni. Az esem\u00e9ny-buszunk nem t\u00fal nagy telep\u00edt\u00e9sekb\u0151l \u00e1ll - 3 br\u00f3ker (szerver) \u00e9s \u00f6sszesen 27 t\u00e9ma van. \u00c1ltal\u00e1ban egy t\u00e9ma egy folyamatot jelent. De ez egy finom dolog, \u00e9s most foglalkozni fogunk vele.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/f398852689b31429cc97b4cbffcabab5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFent a rps grafikon. A visszat\u00e9r\u00edt\u00e9si folyamat a ci\u00e1nk\u00e9k vonallal van megjel\u00f6lve (igen, az, amelyik az X tengelyen fekszik), a r\u00f3zsasz\u00edn pedig a tartalom friss\u00edt\u00e9s\u00e9nek folyamata. <\/p>\n<p>A Lamoda katal\u00f3gus\u00e1ban milli\u00f3 term\u00e9k tal\u00e1lhat\u00f3, \u00e9s az adatok folyamatosan friss\u00fclnek. Egyes kollekci\u00f3k kimentek a divatb\u00f3l, \u00fajakat adnak ki helyett\u00fck, a katal\u00f3gus folyamatosan \u00faj modellekkel b\u0151v\u00fcl. Folyamatosan pr\u00f3b\u00e1ljuk megj\u00f3solni, mi lesz \u00e9rdekes az \u00fcgyfeleink sz\u00e1m\u00e1ra holnap, ez\u00e9rt folyamatosan \u00faj dolgokat v\u00e1s\u00e1rolunk, f\u00e9nyk\u00e9pezz\u00fck \u0151ket, \u00e9s friss\u00edtj\u00fck a vitrin\u00fcnket. <\/p>\n<p>A r\u00f3zsasz\u00edn cs\u00facsok a term\u00e9kfriss\u00edt\u00e9seket jel\u00f6lik, teh\u00e1t a term\u00e9keken v\u00e9grehajtott v\u00e1ltoztat\u00e1sokat. L\u00e1that\u00f3, hogy a sr\u00e1cok f\u00e9nyk\u00e9pezt\u00e9k, f\u00e9nyk\u00e9pezt\u00e9k, majd hirtelen! - bet\u00f6lt\u00f6ttek egy csom\u00f3 esem\u00e9nyt.<\/p>\n<h2>Lamoda esem\u00e9nyhaszn\u00e1lati esetek<\/h2>\n<p>\nAz \u00e9p\u00edtett architekt\u00far\u00e1t az al\u00e1bbi m\u0171veletekhez haszn\u00e1ljuk:<\/p>\n<ul>\n<li><strong>A visszat\u00e9r\u00edt\u00e9sek st\u00e1tusz\u00e1nak nyomon k\u00f6vet\u00e9se<\/strong>: call-to-action \u00e9s a st\u00e1tuszok nyomon k\u00f6vet\u00e9se minden \u00e9rintett rendszerb\u0151l. Fizet\u00e9s, st\u00e1tuszok, fiskaliz\u00e1ci\u00f3, \u00e9rtes\u00edt\u00e9sek. Itt kipr\u00f3b\u00e1ltuk az megk\u00f6zel\u00edt\u00e9st, k\u00e9sz\u00edtett\u00fcnk eszk\u00f6z\u00f6ket, \u00f6sszegy\u0171jt\u00f6tt\u00fck az \u00f6sszes hib\u00e1t, dokument\u00e1ci\u00f3t \u00edrtunk, \u00e9s elmondtuk a koll\u00e9g\u00e1knak, hogyan haszn\u00e1lj\u00e1k ezt.<\/li>\n<li><strong>Term\u00e9kadatlap friss\u00edt\u00e9se: <\/strong>konfigur\u00e1ci\u00f3, metaadatok, jellemz\u0151k. Egy rendszer olvas (ami megjelen\u00edti), m\u00edg t\u00f6bb \u00edr.<\/li>\n<li><strong>Email, push \u00e9s sms<\/strong>: a rendel\u00e9s \u00f6ssze\u00e1llt, a rendel\u00e9s meg\u00e9rkezett, a visszat\u00e9r\u00e9s elfogadva, stb., sok van bel\u0151l\u00fck. <\/li>\n<li><strong>K\u00e9szlet, a rakt\u00e1r friss\u00edt\u00e9se<\/strong>\u00a0\u2014 mennyis\u00e9gi friss\u00edt\u00e9s az elemekr\u0151l, csak sz\u00e1mok: k\u00e9szletbe \u00e9rkez\u00e9s, visszat\u00e9r\u00e9s. Meg kell gy\u0151z\u0151dni arr\u00f3l, hogy minden term\u00e9kfenntart\u00e1ssal kapcsolatos rendszer a lehet\u0151 legaktu\u00e1lisabb adatokkal dolgozik. Jelenleg a k\u00e9szletfriss\u00edt\u00e9si rendszer meglehet\u0151sen bonyolult, a Kafka lehet\u0151v\u00e9 teszi ennek egyszer\u0171s\u00edt\u00e9s\u00e9t.<\/li>\n<li><strong>Adat elemz\u00e9s<\/strong> (K+F oszt\u00e1ly), ML eszk\u00f6z\u00f6k, analitika, statisztika. Azt szeretn\u00e9nk, ha az inform\u00e1ci\u00f3 \u00e1tl\u00e1that\u00f3 lenne \u2013 ez\u00e9rt a Kafka j\u00f3l megfelel.<\/li>\n<\/ul>\n<p>\nMost j\u00f6jj\u00f6n a sz\u00f3rakoztat\u00f3bb r\u00e9sz a tapasztalatokr\u00f3l \u00e9s a figyelemre m\u00e9lt\u00f3 felfedez\u00e9sekr\u0151l, amelyek az elm\u00falt f\u00e9l \u00e9vben t\u00f6rt\u00e9ntek.<\/p>\n<h2>Tervez\u00e9si probl\u00e9m\u00e1k<\/h2>\n<p>\nTegy\u00fck fel, hogy szeretn\u00e9nk l\u00e9trehozni egy \u00faj dolgot \u2013 p\u00e9ld\u00e1ul \u00e1t\u00e1ll\u00edtani a Kafka-ra az eg\u00e9sz sz\u00e1ll\u00edt\u00e1si folyamatot. Jelenleg a folyamat egy r\u00e9sze az Order Processing-ben van a BOB-ban. A rendel\u00e9s szolg\u00e1ltat\u00e1sra tov\u00e1bb\u00edt\u00e1sa, az \u00e1tmeneti rakt\u00e1rba t\u00f6rt\u00e9n\u0151 \u00e1thelyez\u00e9s \u00e9s hasonl\u00f3k m\u00f6g\u00f6tt egy st\u00e1tuszmodell \u00e1ll. Van egy nagy monolit, s\u0151t kett\u0151, r\u00e1ad\u00e1sul egy csom\u00f3 API, amely a sz\u00e1ll\u00edt\u00e1ssal foglalkozik. Sokkal t\u00f6bbet tudnak a sz\u00e1ll\u00edt\u00e1sr\u00f3l. <\/p>\n<p>\u00dagy t\u0171nik, hogy ezek hasonl\u00f3 ter\u00fcletek, de az Order Processing a BOB-ban \u00e9s a sz\u00e1ll\u00edt\u00e1si rendszer eset\u00e9ben a st\u00e1tuszok elt\u00e9rnek. P\u00e9ld\u00e1ul egyes fut\u00e1rszolg\u00e1latok nem k\u00fcldenek k\u00f6ztes st\u00e1tuszokat, csak v\u00e9glegeseket: \u201ek\u00e9zbes\u00edtett\u00e9k\u201d vagy \u201eelveszett\u201d. M\u00e1sok viszont nagyon r\u00e9szletesen t\u00e1j\u00e9koztatnak az \u00e1ruk mozg\u00e1s\u00e1r\u00f3l. Mindnek megvannak a saj\u00e1t valid\u00e1ci\u00f3s szab\u00e1lyai: valakinek egy \u00e9rv\u00e9nyes email c\u00edmmel m\u00e1r feldolgozz\u00e1k; m\u00e1sokn\u00e1l \u00e9rv\u00e9nytelen, de a rendel\u00e9s m\u00e9g mindig feldolgoz\u00e1sra ker\u00fcl, mert van telefonsz\u00e1m a kapcsolattart\u00e1sra, \u00e9s van, aki azt mondja, hogy az ilyen rendel\u00e9st egy\u00e1ltal\u00e1n nem fogj\u00e1k feldolgozni.<\/p>\n<h3>Adatfolyam<\/h3>\n<p>\nA Kafka eset\u00e9ben felmer\u00fcl az adatfolyam megszervez\u00e9s\u00e9nek k\u00e9rd\u00e9se. Ez a feladat a strat\u00e9gia kiv\u00e1laszt\u00e1s\u00e1val kapcsolatos t\u00f6bb szempontb\u00f3l, v\u00e9gigmegy\u00fcnk az \u00f6sszesen.<\/p>\n<h4>Egy t\u00e9m\u00e1ba vagy k\u00fcl\u00f6nb\u00f6z\u0151 t\u00e9m\u00e1kba?<\/h4>\n<p>\nVan egy esem\u00e9nyspecifik\u00e1ci\u00f3nk. A BOB-ban azt \u00edrjuk, hogy egy adott rendel\u00e9st sz\u00e1ll\u00edtani kell, \u00e9s megadjuk: a rendel\u00e9s sz\u00e1ma, \u00f6sszetev\u0151i, SKU-k, vonalk\u00f3dok stb. Amikor az \u00e1ru meg\u00e9rkezik a rakt\u00e1rba, a sz\u00e1ll\u00edt\u00e1s k\u00e9pes lesz megkapni a st\u00e1tuszokat, id\u0151b\u00e9lyegeket \u00e9s minden sz\u00fcks\u00e9ges inform\u00e1ci\u00f3t. De ezut\u00e1n szeretn\u00e9nk a BOB-ban friss\u00edt\u00e9seket kapni ezekr\u0151l az adatokb\u00f3l. Van egy visszaford\u00edtott adatgy\u0171jt\u00e9si folyamat a sz\u00e1ll\u00edt\u00e1st\u00f3l. Ez ugyanaz az esem\u00e9ny? Vagy ez egy k\u00fcl\u00f6n csere, amely k\u00fcl\u00f6n t\u00e9m\u00e1t \u00e9rdemel?<\/p>\n<p>Val\u00f3sz\u00edn\u0171leg nagyon hasonl\u00f3ak lesznek, \u00e9s a k\u00eds\u00e9rt\u00e9s, hogy egy t\u00e9ma legyen, nem alaptalan, mert egy k\u00fcl\u00f6n t\u00e9ma k\u00fcl\u00f6n fogyaszt\u00f3kat, k\u00fcl\u00f6n konfigur\u00e1ci\u00f3kat \u00e9s annak minden gener\u00e1l\u00e1s\u00e1t jelent. De nem biztos.<\/p>\n<h4>\u00daj mez\u0151 vagy \u00faj esem\u00e9ny?<\/h4>\n<p>\nDe ha ugyanazokat az esem\u00e9nyeket haszn\u00e1ljuk, akkor egy m\u00e1sik probl\u00e9ma mer\u00fcl fel. P\u00e9ld\u00e1ul nem minden k\u00e9zbes\u00edt\u00e9si rendszer k\u00e9pes olyan DTO-t gener\u00e1lni, amely k\u00e9pes BOB-ot gener\u00e1lni. Az ID-t k\u00fcldj\u00fck nekik, de \u0151k nem mentik el, mert nem sz\u00fcks\u00e9ges sz\u00e1mukra, \u00e9s az event-bus folyamat\u00e1nak kezd\u00e9se szempontj\u00e1b\u00f3l ez a mez\u0151 k\u00f6telez\u0151. <\/p>\n<p>Ha bevezet\u00fcnk egy szab\u00e1lyt az event-bus sz\u00e1m\u00e1ra, hogy ez a mez\u0151 k\u00f6telez\u0151, akkor k\u00e9nytelenek vagyunk BOB-ban vagy a kezd\u0151 esem\u00e9ny kezel\u0151ben tov\u00e1bbi valid\u00e1l\u00e1si szab\u00e1lyokat meg\u00e1llap\u00edtani. A valid\u00e1l\u00e1s sz\u00e9tsz\u00f3r\u00f3dik a szolg\u00e1ltat\u00e1son \u2014 ez nem t\u00fal k\u00e9nyelmes.<\/p>\n<p>Egy m\u00e1sik probl\u00e9ma a fokozatos fejleszt\u00e9s cs\u00e1b\u00edt\u00e1sa. Azt mondj\u00e1k nek\u00fcnk, hogy valamit hozz\u00e1 kell adni az esem\u00e9nyhez, \u00e9s tal\u00e1n, ha j\u00f3l belegondolunk, ez k\u00fcl\u00f6n esem\u00e9nynek kellett volna lennie. De a s\u00e9ma szerint a k\u00fcl\u00f6n esem\u00e9ny k\u00fcl\u00f6n topik. A k\u00fcl\u00f6n topik az az eg\u00e9sz folyamat, amelyet fentebb le\u00edrtam. A fejleszt\u0151ben felmer\u00fcl a cs\u00e1b\u00edt\u00e1s, hogy csak hozz\u00e1adjon egy \u00faj mez\u0151t a JSON s\u00e9m\u00e1hoz \u00e9s \u00fajragener\u00e1lja.<\/p>\n<p>A refunds eset\u00e9ben \u00edgy jutottunk el f\u00e9l \u00e9v alatt az esem\u00e9nyek esem\u00e9ny\u00e9hez. Volt egy meta-esem\u00e9ny\u00fcnk, ami refund update n\u00e9ven ismert, amelyben volt egy type mez\u0151, ami le\u00edrta, mir\u0151l sz\u00f3l ez a friss\u00edt\u00e9s. Ebb\u0151l ad\u00f3d\u00f3an \u201ecsod\u00e1s\u201d kapcsol\u00f3k voltak a valid\u00e1torokkal, amelyek megmondt\u00e1k, hogyan kell valid\u00e1lni ezt az esem\u00e9nyt ezzel a typal.<\/p>\n<h4>Esem\u00e9nyverzi\u00f3z\u00e1s<\/h4>\n<p>\nA Kafka \u00fczenetek valid\u00e1l\u00e1s\u00e1hoz haszn\u00e1lhat\u00f3 <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.confluent.io\/current\/schema-registry\/docs\/index.html\">Avro<\/a><\/noindex>, de ezt m\u00e1r az elej\u00e9n figyelembe kellett venni \u00e9s haszn\u00e1lni a Confluentot. Az esem\u00e9nyverzi\u00f3z\u00e1ssal \u00f3vatosnak kell lenn\u00fcnk az eset\u00fcnkben. Nem mindig lesz lehets\u00e9ges az \u00fczeneteket \u00fajraolvasni a replication log-b\u00f3l, mert a modell \u201eelment\u201d. Alapvet\u0151en mindig \u00fagy kell verzi\u00f3kat \u00e9p\u00edten\u00fcnk, hogy a modell visszafel\u00e9 kompatibilis legyen: p\u00e9ld\u00e1ul egy mez\u0151t ideiglenesen nem k\u00f6telez\u0151v\u00e9 tenni. Ha a k\u00fcl\u00f6nbs\u00e9gek t\u00fal nagyok, \u00faj topikba kezd\u00fcnk \u00edrni, \u00e9s az \u00fcgyfeleket \u00e1t\u00fcltetj\u00fck, amikor befejezik a r\u00e9git.<\/p>\n<h4>A part\u00edci\u00f3k olvas\u00e1si sorrendj\u00e9nek garant\u00e1l\u00e1sa<\/h4>\n<p>\nA Kafka-n bel\u00fcli topikokat part\u00edci\u00f3kra osztj\u00e1k. Ez nem t\u00fal fontos, am\u00edg megtervezz\u00fck a l\u00e9nyeg\u00e9t \u00e9s az exchange-eket, de fontos, amikor eld\u00f6ntj\u00fck, hogyan kell ezeket fogyasztani \u00e9s m\u00e9retezni.<\/p>\n<p>\u00c1ltal\u00e1ban egy t\u00e9m\u00e1t \u00edr a Kafka-ba. Alap\u00e9rtelmez\u00e9s szerint egy part\u00edci\u00f3t haszn\u00e1l, \u00e9s az \u00f6sszes \u00fczenet ebbe a t\u00e9m\u00e1ba ker\u00fcl. A fogyaszt\u00f3 pedig ennek megfelel\u0151en sorban olvassa ezeket az \u00fczeneteket. Tegy\u00fck fel, hogy most a rendszert \u00fagy kell b\u0151v\u00edten\u00fcnk, hogy az \u00fczeneteket k\u00e9t k\u00fcl\u00f6nb\u00f6z\u0151 fogyaszt\u00f3 olvassa. P\u00e9ld\u00e1ul, ha SMS-t k\u00fcldesz, akkor k\u00e9rheted a Kafk\u00e1t\u00f3l, hogy k\u00e9sz\u00edtsen egy tov\u00e1bbi part\u00edci\u00f3t, \u00e9s a Kafka elkezdi felosztani az \u00fczeneteket k\u00e9t r\u00e9szre \u2013 egy r\u00e9sze ide, egy r\u00e9sze oda. <\/p>\n<p>Hogyan osztja fel ezeket a Kafka? Minden \u00fczenetnek van egy t\u00f6rzse (amelyben a JSON-t t\u00e1roljuk) \u00e9s van egy kulcs. Ehhez a kulcshoz hozz\u00e1rendelhetsz egy hash-funkci\u00f3t, amely meghat\u00e1rozza, hogy melyik part\u00edci\u00f3ba ker\u00fcl az \u00fczenet.<\/p>\n<p>A refunds eset\u00e9ben ez fontos, mert ha k\u00e9t part\u00edci\u00f3t vesz\u00fcnk, van es\u00e9ly arra, hogy a p\u00e1rhuzamos fogyaszt\u00f3 az els\u0151 esem\u00e9nyt feldolgozza els\u0151k\u00e9nt, \u00e9s ez probl\u00e9ma lehet. A hash-funkci\u00f3 garant\u00e1lja, hogy az azonos kulccsal rendelkez\u0151 \u00fczenetek egy \u00e9s ugyanazon part\u00edci\u00f3ba ker\u00fclnek. <\/p>\n<h4>Esem\u00e9nyek vs parancsok<\/h4>\n<p>\nEz egy \u00fajabb probl\u00e9ma, amellyel szembes\u00fclt\u00fcnk. Az esem\u00e9ny egy esem\u00e9ny: azt mondjuk, hogy valami valahol t\u00f6rt\u00e9nt (something_happened), p\u00e9ld\u00e1ul a t\u00e9telt visszavont\u00e1k, vagy megt\u00f6rt\u00e9nt a refund. Ha valaki hallgatja ezeket az esem\u00e9nyeket, akkor az 'item visszavont' kifejez\u00e9s eset\u00e9n l\u00e9trej\u00f6n a refund entit\u00e1s, \u00e9s a 'megt\u00f6rt\u00e9nt a refund' valahol beker\u00fcl a be\u00e1ll\u00edt\u00e1sokba.<\/p>\n<p>De \u00e1ltal\u00e1ban, amikor esem\u00e9nyeket tervezel, nem akarsz feleslegesen \u00edrni \u0151ket - arra sz\u00e1m\u00edtasz, hogy valaki majd olvassa \u0151ket. Nagy a cs\u00e1b\u00edt\u00e1s, hogy ne something_happened (item_canceled, refund_refunded), hanem something_should_be_done kifejez\u00e9seket \u00edrj. P\u00e9ld\u00e1ul, a t\u00e9tel k\u00e9szen \u00e1ll a visszat\u00e9r\u00edt\u00e9sre.<\/p>\n<p>Egyr\u00e9szt ez jelzi, hogyan fogj\u00e1k felhaszn\u00e1lni az esem\u00e9nyt. M\u00e1sr\u00e9szt ez sokkal kev\u00e9sb\u00e9 t\u0171nik norm\u00e1lis esem\u00e9nyn\u00e9vnek. Emellett ez m\u00e1r k\u00f6zel \u00e1ll a do_something parancshoz. De nincs garancia arra, hogy ezt az esem\u00e9nyt valaki elolvasta; \u00e9s ha elolvasta, akkor azt sikeresen tette; \u00e9s ha sikeresen olvasta, akkor tett valamit, \u00e9s az valami sikeresen ment v\u00e9gbe. Abban a pillanatban, amikor az esem\u00e9ny do_something-n\u00e1 v\u00e1lik, sz\u00fcks\u00e9g van visszajelz\u00e9sre, \u00e9s ez probl\u00e9ma.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/b755d91208092bd9791a41ce4633fb48.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAszinkron csere a RabbitMQ-ban, amikor elolvast\u00e1l egy \u00fczenetet, \u00e9s ment\u00e9l az http-re, van v\u00e1laszod - legal\u00e1bb annyi, hogy az \u00fczenetet fogadt\u00e1k. Amikor \u00edrt\u00e1l a Kafk\u00e1ba, van \u00fczenet arr\u00f3l, hogy \u00edrt\u00e1l a Kafk\u00e1ba, de arr\u00f3l, hogy hogyan dolgozt\u00e1k fel, semmit nem tudsz. <\/p>\n<p>Ez\u00e9rt a mi eset\u00fcnkben be kellett vezetni egy v\u00e1lasz esem\u00e9nyt, \u00e9s be kellett \u00e1ll\u00edtani a megfigyel\u00e9st arra, hogy ha ennyi esem\u00e9ny bek\u00f6vetkezett, akkor ennyi v\u00e1lasz esem\u00e9nynek kell \u00e9rkeznie egy adott id\u0151n bel\u00fcl. Ha ez nem t\u00f6rt\u00e9nt meg, akkor \u00fagy t\u0171nik, hogy valami nem stimmelt. P\u00e9ld\u00e1ul, ha elk\u00fcldt\u00fck az \"item_ready_to_refund\" esem\u00e9nyt, azt v\u00e1rjuk, hogy a refund l\u00e9trej\u00f6jj\u00f6n, a kliens visszakapja a p\u00e9nz\u00e9t, \u00e9s meg\u00e9rkezik a \"money_refunded\" esem\u00e9ny. De ez nem biztos, ez\u00e9rt sz\u00fcks\u00e9ges a megfigyel\u00e9s.<\/p>\n<h3>R\u00e9szletek<\/h3>\n<p>\nVan egy meglehet\u0151sen nyilv\u00e1nval\u00f3 probl\u00e9ma: ha a t\u00e9m\u00e1b\u00f3l folyamatosan olvas, \u00e9s van egy rossz \u00fczenet, akkor a fogyaszt\u00f3 le\u00e1ll, \u00e9s nem tud tov\u00e1bbl\u00e9pni. \u00d6nnek le kell <strong>\u00e1ll\u00edtania az \u00f6sszes fogyaszt\u00f3t<\/strong>, el kell k\u00f6teleznie a tov\u00e1bbi offsetet, hogy folytathassa az olvas\u00e1st.<\/p>\n<p>Tudtunk err\u0151l, sz\u00e1moltunk is vele, \u00e9s m\u00e9gis megt\u00f6rt\u00e9nt. Az t\u00f6rt\u00e9nt, hogy az esem\u00e9ny \u00e9rv\u00e9nyes volt az events-bus szempontj\u00e1b\u00f3l, az esem\u00e9ny \u00e9rv\u00e9nyes volt az alkalmaz\u00e1s \u00e9rv\u00e9nyes\u00edt\u0151je szempontj\u00e1b\u00f3l, de nem volt \u00e9rv\u00e9nyes a PostgreSQL szempontj\u00e1b\u00f3l, mert egy MySQL rendszerben UNSIGNED INT-t haszn\u00e1ltunk, m\u00edg az \u00fajonnan \u00edrt rendszerben csak INT volt PostgreSQL. A m\u00e9rete kicsit kisebb, \u00e9s az Id nem f\u00e9rt el. A Symfony kiv\u00e9tellel le\u00e1llt. Persze elkapjuk a kiv\u00e9telt, mert erre sz\u00e1m\u00edtottunk, \u00e9s el akartuk k\u00f6telezni ezt az offsetet, de el\u0151tte meg akartuk n\u00f6velni a probl\u00e9m\u00e1kat sz\u00e1ml\u00e1l\u00f3 mutat\u00f3t, mivel az \u00fczenet feldolgoz\u00e1sa sikertelen volt. A projektben a sz\u00e1ml\u00e1l\u00f3k is az adatb\u00e1zisban vannak, de a Symfony m\u00e1r megsz\u00fcntette az adatb\u00e1zissal val\u00f3 kapcsolatot, \u00e9s a m\u00e1sodik kiv\u00e9tel meg\u00f6lte az eg\u00e9sz folyamatot, es\u00e9ly n\u00e9lk\u00fcl arra, hogy k\u00f6telezz\u00fck az offsetet.<\/p>\n<p>Egy ideig a szolg\u00e1ltat\u00e1s pihent - szerencs\u00e9re a Kafka eset\u00e9ben ez nem olyan ijeszt\u0151, mert az \u00fczenetek megmaradnak. Amikor a munka helyre\u00e1ll, a meg lehet \u0151ket olvasni. Ez k\u00e9nyelmes.<\/p>\n<p>A Kafka lehet\u0151v\u00e9 teszi a tooling seg\u00edts\u00e9g\u00e9vel tetsz\u0151leges offset be\u00e1ll\u00edt\u00e1s\u00e1t. De ahhoz, hogy ezt megtehesse, le kell \u00e1ll\u00edtania az \u00f6sszes fogyaszt\u00f3t - a mi eset\u00fcnkben egy k\u00fcl\u00f6n kiad\u00e1st kell k\u00e9sz\u00edtenie, amelyben nem lesznek fogyaszt\u00f3k, redeployments. Akkor a tooling seg\u00edts\u00e9g\u00e9vel a Kafka-ban az offsetet el lehet tolni, \u00e9s az \u00fczenet \u00e1tmegy.<\/p>\n<p>Egy m\u00e1sik r\u00e9szlet - <strong>replik\u00e1ci\u00f3s napl\u00f3 vs rdkafka.so<\/strong>\u00a0\u2014 a projekt\u00fcnk jelleg\u00e9vel f\u00fcgg \u00f6ssze. PHP-nk van, \u00e9s a PHP-ban \u00e1ltal\u00e1ban minden k\u00f6nyvt\u00e1r a rdkafka.so t\u00e1rol\u00f3n kereszt\u00fcl kapcsol\u00f3dik a Kafka-hoz, majd j\u00f6n valamilyen csomagol\u00e1s. Lehet, hogy ezek a mi saj\u00e1t neh\u00e9zs\u00e9geink, de kider\u00fclt, hogy csak \u00fajraolvasni egy m\u00e1r olvasott r\u00e9szt nem is olyan egyszer\u0171. \u00d6sszess\u00e9g\u00e9ben programoz\u00e1si probl\u00e9m\u00e1ink voltak.<\/p>\n<p>Visszat\u00e9rve a part\u00edci\u00f3k kezel\u00e9s\u00e9nek saj\u00e1toss\u00e1gaira, a dokument\u00e1ci\u00f3ban egy\u00e9rtelm\u0171en le van \u00edrva <strong>consumers &gt;= topic partitions<\/strong>. De err\u0151l sokkal k\u00e9s\u0151bb \u00e9rtes\u00fcltem, mint szerettem volna. Ha m\u00e9retezni szeretne \u00e9s k\u00e9t fogyaszt\u00f3ja van, akkor legal\u00e1bb k\u00e9t part\u00edci\u00f3ra van sz\u00fcks\u00e9ge. Teh\u00e1t, ha volt egy part\u00edci\u00f3ja, amiben 20 ezer \u00fczenet gy\u0171lt \u00f6ssze, \u00e9s k\u00e9sz\u00edtett egy \u00fajat, az \u00fczenetek sz\u00e1ma nem fog egyhamar egyenl\u0151v\u00e9 v\u00e1lni. Ez\u00e9rt, hogy p\u00e1rhuzamos k\u00e9t fogyaszt\u00f3ja legyen, meg kell \u00e9rtenie a part\u00edci\u00f3kat.<\/p>\n<h2>Monitoroz\u00e1s<\/h2>\n<p>\nGondolom, ahogy figyelj\u00fck, egy\u00e9rtelm\u0171bb lesz, milyen probl\u00e9m\u00e1k vannak a megl\u00e9v\u0151 megk\u00f6zel\u00edt\u00e9sben.<\/p>\n<p>P\u00e9ld\u00e1ul sz\u00e1moljuk, h\u00e1ny term\u00e9k \u00e1llapota v\u00e1ltozott meg a k\u00f6zelm\u00faltban, \u00e9s ennek megfelel\u0151en esem\u00e9nyeknek kell t\u00f6rt\u00e9nni\u00fck, \u00e9s ezt a sz\u00e1mot elk\u00fcldj\u00fck a saj\u00e1t figyel\u0151rendszer\u00fcnkbe. Azt\u00e1n a Kafka-b\u00f3l megkapjuk a m\u00e1sodik sz\u00e1mot, hogy val\u00f3j\u00e1ban h\u00e1ny esem\u00e9nyt regisztr\u00e1ltak. Nyilv\u00e1nval\u00f3, hogy a k\u00fcl\u00f6nbs\u00e9g a k\u00e9t sz\u00e1m k\u00f6z\u00f6tt mindig null\u00e1nak kell lennie.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/07d8ed08514f2fb97d9019466b96342c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEzen k\u00edv\u00fcl figyelni kell a producer \u00e1llapot\u00e1t, hogy a events-bus elfogadta-e az \u00fczeneteket, \u00e9s hogy a fogyaszt\u00f3nak hogy \u00e1ll a dolga. P\u00e9ld\u00e1ul az al\u00e1bbi grafikonokon a Refund Tool-n\u00e1l minden rendben, m\u00edg a BOB-n\u00e1l nyilv\u00e1nval\u00f3an probl\u00e9m\u00e1k vannak (k\u00e9k cs\u00facsok).<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/57112dbe70d2b388c53f19c34cca6f63.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nM\u00e1r eml\u00edtettem a consumer-group lag-ot. Durv\u00e1n sz\u00f3lva ez a nem olvasott \u00fczenetek sz\u00e1ma. \u00d6sszess\u00e9g\u00e9ben a fogyaszt\u00f3k n\u00e1lunk gyorsan dolgoznak, ez\u00e9rt a lag \u00e1ltal\u00e1ban 0, de n\u00e9ha lehet egy r\u00f6vid ideig tart\u00f3 cs\u00facs. A Kafka ezt a dobozb\u00f3l tudja, de sz\u00fcks\u00e9ges be\u00e1ll\u00edtani egy intervallumot. <\/p>\n<p>Van egy projekt <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/linkedin\/Burrow\">Burrow<\/a><\/noindex>, amely t\u00f6bb inform\u00e1ci\u00f3t ad a Kafka-r\u00f3l. Egyszer\u0171en az API-n kereszt\u00fcl a consumer-group ad vissza \u00e1llapotot, hogy az adott csoportnak hogy \u00e1ll a dolga. Az OK \u00e9s a Failed mellett ott van a warning is, amib\u0151l megtudhatja, hogy a fogyaszt\u00f3i nem tartanak l\u00e9p\u00e9st a termel\u00e9si temp\u00f3val \u2013 nem tudj\u00e1k elolvasni, ami \u00edr\u00f3dik. A rendszer el\u00e9g okos, k\u00f6nnyen haszn\u00e1lhat\u00f3. <\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/cece8495801e187b155487a802e1a35a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cdgy n\u00e9z ki az API szerint a v\u00e1lasz. Itt a bob-live-fifa csoport, a partition refund.update.v1, \u00e1llapot OK, lag 0 \u2013 az utols\u00f3 v\u00e9gs\u0151 offset ilyen.<\/p>\n<p><img decoding=\"async\" alt=\"A Refund Tool szolg\u00e1ltat\u00e1s fejleszt\u00e9si tapasztalata aszinkron API-val Kafka haszn\u00e1lat\u00e1val\" src=\"\/wp-content\/uploads\/2019\/04\/1538b2ccc390e9b83075f54566f1039b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMonitoroz\u00e1s <strong>updated_at SLA (stuck)<\/strong> M\u00e1r eml\u00edtettem. P\u00e9ld\u00e1ul a term\u00e9k st\u00e1tusza \u00e1tker\u00fclt arra, hogy k\u00e9szen \u00e1ll a visszat\u00e9r\u00edt\u00e9sre. Be\u00e1ll\u00edtunk egy Cron-t, ami azt mondja, hogy ha 5 perc alatt ez az objektum nem ker\u00fclt visszat\u00e9r\u00edt\u00e9sre (a p\u00e9nzt gyorsan visszat\u00e9r\u00edtj\u00fck a fizet\u00e9si rendszereken kereszt\u00fcl), akkor biztos, hogy valami nem m\u0171k\u00f6dik j\u00f3l, \u00e9s ez egy\u00e9rtelm\u0171en egy t\u00e1mogat\u00e1si eset. Ez\u00e9rt egyszer\u0171en haszn\u00e1lunk egy Cron-t, ami olvassa ezeket a dolgokat, \u00e9s ha ezek sz\u00e1ma meghaladja a 0-t, akkor k\u00fcld egy riaszt\u00e1st.<\/p>\n<p><b>\u00d6sszegz\u00e9sk\u00e9ppen az esem\u00e9nyek haszn\u00e1lata k\u00e9nyelmes, amikor<\/b>:<\/p>\n<ul>\n<li>az inform\u00e1ci\u00f3 t\u00f6bb rendszer sz\u00e1m\u00e1ra sz\u00fcks\u00e9ges;<\/li>\n<li>nem fontos a feldolgoz\u00e1s eredm\u00e9nye;<\/li>\n<li>kevesebb esem\u00e9ny van, vagy az esem\u00e9nyek kicsik. <\/li>\n<\/ul>\n<blockquote><p>K\u00e9zenfekv\u0151nek t\u0171nik, hogy a cikknek konkr\u00e9t t\u00e9m\u00e1ja van \u2013 aszinkron API Kafka-ra, de ezzel kapcsolatban azonnal sok mindent szeretn\u00e9k aj\u00e1nlani.<br \/>\nEl\u0151sz\u00f6r is, a k\u00f6vetkez\u0151 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex> nem kell novemberig v\u00e1rni, m\u00e1r \u00e1prilisban lesz a p\u00e9terv\u00e1ri verzi\u00f3ja, \u00e9s j\u00faniusban besz\u00e9l\u00fcnk a nagy terhel\u00e9sekr\u0151l Novoszibirszkben.<br \/>\nM\u00e1sodszor, a jelent\u00e9s szerz\u0151je, Szergej Zaika r\u00e9sze a tud\u00e1smenedzsmenttel foglalkoz\u00f3 \u00faj konferenci\u00e1nk programbizotts\u00e1g\u00e1nak. <noindex><a rel=\"nofollow\" href=\"https:\/\/knowledgeconf.ru\/2019\">KnowledgeConf<\/a><\/noindex>. A konferencia egynapos, \u00e1prilis 26-\u00e1n ker\u00fcl megrendez\u00e9sre, de a program nagyon tartalmas.<br \/>\nTov\u00e1bb\u00e1 m\u00e1jusban lesz <noindex><a rel=\"nofollow\" href=\"https:\/\/phprussia.ru\/2019\">PHP Oroszorsz\u00e1g<\/a><\/noindex> \u00e9s\u00a0<noindex><a rel=\"nofollow\" href=\"https:\/\/ritfest.ru\/2019\">RIT++<\/a><\/noindex> (a DevOpsConf r\u00e9szek\u00e9nt) \u2013 oda m\u00e9g lehet javasolni saj\u00e1t t\u00e9ma aj\u00e1nlatot, tapasztalatokr\u00f3l besz\u00e9lni \u00e9s panaszolni a felmer\u00fclt neh\u00e9zs\u00e9gekre.<\/p><\/blockquote>\n<p>Forr\u00e1s: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/oleg-bunin\/blog\/445424\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044e \u043a\u0430\u043a Lamoda \u0441\u00a0\u043e\u0442\u043b\u0430\u0436\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0438\u00a0\u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434? \u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u0430\u044f: \u043e\u0442\u00a0\u0437\u0430\u043a\u043e\u043d\u043e\u0434\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u00a0\u043f\u0440\u0438\u0441\u0443\u0449\u0435\u0433\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c \u0436\u0435\u043b\u0430\u043d\u0438\u044f \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u043e\u00a0\u044d\u0442\u043e \u0432\u043e\u0432\u0441\u0435 \u043d\u0435\u00a0\u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u00a0\u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u044b\u0433\u043e\u0434\u0443. \u0412\u00a0\u0447\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0432\u043d\u0435\u0434\u0440\u0438\u0442\u044c events-driven API \u043d\u0430\u00a0Kafka, \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442 \u0421\u0435\u0440\u0433\u0435\u0439 \u0417\u0430\u0438\u043a\u0430 (fewald). \u041f\u0440\u043e \u043d\u0430\u0431\u0438\u0442\u044b\u0435 \u0448\u0438\u0448\u043a\u0438 \u0438\u00a0\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0442\u043e\u0436\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22763,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-30778","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044e \u043a\u0430\u043a Lamoda \u0441 \u043e\u0442\u043b\u0430\u0436\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434?\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hu_HU\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u043f\u044b\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Refund Tool \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c API \u043d\u0430 Kafka | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044e \u043a\u0430\u043a Lamoda \u0441 \u043e\u0442\u043b\u0430\u0436\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434?\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:37:23+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:37:23+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47A Refund Tool szolg\u00e1ltat\u00e1s aszinkron API-j\u00e1nak fejleszt\u00e9si tapasztalata Kafka-n | ProHoster","description":"Mi k\u00e9sztethet egy olyan nagy c\u00e9get, mint a Lamoda, amelynek j\u00f3l megalapozott folyamatai \u00e9s tucatnyi \u00f6sszekapcsolt szolg\u00e1ltat\u00e1sa van, arra, hogy jelent\u0151sen megv\u00e1ltoztassa a megk\u00f6zel\u00edt\u00e9st?","canonical_url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hu_HU","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u043f\u044b\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Refund Tool \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c API \u043d\u0430 Kafka | ProHoster","og:description":"\u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044e \u043a\u0430\u043a Lamoda \u0441 \u043e\u0442\u043b\u0430\u0436\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0430\u043c\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434?","og:url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/opyt-razrabotki-servisa-refund-tool-s-asinhronnym-api-na-kafka","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:37:23+00:00","article:modified_time":"2019-10-31T18:37:23+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30778","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 02:58:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:29:56","updated":"2026-01-21 02:58:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/30778","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/comments?post=30778"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/30778\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media\/22763"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media?parent=30778"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/categories?post=30778"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/tags?post=30778"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}