Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Үйл явц нь оновчтой, харилцан уялдаатай олон арван үйлчилгээтэй Ламода шиг ийм том компанийг арга барилаа эрс өөрчлөхөд юу түлхэж чадах вэ? Урам зориг нь огт өөр байж болно: хууль тогтоомжоос эхлээд бүх програмистуудад байдаг туршилт хийх хүсэл.

Гэхдээ энэ нь нэмэлт тэтгэмжид найдаж болохгүй гэсэн үг биш юм. Хэрэв та Кафка дээр үйл явдалд суурилсан API-г хэрэгжүүлбэл яг юу хожих боломжтойг Сергей Зайка танд хэлэх болно (цөөхөн). Том зураг авалт, сонирхолтой нээлтүүдийн тухай ярих нь гарцаагүй - туршилт түүнгүйгээр хийх боломжгүй юм.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Анхааруулга: Энэ нийтлэл нь Сергейгийн 2018 оны XNUMX-р сард HighLoad++ дээр хийсэн уулзалтын материал дээр үндэслэсэн болно. Ламодагийн Кафкатай ажиллаж байсан амьд туршлага нь бусад хуваарийн тайлангаас дутахааргүй сонсогчдыг татав. Энэ бол та үргэлж ижил сэтгэлгээтэй хүмүүсийг олж чадна, мөн байх ёстой байдгийн гайхалтай жишээ бөгөөд HighLoad++-ийн зохион байгуулагчид үүнд таатай уур амьсгалыг бий болгохыг хичээсээр байх болно гэж бид бодож байна.

Үйл явцын талаар

Ламода бол өөрийн холбоо барих төв, хүргэлтийн үйлчилгээ (мөн олон салбартай), гэрэл зургийн студи, асар том агуулахтай, энэ бүхэн өөрийн программ хангамж дээр ажилладаг томоохон цахим худалдааны платформ юм. Эдгээр үйлчилгээний заримыг эсвэл бүгдийг нь ашиглаж болох, бүтээгдэхүүнийхээ хамгийн сүүлийн үеийн мэдээллийг мэдэхийг хүсдэг олон арван төлбөрийн аргууд, b2b түншүүд байдаг. Нэмж дурдахад Ламода нь ОХУ-аас гадна гурван улсад үйл ажиллагаа явуулдаг бөгөөд тэнд бүх зүйл арай өөр байдаг. Нийтдээ шинэ захиалгыг тохируулах зуу гаруй арга зам байж магадгүй бөгөөд үүнийг өөрийн гэсэн аргаар боловсруулах ёстой. Энэ бүхэн заримдаа тодорхой бус байдлаар харилцдаг олон арван үйлчилгээний тусламжтайгаар ажилладаг. Мөн захиалгын статусыг хариуцдаг төвлөрсөн систем байдаг. Бид түүнийг BOB гэж дууддаг, би түүнтэй ажилладаг.

Үйл явдалд тулгуурласан API бүхий буцаан олгох хэрэгсэл

Үйл явдалд тулгуурласан гэдэг үг нь нэлээд хачирхалтай бөгөөд энэ нь юу гэсэн үг болохыг бид жаахан цааш нь илүү нарийвчлан тодорхойлох болно. Би Кафка дахь үйл явдалд тулгуурласан API хандлагыг туршиж үзэхээр шийдсэн контекстээс эхлэх болно.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Аль ч дэлгүүрт үйлчлүүлэгчид төлбөр төлдөг захиалгаас гадна тухайн бүтээгдэхүүн нь үйлчлүүлэгчид тохирохгүй байсан тул мөнгөө буцааж өгөхийг шаарддаг тохиолдол байдаг. Энэ нь харьцангуй богино үйл явц юм: шаардлагатай бол бид мэдээллийг тодруулж, мөнгөө шилжүүлдэг.

Гэвч хууль тогтоомжийн өөрчлөлтөөс болж буцаах нь илүү төвөгтэй болж, бид тусдаа бичил үйлчилгээ хэрэгжүүлэх шаардлагатай болсон.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Бидний урам зориг:

  1. FZ-54 хууль - Товчхондоо, хуулийн дагуу татварын албанд буцаан олголт, баримт гэх мэт мөнгөний гүйлгээ бүрийг хэдхэн минутын дотор тайлагнаж байхыг шаарддаг. Бид цахим худалдааны компанийн хувьд нэлээд олон үйл ажиллагаа явуулдаг. Техникийн хувьд энэ нь шинэ үүрэг хариуцлага (тиймээс шинэ үйлчилгээ) болон холбогдох бүх системийг сайжруулах гэсэн үг юм.
  2. BOB хуваагдсан нь BOB-ийг олон тооны үндсэн бус үүрэг хариуцлагаас чөлөөлж, ерөнхий нарийн төвөгтэй байдлыг багасгах компанийн дотоод төсөл юм.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Энэ диаграмм нь үндсэн Lamoda системийг харуулж байна. Одоо тэдний ихэнх нь илүү болсон багасч буй цул орчмын 5-10 микро үйлчилгээний одны. Тэд аажмаар өсч байгаа ч бид тэдгээрийг жижиг болгохыг хичээж байна, учир нь дунд хэсэгт сонгосон фрагментийг байрлуулах нь аймшигтай - бид үүнийг унахыг зөвшөөрөхгүй. Бид бүх солилцоог (сум) нөөцлөхөөс өөр аргагүй болж байгаа бөгөөд тэдгээрийн аль нэг нь боломжгүй болж болзошгүйг харгалзан үздэг.

BOB нь маш олон солилцоотой: төлбөрийн систем, хүргэх систем, мэдэгдлийн систем гэх мэт.

Техникийн хувьд BOB нь:

  • ~150к мөр код + ~100к мөр тест;
  • php7.2 + Zend 1 & Symfony бүрэлдэхүүн хэсгүүд 3;
  • >100 API & ~50 гадагш чиглэсэн интеграцчилал;
  • Өөрийн гэсэн бизнесийн логиктой 4 улс.

BOB-г байршуулах нь үнэтэй бөгөөд зовлонтой бөгөөд үүнийг шийддэг код, асуудлын хэмжээ нь хэн ч үүнийг бүгдийг нь толгойдоо оруулж чадахгүй. Ерөнхийдөө үүнийг хялбарчлах олон шалтгаан бий.

Буцах үйл явц

Эхний ээлжинд BOB болон Payment гэсэн хоёр систем үйл явцад оролцдог. Одоо дахиад хоёр гарч ирнэ:

  • Санхүүжилттэй холбоотой асуудлуудыг шийдвэрлэх, гадаад үйлчилгээтэй харилцах үйлчилгээ.
  • Буцаан олголтын хэрэгсэл нь BOB-ийг өсгөхгүйн тулд шинэ солилцоог агуулдаг.

Одоо процесс дараах байдлаар харагдаж байна.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

  1. BOB нь буцаан олгох хүсэлтийг хүлээн авдаг.
  2. BOB энэ буцаан олгох хэрэгслийн талаар ярьдаг.
  3. Буцаан олголтын хэрэгсэл нь төлбөрт: "Мөнгө буцааж өг" гэж хэлдэг.
  4. Төлбөр нь мөнгийг буцааж өгдөг.
  5. Буцаан олголтын хэрэгсэл болон BOB нь статусыг бие биетэйгээ синхрончилдог, учир нь одоохондоо хоёуланд нь хэрэгтэй байна. BOB нь хэрэглэгчийн интерфэйстэй, нягтлан бодох бүртгэлд зориулсан тайлангууд, ерөнхийдөө амархан шилжүүлэх боломжгүй маш олон өгөгдөлтэй тул бид буцаан олгох хэрэгсэл рүү бүрэн шилжихэд хараахан бэлэн болоогүй байна. Та хоёр сандал дээр суух хэрэгтэй.
  6. Санхүүжилт хийх хүсэлт алга болно.

Үүний үр дүнд бид Кафка дээр бүх зүйл эхэлсэн үйл явдлын автобусны нэг төрөл болсон. Хөөе, одоо бидэнд бүтэлгүйтлийн ганц цэг байна (шолох).

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Давуу болон сул тал нь маш ойлгомжтой. Бид автобус хийсэн нь одоо бүх үйлчилгээ үүнээс хамаардаг гэсэн үг юм. Энэ нь дизайныг хялбарчлах боловч системд алдаа дутагдлын нэг цэгийг нэвтрүүлдэг. Кафка сүйрнэ, процесс зогсоно.

Үйл явдалд тулгуурласан API гэж юу вэ

Энэ асуултын сайн хариулт нь Мартин Фаулерын илтгэлд байдаг (GOTO 2017) "Үйл явдалд тулгуурласан архитектурын олон утга учир".

Бидний хийсэн зүйлийг товч дурдвал:

  1. Бүх асинхрон солилцоог дамжуулан дуусга үйл явдлын хадгалалт. Сүлжээгээр дамжуулан статусын өөрчлөлтийн талаар сонирхсон хэрэглэгч бүрт мэдэгдэхийн оронд бид статусын өөрчлөлтийн тухай үйл явдлыг төвлөрсөн хадгалах санд бичиж, тухайн сэдвийг сонирхож буй хэрэглэгчид тэндээс гарч буй бүх зүйлийг уншдаг.
  2. Энэ тохиолдолд үйл явдал нь мэдэгдэл юм (мэдэгдэл) ямар нэг зүйл хаа нэгтээ өөрчлөгдсөн. Жишээлбэл, захиалгын статус өөрчлөгдсөн. Мэдэгдэлд ороогүй статусын өөрчлөлттэй холбоотой зарим өгөгдлийг сонирхож буй хэрэглэгч түүний статусыг өөрөө олж мэдэх боломжтой.
  3. Хамгийн дээд сонголт бол үйл явдлын бүрэн эх үүсвэр юм. улсын шилжүүлэг, ямар тохиолдолд боловсруулахад шаардлагатай бүх мэдээллийг агуулна: энэ нь хаанаас ирсэн, ямар статустай болсон, өгөгдөл яг хэрхэн өөрчлөгдсөн гэх мэт. Ганц асуулт бол таны хадгалах боломж, мэдээллийн хэмжээ юм.

Буцаан олголтын хэрэгслийг эхлүүлэх хүрээнд бид гурав дахь сонголтыг ашигласан. Нарийвчилсан мэдээлэл авах шаардлагагүй тул үйл явдлын боловсруулалтыг хялбаршуулсан бөгөөд шинэ үйл явдал бүр хэрэглэгчдээс тодруулах хүсэлтийг бий болгодог хувилбарыг арилгасан.

Буцаан олголтын хэрэгслийн үйлчилгээ ачаалагдаагүй, тиймээс Кафкад хэрэгцээ гэхээсээ илүү үзэгний амт байдаг. Хэрэв буцаан олголтын үйлчилгээ нь ачаалал ихтэй төсөл болсон бол бизнес аз жаргалтай байх болно гэж би бодохгүй байна.

Асинхронгуй солилцоо

Асинхрон солилцооны хувьд РНР хэлтэс ихэвчлэн RabbitMQ ашигладаг. Бид хүсэлтийн өгөгдлийг цуглуулж, дараалалд оруулсан бөгөөд ижил үйлчилгээний хэрэглэгч үүнийг уншиж, илгээсэн (эсвэл илгээгээгүй). API өөрөө Lamoda Swagger-ийг идэвхтэй ашигладаг. Бид API боловсруулж, Swagger дээр тайлбарлаж, үйлчлүүлэгч болон серверийн кодыг үүсгэдэг. Бид мөн бага зэрэг сайжруулсан JSON RPC 2.0 ашигладаг.

Зарим газар ESB автобус ашигладаг, зарим нь activeMQ дээр амьдардаг, гэхдээ ерөнхийдөө RabbitMQ - стандарт.

Асинхронгуй солилцоо TO BE

Үйл явдлын автобусаар дамжуулан солилцоог зохион бүтээхдээ аналогийг ажиглаж болно. Бид үйл явдлын бүтцийн тайлбараар дамжуулан ирээдүйн мэдээлэл солилцохыг мөн адил дүрсэлдэг. Yaml форматын хувьд бид код үүсгэх ажлыг өөрсдөө хийх ёстой байсан бөгөөд генератор нь техникийн нөхцлийн дагуу DTO-г үүсгэж, үйлчлүүлэгчид болон серверүүдтэй ажиллахыг заадаг. Үе үе хоёр хэлээр дамждаг - голанг болон php. Энэ нь номын санг тогтвортой байлгахад тусалдаг. Генератор нь голанг хэл дээр бичигдсэн тул гоги гэж нэрлэсэн.

Кафка дээр үйл явдал хайх нь ердийн зүйл юм. Kafka Confluent-ийн үндсэн аж ахуйн нэгжийн хувилбараас шийдэл байдаг накади, манай домайн ах Заландогийн шийдэл. Манай ваниль Кафкагаар эхлэх сэдэл - Энэ нь бид үүнийг хаа сайгүй ашиглах эсэхээ эцэслэн шийдэх хүртэл шийдлийг чөлөөтэй үлдээхээс гадна өөрсдөдөө маневр хийх, сайжруулах зай үлдээнэ гэсэн үг: бид өөрсдийнхөө төлөө дэмжлэг хүсч байна. JSON RPC 2.0, хоёр хэлний генераторууд ба өөр юу болохыг харцгаая.

Ойролцоогоор ижил төстэй шийдлийг гаргасан Заландо гэсэн ийм аз жаргалтай тохиолдолд ч бид үүнийг үр дүнтэй ашиглаж чадахгүй байгаа нь хачирхалтай юм.

Эхлэх үеийн архитектурын загвар нь дараах байдалтай байна: бид Кафкагаас шууд уншдаг, гэхдээ зөвхөн үйл явдлуудын автобусаар бичдэг. Кафка дээр уншихад бэлэн маш их зүйл бий: брокерууд, тэнцвэржүүлэгчид, мөн энэ нь хэвтээ масштаблахад бэлэн байгаа тул би үүнийг хадгалахыг хүссэн. Бид нэг Gateway буюу Events-автобусаар дамжуулан бичлэгээ дуусгахыг хүссэн бөгөөд яагаад гэдгийг эндээс харж болно.

Үйл явдал - автобус

Эсвэл арга хэмжээний автобус. Энэ бол зүгээр л харьяалалгүй http гарц бөгөөд хэд хэдэн чухал үүрэг гүйцэтгэдэг:

  • Баталгаажуулалт хийх - бид үйл явдлууд нь бидний техникийн шаардлагад нийцэж байгаа эсэхийг шалгадаг.
  • Үйл явдлын мастер систем, өөрөөр хэлбэл, энэ нь ямар үйл явдал ямар бүтэц хүчинтэй гэж тооцогддог вэ гэсэн асуултанд хариулдаг компанийн гол бөгөөд цорын ганц систем юм. Баталгаажуулалт нь агуулгыг хатуу зааж өгөхийн тулд өгөгдлийн төрөл, тоололыг агуулдаг.
  • Хэш функц sharding-ийн хувьд - Кафка мессежийн бүтэц нь түлхүүр-утга бөгөөд түлхүүрийн хэшийг ашиглан хаана байрлуулахаа тооцоолно.

яагаад

Бид үйл явц нь хялбарчилсан томоохон компанид ажилладаг. Яагаад ямар нэг зүйлийг өөрчлөх вэ? Энэ бол туршилт юм, мөн бид хэд хэдэн үр өгөөжийг хүртэнэ гэж найдаж байна.

1:n+1 солилцоо (нэгээс олон)

Кафка нь шинэ хэрэглэгчдийг API-д холбоход маш хялбар болгодог.

Танд нэгэн зэрэг хэд хэдэн системд (мөн зарим шинэ системд) шинэчлэгдэх лавлах байгаа гэж бодъё. Өмнө нь бид set-API-г хэрэгжүүлсэн багцыг зохион бүтээсэн бөгөөд мастер системд хэрэглэгчийн хаягийг мэдээлдэг байсан. Одоо мастер систем нь сэдвийн шинэчлэлтүүдийг илгээдэг бөгөөд сонирхсон хүн бүр үүнийг уншдаг. Шинэ систем гарч ирэв - бид энэ сэдвээр бүртгүүлсэн. Тийм, бас багц, гэхдээ илүү хялбар.

BOB-ийн нэг хэсэг болох буцаан олгох хэрэгслийн хувьд тэдгээрийг Кафкагаар дамжуулан синхрончлох нь бидэнд тохиромжтой. Төлбөр нь мөнгийг буцааж өгсөн гэж хэлсэн: BOB, RT энэ талаар олж мэдээд статусаа өөрчилсөн, Санхүүжилтийн алба үүнийг олж мэдээд чек гаргасан.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Бид үйлчлүүлэгчид захиалга/буцаах мэдээний талаар мэдээлэх нэгдсэн мэдэгдлийн үйлчилгээг бий болгохоор төлөвлөж байна. Одоо энэ хариуцлага нь системүүдийн хооронд тархсан. Кафкагаас холбогдох мэдээллийг авч, түүнд хариу өгөхийг мэдэгдлийн үйлчилгээнд заах нь бидэнд хангалттай байх болно (мөн бусад системд эдгээр мэдэгдлийг идэвхгүй болгох). Шинэ шууд солилцоо хийх шаардлагагүй.

Өгөгдөлд тулгуурласан

Систем хоорондын мэдээлэл ил тод болдог - танд ямар ч "цуст аж ахуйн нэгж" байгаа эсэхээс үл хамааран, таны хоцрогдол хэр их байсан ч хамаагүй. Lamoda нь системээс өгөгдөл цуглуулж, бизнес болон ухаалаг системд зориулж дахин ашиглах боломжтой хэлбэрт оруулдаг Өгөгдлийн аналитик хэлтэстэй. Кафка танд маш их өгөгдлийг хурдан өгч, мэдээллийн урсгалыг шинэчлэн байлгах боломжийг олгодог.

Хуулбарлах бүртгэл

RabbitMQ-д байдаг шиг уншсаны дараа мессеж алга болдоггүй. Үйл явдал боловсруулахад хангалттай мэдээлэл агуулж байвал бид тухайн объектын сүүлийн үеийн өөрчлөлтүүдийн түүхтэй бөгөөд хэрэв хүсвэл эдгээр өөрчлөлтийг хэрэгжүүлэх боломжтой болно.

Хуулбарлах бүртгэлийн хадгалалтын хугацаа нь энэ сэдвийг бичих эрчмээс хамаарна; Кафка нь хадгалах хугацаа болон өгөгдлийн хэмжээг уян хатан байдлаар тохируулах боломжийг олгодог. Эрчимтэй сэдвүүдийн хувьд богино хугацаанд ажиллах боломжгүй байсан ч бүх хэрэглэгчид мэдээлэл алга болохоос нь өмнө унших цагтай байх нь чухал юм. Энэ нь ихэвчлэн өгөгдөл хадгалах боломжтой байдаг өдрийн нэгж, энэ нь дэмжлэг үзүүлэхэд хангалттай юм.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Дараа нь Кафкаг сайн мэдэхгүй хүмүүст зориулж баримт бичгийн талаар бага зэрэг тайлагнасан болно (зураг мөн баримтаас авсан болно)

AMQP нь дараалалтай: бид хэрэглэгчийн дараалалд мессеж бичдэг. Ихэвчлэн нэг дарааллыг ижил бизнесийн логиктой нэг систем боловсруулдаг. Хэрэв та хэд хэдэн системд мэдэгдэх шаардлагатай бол програмыг хэд хэдэн дараалалд бичихийг зааж өгөх эсвэл тэдгээрийг өөрөө хувилдаг fanout механизмаар солилцоог тохируулах боломжтой.

Кафка ч мөн адил хийсвэр ойлголттой сэдэв, та мессеж бичдэг боловч уншсаны дараа алга болдоггүй. Анхдагч байдлаар, та Кафкатай холбогдох үед бүх мессежийг хүлээн авах ба зогссон газраа хадгалах боломжтой. Өөрөөр хэлбэл, та дараалсан уншсан, та мессежийг уншсан гэж тэмдэглэхгүй байж болно, гэхдээ дараа нь үргэлжлүүлэн унших боломжтой ID-г хадгалаарай. Таны тогтсон Id-г офсет гэж нэрлэдэг ба механизмыг commit offset гэж нэрлэдэг.

Үүний дагуу янз бүрийн логикийг хэрэгжүүлж болно. Жишээлбэл, бид өөр өөр улс оронд 4 тохиолдолд BOB-тэй байдаг - Ламода нь Орос, Казахстан, Украин, Беларусь улсад байдаг. Тэдгээрийг тусад нь байрлуулсан тул тэдгээр нь арай өөр тохиргоотой, өөрийн бизнесийн логиктой. Энэ нь аль улсад хамаарахыг бид зурваст зааж өгсөн болно. Улс бүрийн BOB хэрэглэгч бүр өөр groupId-ээр уншдаг бөгөөд хэрэв мессеж тэдэнд хамаарахгүй бол тэд үүнийг алгасах, өөрөөр хэлбэл. нэн даруй +1 офсет хийнэ. Хэрэв ижил сэдвийг манай Төлбөрийн үйлчилгээ уншдаг бол үүнийг тусдаа бүлэгт хийдэг тул офсетууд огтлолцохгүй.

Үйл явдлын шаардлага:

  • Өгөгдлийн бүрэн байдал. Би үйл явдал хангалттай мэдээлэлтэй байгаа тул үүнийг боловсруулах боломжтой байхыг хүсч байна.

  • Шударга байдал Бид Events-bus-д тухайн үйл явдал нийцэж байгаа бөгөөд үүнийг боловсруулах боломжтой эсэхийг баталгаажуулах эрхийг шилжүүлдэг.
  • Захиалга чухал. Эргэж ирсэн тохиолдолд бид түүхтэй ажиллахаас өөр аргагүй болдог. Мэдэгдэлтэй бол захиалга нь чухал биш, хэрэв тэдгээр нь нэгэн төрлийн мэдэгдлүүд байвал аль захиалга эхэлж ирсэнээс үл хамааран имэйл нь ижил байх болно. Буцаан олголтын хувьд тодорхой үйл явц байдаг; хэрэв бид дарааллыг өөрчилвөл үл хамаарах зүйлүүд гарч ирэх бөгөөд буцаан олголтыг үүсгэх эсвэл боловсруулахгүй - бид өөр статустай болно.
  • Тууштай байдал. Бид дэлгүүртэй бөгөөд одоо API-ийн оронд үйл явдлуудыг үүсгэж байна. Бидэнд шинэ үйл явдал, одоо байгаа өөрчлөлтүүдийн талаарх мэдээллийг хурдан бөгөөд хямдаар үйлчилгээндээ дамжуулах арга хэрэгтэй байна. Үүнийг тусдаа git репозитор болон кодын үүсгэгч дэх нийтлэг тодорхойлолтоор хангадаг. Тиймээс өөр өөр үйлчилгээн дэх үйлчлүүлэгч, серверүүд хоорондоо уялдаа холбоотой байдаг.

Ламод дахь Кафка

Бидэнд гурван Кафка суулгац бий:

  1. Бүртгэл;
  2. R&D;
  3. Үйл явдал - автобус.

Өнөөдөр бид зөвхөн сүүлчийн зүйлийн талаар ярьж байна. Үйл явдал-автобус дээр бид маш том суурилуулалттай байдаггүй - 3 брокер (сервер), зөвхөн 27 сэдэв. Дүрмээр бол нэг сэдэв нь нэг үйл явц юм. Гэхдээ энэ бол нарийн зүйл бөгөөд бид одоо үүнийг хөндөх болно.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Дээрх нь rps график юм. Буцаан олголтын үйл явцыг оюу шугамаар (тиймээ, X тэнхлэг дээрх) тэмдэглэсэн бөгөөд ягаан шугам нь контентыг шинэчлэх үйл явц юм.

Lamoda каталог нь сая сая бүтээгдэхүүнийг агуулдаг бөгөөд өгөгдөл нь байнга шинэчлэгддэг. Зарим цуглуулга моодноос гарч, тэдгээрийг орлох шинэ загварууд гарч, шинэ загварууд каталогид байнга гарч ирдэг. Бид маргааш үйлчлүүлэгчдэдээ юу сонирхолтой байхыг урьдчилан таамаглахыг хичээдэг тул бид байнга шинэ зүйл худалдаж авч, зургийг нь авч, дэлгэцийн гэрийг шинэчилдэг.

Ягаан оргилууд нь бүтээгдэхүүний шинэчлэлт, өөрөөр хэлбэл бүтээгдэхүүний өөрчлөлт юм. Залуус зургаа авхуулж, зургаа авхуулж, дараа нь дахин харж болно! - үйл явдлын багцыг ачааллаа.

Lamoda Events ашиглах тохиолдол

Бид бүтээгдсэн архитектурыг дараах үйлдлүүдэд ашигладаг.

  • Буцах төлөвийг хянах: холбогдох бүх системээс үйлдэлд уриалж, статусыг хянах. Төлбөр, статус, санхүүжүүлэх, мэдэгдэл. Энд бид арга барилыг туршиж, багаж хэрэгсэл хийж, бүх алдааг цуглуулж, баримт бичгийг бичиж, хамтран ажиллагсаддаа үүнийг хэрхэн ашиглахыг хэлсэн.
  • Бүтээгдэхүүний картуудыг шинэчлэх: тохиргоо, мета өгөгдөл, шинж чанар. Нэг систем уншдаг (харуулдаг), хэд хэдэн бичдэг.
  • Имэйл, түлхэх, SMS: захиалга авсан, захиалга ирсэн, буцаах хүлээн авсан гэх мэт маш олон байдаг.
  • Хувьцаа, агуулахын шинэчлэл - зүйлийн тоон шинэчлэл, зүгээр л тоо: агуулахад ирэх, буцах. Барааг нөөцлөхтэй холбоотой бүх систем нь хамгийн сүүлийн үеийн өгөгдөлтэй ажиллах шаардлагатай. Одоогийн байдлаар хувьцааны шинэчлэлтийн систем нь нэлээд төвөгтэй бөгөөд Кафка үүнийг хялбарчлах болно.
  • Мэдээллийн дүн шинжилгээ хийх (R&D хэлтэс), ML хэрэгсэл, аналитик, статистик. Бид мэдээлэл ил тод байхыг хүсч байна - Кафка үүнд маш тохиромжтой.

Одоо сүүлийн зургаан сарын хугацаанд болсон том овойлт, сонирхолтой нээлтүүдийн тухай илүү сонирхолтой хэсэг.

Дизайн асуудал

Бид шинэ зүйл хийхийг хүсч байна гэж бодъё - жишээлбэл, бүх хүргэх үйл явцыг Кафка руу шилжүүлэх. Одоо үйл явцын нэг хэсэг нь BOB дахь Захиалга боловсруулахад хэрэгжиж байна. Захиалгыг хүргэлтийн үйлчилгээнд шилжүүлэх, завсрын агуулах руу шилжүүлэх гэх мэт статусын загвар байдаг. Бүхэл бүтэн цул, бүр хоёр, дээр нь хүргэхэд зориулагдсан олон API байдаг. Тэд хүргэлтийн талаар илүү ихийг мэддэг.

Эдгээр нь ижил төстэй газар мэт боловч BOB дахь Захиалга боловсруулах болон Тээвэрлэлтийн систем нь өөр өөр статустай байдаг. Жишээлбэл, зарим шуудангийн үйлчилгээ нь завсрын статусыг илгээдэггүй, харин зөвхөн эцсийн статусыг илгээдэг: "хүргэгдсэн" эсвэл "алдагдсан". Бусад нь, эсрэгээр, барааны хөдөлгөөний талаар маш нарийн мэдээлдэг. Хүн бүр өөрийн гэсэн баталгаажуулалтын дүрэмтэй байдаг: зарим хүмүүсийн хувьд имэйл хүчинтэй, энэ нь түүнийг боловсруулах болно гэсэн үг юм; бусдын хувьд энэ нь хүчинтэй биш боловч холбогдох утасны дугаар байгаа тул захиалгыг боловсруулах болно, хэн нэгэн ийм захиалгыг огт боловсруулахгүй гэж хэлэх болно.

Өгөгдлийн урсгал

Кафкагийн хувьд өгөгдлийн урсгалыг зохион байгуулах тухай асуудал гарч ирдэг. Энэ даалгавар нь хэд хэдэн цэг дээр суурилсан стратеги сонгох явдал бөгөөд бүгдийг нь авч үзье.

Нэг сэдвээр үү эсвэл өөр сэдвээр үү?

Бидэнд үйл явдлын тодорхойлолт бий. BOB дээр бид ийм захиалгыг хүргэх шаардлагатай гэж бичээд: захиалгын дугаар, түүний найрлага, зарим SKU, зураасан код гэх мэтийг зааж өгнө. Бараа агуулахад ирэхэд хүргэлт нь статус, цагийн тэмдэг, шаардлагатай бүх зүйлийг хүлээн авах боломжтой болно. Гэхдээ дараа нь бид BOB дээрх энэ өгөгдлийн шинэчлэлтийг хүлээн авахыг хүсч байна. Бид хүргэлтээс өгөгдөл хүлээн авах урвуу үйл явцтай. Энэ ижил үйл явдал мөн үү? Эсвэл энэ нь өөрийн гэсэн сэдэвтэй байх ёстой тусдаа солилцоо мөн үү?

Тэд маш төстэй байх магадлалтай бөгөөд нэг сэдэв гаргах уруу таталт нь үндэслэлгүй биш юм, учир нь тусдаа сэдэв нь тусдаа хэрэглэгчид, тусдаа тохиргоо, энэ бүхний тусдаа үе гэсэн үг юм. Гэхдээ баримт биш.

Шинэ талбар эсвэл шинэ арга хэмжээ?

Гэхдээ хэрэв та ижил үйл явдлуудыг ашиглавал өөр асуудал гарч ирнэ. Жишээлбэл, бүх хүргэх системүүд BOB-ийн үүсгэж болох DTO-г үүсгэж чадахгүй. Бид тэдэнд ID-г илгээдэг, гэхдээ тэд үүнийг хадгалахгүй, учир нь энэ нь шаардлагагүй бөгөөд үйл явдлын автобусны процессыг эхлүүлэх үүднээс энэ талбар шаардлагатай.

Хэрэв бид үйл явдлын автобусанд энэ талбар шаардлагатай гэсэн дүрмийг оруулбал бид BOB эсвэл эхлэх үйл явдал зохицуулагч дээр нэмэлт баталгаажуулалтын дүрмийг тохируулахаас өөр аргагүй болно. Баталгаажуулалт нь үйлчилгээний даяар тархаж эхэлдэг - энэ нь тийм ч тохиромжтой биш юм.

Өөр нэг асуудал бол өсөн нэмэгдэж буй хөгжилд уруу таталт юм. Энэ үйл явдалд ямар нэг зүйл нэмж оруулах хэрэгтэй гэж хэлдэг, магадгүй энэ талаар бодох юм бол тусдаа арга хэмжээ байх ёстой байсан. Гэхдээ манай схемд тусдаа үйл явдал нь тусдаа сэдэв юм. Тусдаа сэдэв бол миний дээр дурдсан бүх үйл явц юм. Хөгжүүлэгч нь JSON схемд өөр талбар нэмж, түүнийг дахин үүсгэхийг хүсдэг.

Буцаан олголтын хувьд бид хагас жилийн хугацаанд үйл явдлын үеэр ирсэн. Бидэнд буцаан олголтын шинэчлэл гэж нэрлэгддэг нэг мета үйл явдал байсан бөгөөд энэ шинэчлэлт нь үнэндээ юу болохыг тайлбарласан төрлийн талбартай байв. Үүнээс болж бид баталгаажуулагчтай "гайхалтай" унтраалгатай байсан бөгөөд энэ төрлийн үйл явдлыг хэрхэн баталгаажуулахыг бидэнд хэлсэн.

Үйл явдлын хувилбар

Кафка дахь мессежийг баталгаажуулахын тулд та ашиглаж болно Авро Ар-, гэхдээ нэн даруй үүн дээр хэвтэж, Confluent ашиглах шаардлагатай байв. Манай тохиолдолд хувилбар гаргахдаа болгоомжтой хандах хэрэгтэй. Загвар "зүүн" байгаа тул хуулбарлах бүртгэлээс мессежийг дахин унших боломжгүй. Үндсэндээ энэ нь загвар нь хоцрогдсон нийцтэй байхын тулд хувилбаруудыг бүтээх болж байна: жишээлбэл талбарыг түр хугацаагаар нэмэлт болгох. Хэрэв ялгаа нь хэтэрхий хүчтэй байвал бид шинэ сэдвээр бичиж эхэлдэг бөгөөд хуучин сэдвийг уншиж дууссаны дараа үйлчлүүлэгчээ шилжүүлдэг.

Хуваалтын баталгаатай унших дараалал

Кафка доторх сэдвүүд нь хуваалтуудад хуваагддаг. Энэ нь бид аж ахуйн нэгж, биржүүдийг төлөвлөхдөө тийм ч чухал биш боловч үүнийг хэрхэн ашиглах, өргөжүүлэх талаар шийдэхэд чухал юм.

Ердийн тохиолдолд та Кафка дээр нэг сэдэв бичдэг. Анхдагч байдлаар, нэг хуваалтыг ашигладаг бөгөөд энэ сэдэв дэх бүх мессежүүд түүн рүү очдог. Хэрэглэгч эдгээр мессежийг дараалан уншдаг. Мессежийг хоёр өөр хэрэглэгч уншихын тулд системийг өргөжүүлэх хэрэгтэй гэж үзье. Жишээлбэл, хэрэв та SMS илгээж байгаа бол Кафкад нэмэлт хуваалт хийхийг хэлэх боломжтой бөгөөд Кафка мессежийг хоёр хэсэгт хувааж эхэлнэ - хагас нь энд, хагас нь энд.

Кафка тэднийг хэрхэн хуваадаг вэ? Мессеж бүр бие (бид JSON хадгалдаг) болон түлхүүртэй. Та энэ товчлуурт хэш функцийг хавсаргаж болох бөгөөд энэ нь мессеж аль хэсэгт орохыг тодорхойлох болно.

Буцаан олголтын хувьд бидний хувьд энэ нь чухал бөгөөд хэрэв бид хоёр хуваалт авбал зэрэгцээ хэрэглэгч хоёр дахь үйл явдлыг эхнийхээс өмнө боловсруулж, асуудал гарах магадлалтай. Хэш функц нь ижил түлхүүртэй мессежүүд ижил хуваалтад дуусахыг баталгаажуулдаг.

Үйл явдал ба командууд

Энэ бол бидний тулгарсан өөр нэг асуудал юм. Үйл явдал бол тодорхой үйл явдал юм: бид хаа нэгтээ ямар нэг зүйл болсон гэж хэлдэг (ямар нэгэн зүйл болсон), жишээлбэл, бараа цуцлагдсан эсвэл буцаан олголт хийгдсэн. Хэрэв хэн нэгэн эдгээр үйл явдлыг сонсвол "зүйл цуцлагдсан"-ын дагуу буцаан олголтын байгууллага үүсч, тохиргооны хаа нэгтээ "буцаан олголтын" гэж бичнэ.

Гэхдээ ихэвчлэн үйл явдлуудыг зохион бүтээхдээ та тэдгээрийг дэмий хоосон бичихийг хүсдэггүй - хэн нэгэн тэднийг унших болно гэдэгт найдаж байна. Ямар нэг зүйл болсон (цуцлагдсан, буцаан олгогдлоо) биш, харин ямар нэг зүйл хийх ёстой гэж бичих хүсэл их байдаг. Жишээлбэл, бараа буцаахад бэлэн байна.

Энэ нь нэг талаас үйл явдлыг хэрхэн ашиглахыг санал болгодог. Нөгөөтэйгүүр, энэ нь ердийн үйл явдлын нэр шиг бага сонсогддог. Үүнээс гадна, эндээс do_something команд хүртэл холгүй байна. Гэхдээ хэн нэгэн энэ үйл явдлыг уншсан гэсэн баталгаа танд байхгүй; мөн хэрэв та үүнийг уншвал амжилттай уншсан; Хэрэв та үүнийг амжилттай уншсан бол та ямар нэг зүйл хийсэн, тэр зүйл амжилттай болсон. Аливаа үйл явдал ямар нэг зүйл болж хувирах мөчид санал хүсэлт шаардлагатай болж, энэ нь асуудал юм.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

RabbitMQ дахь асинхрон солилцооны үед та мессежийг уншихдаа http руу очно уу, танд хариу байна - наад зах нь мессеж хүлээн авсан. Чамайг Кафка руу бичихэд Кафка руу бичсэн гэсэн мессеж байдаг ч яаж боловсруулсныг мэдэхгүй.

Тиймээс манайд хариу арга хэмжээ нэвтрүүлж, ийм олон арга хэмжээ явуулсан бол ийм ийм хугацааны дараа тэр тооны хариу арга хэмжээ ирэх ёстой гэж хяналт тавих ёстой байсан. Хэрэв ийм зүйл болохгүй бол ямар нэг зүйл буруу болсон бололтой. Жишээлбэл, хэрэв бид "буцаан олгоход_бэлэн" арга хэмжээг илгээсэн бол буцаан олголт үүсэж, мөнгөө үйлчлүүлэгчид буцааж өгч, "мөнг_буцаан олгох" арга хэмжээ бидэнд илгээгдэнэ гэж найдаж байна. Гэхдээ энэ нь тодорхой биш байгаа тул хяналт тавих шаардлагатай байна.

Нэр томъёо

Маш тодорхой асуудал бий: хэрэв та сэдвээс дараалан уншиж, танд муу мэдээ байгаа бол хэрэглэгч унаж, цааш явахгүй. Чамд хэрэгтэй бүх хэрэглэгчдийг зогсоох, цааш үргэлжлүүлэн уншихын тулд офсет хийнэ үү.

Бид энэ талаар мэдэж байсан, найдаж байсан ч ийм зүйл болсон. Үйл явдал нь үйл явдал-автобусны үүднээс, үйл явдал нь програмын баталгаажуулагчийн үүднээс хүчинтэй байсан ч PostgreSQL-ийн үүднээс энэ нь хүчин төгөлдөр бус байсан тул энэ нь болсон, учир нь манай нэг системд байдаг. UNSIGNED INT-тэй MySQL, шинээр бичигдсэн системд зөвхөн INT-тэй PostgreSQL-тэй байсан. Түүний хэмжээ арай бага, Id нь тохирохгүй байна. Симфони үл хамаарах зүйлээр нас баржээ. Мэдээжийн хэрэг, бид үүн дээр тулгуурлаж, энэ офсетийг хийх гэж байсан тул үл хамаарах зүйлийг барьж авсан, гэхдээ үүнээс өмнө мессежийг амжилттай боловсруулж чадаагүй тул асуудлын тоолуурыг нэмэгдүүлэхийг хүссэн. Энэ төслийн тоолуурууд мөн мэдээллийн санд байгаа бөгөөд Symfony нь мэдээллийн сантай харилцах харилцааг аль хэдийн хаасан бөгөөд хоёр дахь үл хамаарах зүйл нь офсет хийх боломжгүйгээр бүх процессыг устгасан.

Үйлчилгээ хэсэг хугацаанд зогссон - аз болоход, Кафкагийн хувьд энэ нь тийм ч муу биш, учир нь мессежүүд хэвээр байна. Ажил сэргээгдэх үед та тэдгээрийг уншиж дуусгаж болно. Энэ нь тухтай.

Кафка багаж хэрэгслээр дамжуулан дурын офсет тогтоох чадвартай. Гэхдээ үүнийг хийхийн тулд та бүх хэрэглэгчдийг зогсоох хэрэгтэй - манай тохиолдолд хэрэглэгч, дахин байршуулалт байхгүй тусдаа хувилбар бэлтгэх хэрэгтэй. Дараа нь Кафка дээр та багаж хэрэгслээр дамжуулан офсетийг шилжүүлэх боломжтой бөгөөд мессеж дамжих болно.

Өөр нэг нюанс - хуулбарлах бүртгэл vs rdkafka.so - манай төслийн онцлогтой холбоотой. Бид РНР ашигладаг ба PHP-д дүрмээр бол бүх номын сан Кафкатай rdkafka.so репозитороор холбогдож, дараа нь ямар нэг төрлийн боодол байдаг. Магадгүй эдгээр нь бидний хувийн бэрхшээл байж болох ч уншсан зүйлийнхээ хэсгийг дахин унших нь тийм ч амар биш болох нь тогтоогдсон. Ерөнхийдөө програм хангамжийн асуудал байсан.

Хуваалтуудтай ажиллах онцлог руу буцахдаа үүнийг баримт бичигт шууд бичсэн болно хэрэглэгчид >= сэдвийн хуваалтууд. Гэхдээ би энэ талаар бодож байснаас хамаагүй хожуу мэдсэн. Хэрэв та томруулж, хоёр хэрэглэгчтэй болохыг хүсч байвал дор хаяж хоёр хуваалт хэрэгтэй. Өөрөөр хэлбэл, хэрэв танд 20 мянган мессеж хуримтлагдсан нэг хуваалт байсан бөгөөд та шинээр хийсэн бол мессежийн тоог удахгүй тэнцүүлэхгүй. Тиймээс хоёр зэрэгцээ хэрэглэгчтэй болохын тулд хуваалтуудтай ажиллах хэрэгтэй.

Хяналт шинжилгээ

Үүнийг хянах арга барил нь одоо байгаа арга барилд ямар асуудал байгаа нь илүү тодорхой болно гэж би бодож байна.

Жишээлбэл, бид мэдээллийн санд байгаа хэчнээн бүтээгдэхүүн сүүлийн үед статусаа өөрчилсөн, үүний дагуу эдгээр өөрчлөлтөд үндэслэн үйл явдал тохиолдох ёстойг тооцоолж, энэ дугаарыг хяналтын системдээ илгээдэг. Дараа нь Кафкагаас бид хоёр дахь дугаарыг авдаг, яг хэдэн үйл явдал бүртгэгдсэн бэ. Мэдээжийн хэрэг, эдгээр хоёр тооны ялгаа үргэлж тэг байх ёстой.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Нэмж дурдахад та үйлдвэрлэгч хэрхэн ажиллаж байгаа, үйл явдал-автобус мессеж хүлээн авсан эсэх, хэрэглэгч хэрхэн ажиллаж байгааг хянах хэрэгтэй. Жишээлбэл, доорх диаграммд Буцаан олголтын хэрэгсэл сайн ажиллаж байгаа ч BOB-д зарим асуудал байгаа нь тодорхой байна (цэнхэр оргилууд).

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Хэрэглэгчийн бүлгийн хоцрогдол гэж би аль хэдийн дурдсан. Ойролцоогоор энэ бол уншаагүй мессежийн тоо юм. Ер нь манай хэрэглэгчид хурдан ажилладаг болохоор хоцрогдол нь ихэвчлэн 0 байдаг ч заримдаа богино хугацааны оргил үе ч байж болно. Кафка үүнийг хайрцагнаас гаргаж чадна, гэхдээ та тодорхой интервал тохируулах хэрэгтэй.

Төсөл байгаа БуррооЭнэ нь танд Кафкагийн талаар илүү их мэдээлэл өгөх болно. Энэ нь зүгээр л хэрэглэгчийн бүлгийн API-г ашиглан энэ бүлгийн үйл ажиллагааны статусыг өгдөг. OK, Failed-ээс гадна анхааруулга байдаг бөгөөд таны хэрэглэгчид үйлдвэрлэлийн хурдыг даван туулж чадахгүй байгааг олж мэдэх боломжтой - тэдэнд бичсэн зүйлийг засах цаг байхгүй. Систем нь нэлээд ухаалаг бөгөөд хэрэглэхэд хялбар юм.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

API хариулт нь иймэрхүү харагдаж байна. Энд бүлэг bob-live-fifa, partition refund.update.v1, статус OK, хоцрогдол 0 - сүүлийн эцсийн офсет ийм, ийм.

Кафка дээрх асинхрон API бүхий Refund Tool үйлчилгээг хөгжүүлж байсан туршлагатай

Хяналт шинжилгээ SLA-д шинэчлэгдсэн (гацсан) Би аль хэдийн дурдсан. Жишээлбэл, бүтээгдэхүүн нь буцаахад бэлэн гэсэн статустай болсон. Бид Cron-ийг суулгасан бөгөөд хэрэв 5 минутын дотор энэ объект буцаан олгоогүй бол (бид төлбөрийн системээр дамжуулан мөнгөө маш хурдан буцааж өгдөг) ямар нэг зүйл буруу болсон бөгөөд энэ нь мэдээжийн хэрэг дэмжлэг үзүүлэх явдал юм. Тиймээс бид ийм зүйлийг уншдаг Cron-ийг зүгээр л авч, хэрэв 0-ээс их байвал энэ нь анхааруулга илгээдэг.

Дүгнэж хэлэхэд, үйл явдлыг ашиглах нь тохиромжтой үед:

  • мэдээлэл хэд хэдэн системд шаардлагатай;
  • боловсруулалтын үр дүн чухал биш;
  • цөөхөн үйл явдал эсвэл жижиг үйл явдал байдаг.

Энэ нийтлэлд Кафка дээрх асинхрон API гэсэн маш тодорхой сэдэв байгаа юм шиг санагдаж байна, гэхдээ үүнтэй холбогдуулан би олон зүйлийг нэг дор санал болгохыг хүсч байна.
Эхлээд, дараа нь Өндөр ачаалал ++ Бид XNUMX-р сар хүртэл хүлээх хэрэгтэй, XNUMX-р сард Санкт-Петербургийн хувилбар гарах бөгөөд XNUMX-р сард бид Новосибирск хотод их ачааллын талаар ярих болно.
Хоёрдугаарт, илтгэлийн зохиогч Сергей Зайка бол манай мэдлэгийн менежментийн шинэ бага хурлын хөтөлбөрийн хорооны гишүүн юм. KnowledgeConf. Чуулган нэг өдрийн хугацаатай, дөрөвдүгээр сарын 26-нд болох ч хөтөлбөр нь маш эрчимтэй.
Тэгээд тавдугаар сард болно PHP Орос и RIT++ (DevOpsConf багтсан) - та мөн тэнд сэдвээ санал болгож, туршлагаа ярьж, чихмэл боргоцойгоо гомдоллож болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх