Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Apakah yang boleh memaksa syarikat besar seperti Lamoda, dengan proses yang diperkemas dan berpuluh-puluh perkhidmatan yang saling berkaitan, mengubah pendekatannya dengan ketara? Motivasi boleh berbeza sama sekali: dari perundangan kepada keinginan untuk bereksperimen yang wujud dalam semua pengaturcara.

Tetapi ini tidak bermakna anda tidak boleh mengharapkan faedah tambahan. Sergey Zaika akan memberitahu anda apa sebenarnya yang anda boleh menangi jika anda melaksanakan API dipacu peristiwa pada Kafka (fewald). Terdapat juga pasti akan bercakap tentang gambar besar dan penemuan menarik - percubaan tidak boleh dilakukan tanpa mereka.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Penafian: Artikel ini berdasarkan bahan daripada pertemuan yang diadakan oleh Sergey pada November 2018 di HighLoad++. Pengalaman langsung Lamoda bekerja dengan Kafka menarik pendengar tidak kurang daripada laporan lain dalam jadual. Kami fikir ini adalah contoh terbaik tentang fakta bahawa anda boleh dan harus sentiasa mencari orang yang berfikiran sama, dan penganjur HighLoad++ akan terus cuba mewujudkan suasana yang kondusif untuk perkara ini.

Mengenai proses

Lamoda ialah platform e-dagang besar yang mempunyai pusat hubungan sendiri, perkhidmatan penghantaran (dan banyak ahli gabungan), studio foto, gudang besar, dan semua ini berjalan pada perisiannya sendiri. Terdapat berpuluh-puluh kaedah pembayaran, rakan kongsi b2b yang mungkin menggunakan sebahagian atau semua perkhidmatan ini dan ingin mengetahui maklumat terkini tentang produk mereka. Di samping itu, Lamoda beroperasi di tiga negara selain Persekutuan Rusia dan semuanya berbeza sedikit di sana. Secara keseluruhan, mungkin terdapat lebih daripada seratus cara untuk mengkonfigurasi pesanan baharu, yang mesti diproses dengan cara tersendiri. Semua ini berfungsi dengan bantuan berpuluh-puluh perkhidmatan yang kadang-kadang berkomunikasi dengan cara yang tidak jelas. Terdapat juga sistem pusat yang tanggungjawab utamanya ialah status pesanan. Kami memanggilnya BOB, saya bekerja dengannya.

Alat Bayaran Balik dengan API terdorong peristiwa

Perkataan yang didorong oleh peristiwa agak rumit; sedikit lagi kita akan mentakrifkan dengan lebih terperinci apa yang dimaksudkan dengan ini. Saya akan mulakan dengan konteks di mana kami memutuskan untuk mencuba pendekatan API terdorong peristiwa dalam Kafka.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Di mana-mana kedai, selain tempahan yang pelanggan bayar, ada kalanya kedai tersebut perlu memulangkan wang kerana produk tersebut tidak sesuai dengan pelanggan. Ini adalah proses yang agak singkat: kami menjelaskan maklumat, jika perlu, dan memindahkan wang.

Tetapi pemulangan menjadi lebih rumit disebabkan oleh perubahan dalam perundangan, dan kami terpaksa melaksanakan perkhidmatan mikro yang berasingan untuknya.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Motivasi kami:

  1. Undang-undang FZ-54 - ringkasnya, undang-undang memerlukan pelaporan kepada pejabat cukai tentang setiap transaksi kewangan, sama ada pemulangan atau resit, dalam SLA yang agak singkat dalam beberapa minit. Kami, sebagai syarikat e-dagang, menjalankan banyak operasi. Secara teknikal, ini bermakna tanggungjawab baharu (dan oleh itu perkhidmatan baharu) dan penambahbaikan dalam semua sistem yang terlibat.
  2. BOB berpecah ialah projek dalaman syarikat untuk melepaskan BOB daripada sejumlah besar tanggungjawab bukan teras dan mengurangkan kerumitan keseluruhannya.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Rajah ini menunjukkan sistem Lamoda utama. Sekarang kebanyakannya lebih buruj 5-10 perkhidmatan mikro di sekeliling monolit yang mengecut. Mereka perlahan-lahan berkembang, tetapi kami cuba untuk menjadikannya lebih kecil, kerana menggunakan serpihan yang dipilih di tengah adalah menakutkan - kami tidak boleh membiarkannya jatuh. Kami terpaksa menempah semua pertukaran (anak panah) dan mengambil kira hakikat bahawa mana-mana daripadanya mungkin tidak tersedia.

BOB juga mempunyai banyak pertukaran: sistem pembayaran, sistem penghantaran, sistem pemberitahuan, dll.

Secara teknikalnya BOB ialah:

  • ~150k baris kod + ~100k baris ujian;
  • php7.2 + Zend 1 & Komponen Symfony 3;
  • >100 API & ~50 penyepaduan keluar;
  • 4 negara dengan logik perniagaan mereka sendiri.

Menggunakan BOB adalah mahal dan menyakitkan, jumlah kod dan masalah yang diselesaikannya adalah sedemikian rupa sehingga tiada siapa yang boleh memasukkan semuanya ke dalam kepala mereka. Secara umum, terdapat banyak sebab untuk memudahkannya.

Proses Pemulangan

Pada mulanya, dua sistem terlibat dalam proses: BOB dan Pembayaran. Kini dua lagi muncul:

  • Perkhidmatan Fiskalisasi, yang akan menangani masalah dengan fiskalisasi dan komunikasi dengan perkhidmatan luar.
  • Alat Bayaran Balik, yang hanya mengandungi pertukaran baharu supaya tidak mengembang BOB.

Sekarang prosesnya kelihatan seperti ini:

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

  1. BOB menerima permintaan untuk bayaran balik.
  2. BOB bercakap tentang Alat Bayaran Balik ini.
  3. Alat Bayaran Balik memberitahu Pembayaran: "Kembalikan wang."
  4. Bayaran memulangkan wang.
  5. Alat Bayaran Balik dan BOB menyegerakkan status antara satu sama lain, kerana buat masa ini mereka berdua memerlukannya. Kami belum bersedia untuk beralih sepenuhnya kepada Alat Bayaran Balik, kerana BOB mempunyai UI, laporan untuk perakaunan, dan secara amnya banyak data yang tidak boleh dipindahkan dengan begitu mudah. Anda perlu duduk di atas dua kerusi.
  6. Permintaan untuk fiskalisasi hilang.

Akibatnya, kami membuat sejenis bas acara di Kafka - bas acara, di mana segala-galanya bermula. Hore, sekarang kita mempunyai satu titik kegagalan (sindiran).

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Kebaikan dan keburukan cukup jelas. Kami membuat bas, yang bermaksud bahawa kini semua perkhidmatan bergantung kepadanya. Ini memudahkan reka bentuk, tetapi memperkenalkan satu titik kegagalan ke dalam sistem. Kafka akan ranap, proses akan berhenti.

Apakah itu API terdorong peristiwa

Jawapan yang baik untuk soalan ini adalah dalam laporan oleh Martin Fowler (GOTO 2017) "Banyak Makna Seni Bina Didorong Peristiwa".

Secara ringkas apa yang kami lakukan:

  1. Selesaikan semua pertukaran tak segerak melalui penyimpanan acara. Daripada memaklumkan kepada setiap pengguna yang berminat tentang perubahan status melalui rangkaian, kami menulis acara tentang perubahan status kepada storan terpusat dan pengguna yang berminat dengan topik membaca semua yang muncul dari sana.
  2. Peristiwa dalam kes ini ialah pemberitahuan (pemberitahuan) bahawa sesuatu telah berubah di suatu tempat. Sebagai contoh, status pesanan telah berubah. Pengguna yang berminat dengan beberapa data yang mengiringi perubahan status yang tidak disertakan dalam pemberitahuan boleh mengetahui sendiri statusnya.
  3. Pilihan maksimum ialah penyumberan acara sepenuhnya, pemindahan negeri, dalam acara yang mana mengandungi semua maklumat yang diperlukan untuk pemprosesan: dari mana ia datang dan status apa yang ia pergi, bagaimana sebenarnya data itu berubah, dsb. Satu-satunya persoalan ialah kebolehlaksanaan dan jumlah maklumat yang anda mampu simpan.

Sebagai sebahagian daripada pelancaran Alat Bayaran Balik, kami menggunakan pilihan ketiga. Pemprosesan acara dipermudahkan ini kerana tidak perlu mengekstrak maklumat terperinci, serta menghapuskan senario di mana setiap peristiwa baharu menjana ledakan penjelasan mendapatkan permintaan daripada pengguna.

Perkhidmatan Alat Bayaran Balik tidak dimuatkan, jadi Kafka ada lebih rasa pena daripada keperluan. Saya tidak fikir jika perkhidmatan bayaran balik menjadi projek beban tinggi, perniagaan akan gembira.

Pertukaran Async SEBAGAIMANA ADANYA

Untuk pertukaran tak segerak, jabatan PHP biasanya menggunakan RabbitMQ. Kami mengumpul data untuk permintaan itu, meletakkannya dalam baris gilir, dan pengguna perkhidmatan yang sama membacanya dan menghantarnya (atau tidak menghantarnya). Untuk API itu sendiri, Lamoda secara aktif menggunakan Swagger. Kami mereka bentuk API, menerangkannya dalam Swagger, dan menjana kod pelanggan dan pelayan. Kami juga menggunakan JSON RPC 2.0 yang dipertingkatkan sedikit.

Di sesetengah tempat bas ESB digunakan, sesetengahnya hidup di activeMQ, tetapi, secara umum, RabbitMQ - standard.

Pertukaran Async TO BE

Apabila mereka bentuk pertukaran melalui bas acara, analogi boleh dikesan. Kami juga menerangkan pertukaran data masa hadapan melalui penerangan struktur acara. Format yaml, kami terpaksa melakukan penjanaan kod sendiri, penjana mencipta DTO mengikut spesifikasi dan mengajar pelanggan dan pelayan untuk bekerja dengan mereka. Generasi masuk ke dalam dua bahasa - golang dan php. Ini membantu memastikan perpustakaan konsisten. Penjana itu ditulis dalam golang, sebab itu ia mendapat nama gogi.

Penyumberan acara di Kafka adalah perkara biasa. Terdapat penyelesaian dari versi perusahaan utama Kafka Confluent, ada nakadi, penyelesaian daripada saudara domain kami Zalando. kami motivasi untuk bermula dengan vanilla Kafka - ini bermakna membiarkan penyelesaian itu percuma sehingga kami akhirnya memutuskan sama ada kami akan menggunakannya di mana-mana sahaja, dan juga memberi ruang kepada diri kami sendiri untuk bergerak dan penambahbaikan: kami mahukan sokongan untuk kami JSON RPC 2.0, penjana untuk dua bahasa dan mari kita lihat apa lagi.

Sungguh ironis bahawa walaupun dalam kes yang menggembirakan, apabila terdapat perniagaan yang hampir serupa, Zalando, yang membuat penyelesaian yang hampir serupa, kami tidak dapat menggunakannya dengan berkesan.

Corak seni bina semasa pelancaran adalah seperti berikut: kami membaca terus dari Kafka, tetapi menulis hanya melalui bas acara. Terdapat banyak yang sedia untuk dibaca dalam Kafka: broker, pengimbang, dan ia lebih kurang bersedia untuk penskalaan mendatar, saya ingin menyimpannya. Kami mahu melengkapkan rakaman melalui satu Gateway aka Events-bas, dan inilah sebabnya.

Acara-bas

Atau bas acara. Ini hanyalah gerbang http tanpa negara, yang mengambil beberapa peranan penting:

  • Menghasilkan Pengesahan β€” kami menyemak sama ada acara itu memenuhi spesifikasi kami.
  • Sistem induk acara, iaitu, ini adalah sistem utama dan satu-satunya dalam syarikat yang menjawab persoalan tentang peristiwa yang mana struktur dianggap sah. Pengesahan hanya melibatkan jenis data dan enum untuk menentukan kandungan dengan ketat.
  • Fungsi hash untuk sharding - struktur mesej Kafka ialah nilai kunci dan menggunakan cincangan kunci ia dikira di mana untuk meletakkannya.

Mengapa

Kami bekerja di sebuah syarikat besar dengan proses yang diperkemas. Mengapa mengubah apa-apa? Ini adalah percubaan, dan kami menjangkakan untuk meraih beberapa faedah.

1:n+1 pertukaran (satu kepada banyak)

Kafka menjadikannya sangat mudah untuk menghubungkan pengguna baharu kepada API.

Katakan anda mempunyai direktori yang anda perlukan untuk sentiasa dikemas kini dalam beberapa sistem sekaligus (dan dalam beberapa sistem baharu). Sebelum ini, kami mencipta himpunan yang melaksanakan set-API, dan sistem induk dimaklumkan tentang alamat pengguna. Kini sistem induk menghantar kemas kini kepada topik, dan semua orang yang berminat membacanya. Sistem baharu telah muncul - kami telah mendaftar untuk topik tersebut. Ya, juga berkas, tetapi lebih ringkas.

Dalam kes alat bayaran balik, yang merupakan sebahagian daripada BOB, adalah mudah bagi kami untuk memastikannya disegerakkan melalui Kafka. Pembayaran mengatakan bahawa wang itu telah dipulangkan: BOB, RT mengetahui tentang ini, menukar status mereka, Perkhidmatan Fiskalisasi mengetahui tentang perkara ini dan mengeluarkan cek.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Kami mempunyai rancangan untuk mencipta Perkhidmatan Pemberitahuan bersatu yang akan memberitahu pelanggan tentang berita mengenai pesanan/pemulangannya. Kini tanggungjawab ini tersebar antara sistem. Cukuplah untuk kami mengajar Perkhidmatan Pemberitahuan untuk menangkap maklumat yang berkaitan daripada Kafka dan membalasnya (dan melumpuhkan pemberitahuan ini dalam sistem lain). Tiada pertukaran langsung baharu diperlukan.

Didorong data

Maklumat antara sistem menjadi telus - tidak kira apa "perusahaan berdarah" yang anda miliki dan tidak kira betapa banyaknya tunggakan anda. Lamoda mempunyai jabatan Analitis Data yang mengumpul data daripada sistem dan meletakkannya dalam bentuk yang boleh digunakan semula, untuk perniagaan dan sistem pintar. Kafka membolehkan anda memberi mereka banyak data dengan cepat dan memastikan aliran maklumat itu dikemas kini.

Log replikasi

Mesej tidak hilang selepas dibaca, seperti dalam RabbitMQ. Apabila acara mengandungi maklumat yang mencukupi untuk diproses, kami mempunyai sejarah perubahan terkini pada objek dan, jika dikehendaki, keupayaan untuk menggunakan perubahan ini.

Tempoh penyimpanan log replikasi bergantung pada keamatan menulis topik ini; Kafka membolehkan anda menetapkan had masa penyimpanan dan volum data secara fleksibel. Untuk topik intensif, adalah penting bahawa semua pengguna mempunyai masa untuk membaca maklumat sebelum ia hilang, walaupun dalam kes ketidakupayaan jangka pendek. Ia biasanya mungkin untuk menyimpan data untuk unit hari, yang cukup untuk sokongan.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Seterusnya, sedikit penceritaan semula dokumentasi, bagi mereka yang tidak biasa dengan Kafka (gambar juga dari dokumentasi)

AMQP mempunyai baris gilir: kami menulis mesej ke baris gilir untuk pengguna. Biasanya, satu baris gilir diproses oleh satu sistem dengan logik perniagaan yang sama. Jika anda perlu memberitahu beberapa sistem, anda boleh mengajar aplikasi untuk menulis ke beberapa baris gilir atau mengkonfigurasi pertukaran dengan mekanisme fanout, yang mengklonkannya sendiri.

Kafka mempunyai abstraksi yang serupa topik, di mana anda menulis mesej, tetapi ia tidak hilang selepas membaca. Secara lalai, apabila anda menyambung ke Kafka, anda menerima semua mesej dan mempunyai pilihan untuk menyimpan dari tempat anda berhenti. Iaitu, anda membaca secara berurutan, anda mungkin tidak menandakan mesej sebagai dibaca, tetapi simpan id yang anda boleh teruskan membacanya. Id yang anda selesaikan dipanggil offset, dan mekanisme komit offset.

Sehubungan itu, logik yang berbeza boleh dilaksanakan. Sebagai contoh, kami mempunyai BOB dalam 4 keadaan untuk negara yang berbeza - Lamoda berada di Rusia, Kazakhstan, Ukraine, Belarus. Memandangkan mereka digunakan secara berasingan, mereka mempunyai konfigurasi yang sedikit berbeza dan logik perniagaan mereka sendiri. Kami menunjukkan dalam mesej negara mana yang dirujuk. Setiap pengguna BOB di setiap negara membaca dengan groupId yang berbeza, dan jika mesej itu tidak berkenaan dengan mereka, mereka melangkaunya, i.e. serta-merta melakukan +1 mengimbangi. Jika topik yang sama dibaca oleh Perkhidmatan Pembayaran kami, maka topik itu melakukannya dengan kumpulan yang berasingan, dan oleh itu offset tidak bersilang.

Keperluan acara:

  • Kelengkapan data. Saya ingin acara itu mempunyai data yang mencukupi supaya ia boleh diproses.

  • Integriti. Kami mewakilkan kepada Events-bus pengesahan bahawa acara itu konsisten dan ia boleh memprosesnya.
  • Perintah itu penting. Dalam kes pulangan, kita terpaksa bekerja dengan sejarah. Dengan pemberitahuan, pesanan itu tidak penting, jika ia adalah pemberitahuan homogen, e-mel akan sama tanpa mengira pesanan yang tiba dahulu. Dalam kes bayaran balik, terdapat proses yang jelas; jika kami menukar pesanan, pengecualian akan timbul, bayaran balik tidak akan dibuat atau diproses - kami akan berakhir dalam status yang berbeza.
  • Konsisten. Kami mempunyai kedai, dan kini kami mencipta acara dan bukannya API. Kami memerlukan cara untuk menghantar maklumat dengan cepat dan murah tentang acara baharu dan perubahan kepada yang sedia ada kepada perkhidmatan kami. Ini dicapai melalui spesifikasi biasa dalam repositori git dan penjana kod yang berasingan. Oleh itu, pelanggan dan pelayan dalam perkhidmatan yang berbeza diselaraskan.

Kafka di Lamoda

Kami mempunyai tiga pemasangan Kafka:

  1. Log;
  2. R&D;
  3. Acara-bas.

Hari ini kita hanya bercakap tentang perkara terakhir. Di bas acara, kami tidak mempunyai pemasangan yang sangat besar - 3 broker (pelayan) dan hanya 27 topik. Sebagai peraturan, satu topik adalah satu proses. Tetapi ini adalah perkara yang halus, dan kami akan menyentuhnya sekarang.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Di atas ialah graf rps. Proses bayaran balik ditandakan dengan garis biru (ya, pada paksi X), dan garis merah jambu ialah proses kemas kini kandungan.

Katalog Lamoda mengandungi berjuta-juta produk, dan data dikemas kini sepanjang masa. Sesetengah koleksi ketinggalan zaman, yang baharu dikeluarkan untuk menggantikannya, dan model baharu sentiasa muncul dalam katalog. Kami cuba meramalkan perkara yang menarik kepada pelanggan kami esok, jadi kami sentiasa membeli perkara baharu, mengambil gambar dan mengemas kini kotak paparan.

Puncak merah jambu ialah kemas kini produk, iaitu perubahan dalam produk. Ia boleh dilihat bahawa lelaki itu mengambil gambar, mengambil gambar, dan kemudian sekali lagi! β€” memuatkan pek acara.

Kes penggunaan Lamoda Events

Kami menggunakan seni bina yang dibina untuk operasi berikut:

  • Penjejakan status kembali: seruan tindak dan penjejakan status daripada semua sistem yang terlibat. Pembayaran, status, fiskalisasi, pemberitahuan. Di sini kami menguji pendekatan, membuat alatan, mengumpul semua pepijat, menulis dokumentasi dan memberitahu rakan sekerja kami cara menggunakannya.
  • Mengemas kini kad produk: konfigurasi, meta-data, ciri. Satu sistem membaca (yang memaparkan), dan beberapa menulis.
  • E-mel, tolak dan sms: order dah kumpul, order dah sampai, pulangan dah terima, dan lain-lain lagi banyak.
  • Stok, pembaharuan gudang β€” kemas kini kuantitatif item, hanya nombor: ketibaan di gudang, kembali. Semua sistem yang berkaitan dengan tempahan barangan perlu beroperasi dengan data terkini. Pada masa ini, sistem kemas kini stok agak rumit; Kafka akan memudahkannya.
  • Analisis Data (jabatan R&D), alat ML, analitik, statistik. Kami mahu maklumat menjadi telus - Kafka sangat sesuai untuk ini.

Kini bahagian yang lebih menarik tentang lebam besar dan penemuan menarik yang telah berlaku sejak enam bulan lalu.

Masalah reka bentuk

Katakan kita ingin melakukan perkara baharu - contohnya, pindahkan keseluruhan proses penghantaran ke Kafka. Kini sebahagian daripada proses itu dilaksanakan dalam Pemprosesan Pesanan dalam BOB. Terdapat model status di sebalik pemindahan pesanan ke perkhidmatan penghantaran, pergerakan ke gudang perantaraan, dan sebagainya. Terdapat keseluruhan monolit, malah dua, serta sekumpulan API khusus untuk penghantaran. Mereka tahu lebih banyak tentang penghantaran.

Ini kelihatan seperti kawasan yang serupa, tetapi Pemprosesan Pesanan dalam BOB dan Sistem Penghantaran mempunyai status yang berbeza. Sebagai contoh, sesetengah perkhidmatan kurier tidak menghantar status perantaraan, tetapi hanya yang terakhir: "dihantar" atau "hilang". Yang lain, sebaliknya, melaporkan dengan terperinci tentang pergerakan barang. Setiap orang mempunyai peraturan pengesahan mereka sendiri: bagi sesetengah orang, e-mel itu sah, yang bermaksud ia akan diproses; untuk yang lain tidak sah, tetapi pesanan tetap akan diproses kerana ada nombor telefon untuk dihubungi, dan seseorang akan mengatakan bahawa pesanan sedemikian tidak akan diproses sama sekali.

Aliran data

Dalam kes Kafka, persoalan mengatur aliran data timbul. Tugas ini melibatkan pemilihan strategi berdasarkan beberapa perkara; mari kita lalui semuanya.

Dalam satu topik atau dalam topik yang berbeza?

Kami mempunyai spesifikasi acara. Dalam BOB kami menulis bahawa pesanan itu dan itu perlu dihantar, dan menunjukkan: nombor pesanan, komposisinya, beberapa SKU dan kod bar, dsb. Apabila barang tiba di gudang, penghantaran akan dapat menerima status, cap masa dan semua yang diperlukan. Tetapi kemudian kami mahu menerima kemas kini tentang data ini dalam BOB. Kami mempunyai proses terbalik untuk menerima data daripada penghantaran. Adakah ini acara yang sama? Atau adakah ini pertukaran berasingan yang layak untuk topiknya sendiri?

Kemungkinan besar, mereka akan sangat serupa, dan godaan untuk membuat satu topik bukanlah tidak berasas, kerana topik yang berasingan bermakna pengguna yang berasingan, konfigurasi yang berasingan, generasi yang berasingan dari semua ini. Tetapi bukan fakta.

Medan baharu atau acara baharu?

Tetapi jika anda menggunakan acara yang sama, maka masalah lain timbul. Sebagai contoh, tidak semua sistem penghantaran boleh menjana jenis DTO yang boleh dihasilkan oleh BOB. Kami menghantar id kepada mereka, tetapi mereka tidak menyimpannya kerana mereka tidak memerlukannya, dan dari sudut pandangan memulakan proses bas acara, medan ini diperlukan.

Jika kami memperkenalkan peraturan untuk bas acara bahawa medan ini diperlukan, maka kami terpaksa menetapkan peraturan pengesahan tambahan dalam BOB atau dalam pengendali acara mula. Pengesahan mula tersebar di seluruh perkhidmatan - ini tidak begitu mudah.

Masalah lain ialah godaan untuk pembangunan tambahan. Kami diberitahu bahawa sesuatu perlu ditambah pada acara itu, dan mungkin, jika kita memikirkannya, ia sepatutnya menjadi acara yang berasingan. Tetapi dalam skema kami, acara yang berasingan adalah topik yang berasingan. Topik yang berasingan ialah keseluruhan proses yang saya terangkan di atas. Pembangun tergoda untuk hanya menambah medan lain pada skema JSON dan menjananya semula.

Dalam kes bayaran balik, kami tiba di acara acara dalam setengah tahun. Kami mempunyai satu peristiwa meta yang dipanggil kemas kini bayaran balik, yang mempunyai medan jenis yang menerangkan tentang kemas kini ini sebenarnya. Oleh sebab itu, kami mempunyai suis "hebat" dengan pengesah yang memberitahu kami cara untuk mengesahkan acara ini dengan jenis ini.

Versi acara

Untuk mengesahkan mesej dalam Kafka anda boleh gunakan Avro, tetapi perlu segera meletakkannya dan menggunakan Confluent. Dalam kes kita, kita perlu berhati-hati dengan versi. Ia tidak semestinya boleh membaca semula mesej daripada log replikasi kerana model telah "kiri". Pada asasnya, ternyata membina versi supaya model itu serasi ke belakang: sebagai contoh, jadikan medan pilihan buat sementara waktu. Jika perbezaan terlalu kuat, kami mula menulis dalam topik baharu, dan memindahkan pelanggan apabila mereka selesai membaca topik lama.

Terjamin susunan bacaan partition

Topik di dalam Kafka dibahagikan kepada partition. Ini tidak begitu penting semasa kami mereka bentuk entiti dan pertukaran, tetapi ia penting apabila memutuskan cara untuk menggunakan dan menskalakannya.

Dalam kes biasa, anda menulis satu topik dalam Kafka. Secara lalai, satu partition digunakan dan semua mesej dalam topik ini pergi kepadanya. Dan seterusnya pengguna membaca mesej ini secara berurutan. Katakan sekarang kita perlu mengembangkan sistem supaya mesej dibaca oleh dua pengguna yang berbeza. Jika, sebagai contoh, anda menghantar SMS, maka anda boleh memberitahu Kafka untuk membuat partition tambahan, dan Kafka akan mula membahagikan mesej kepada dua bahagian - separuh di sini, separuh di sini.

Bagaimanakah Kafka membahagikan mereka? Setiap mesej mempunyai badan (di mana kami menyimpan JSON) dan kunci. Anda boleh melampirkan fungsi cincang pada kekunci ini, yang akan menentukan partition mana mesej akan masuk.

Dalam kes kami dengan bayaran balik, ini penting, jika kami mengambil dua partition, maka ada kemungkinan pengguna selari akan memproses acara kedua sebelum yang pertama dan akan ada masalah. Fungsi cincang memastikan bahawa mesej dengan kunci yang sama berakhir dalam partition yang sama.

Peristiwa vs arahan

Ini adalah satu lagi masalah yang kami hadapi. Acara ialah acara tertentu: kami mengatakan bahawa sesuatu telah berlaku di suatu tempat (something_happened), contohnya, item telah dibatalkan atau bayaran balik berlaku. Jika seseorang mendengar acara ini, maka menurut "item dibatalkan", entiti bayaran balik akan dibuat dan "bayaran balik berlaku" akan ditulis di suatu tempat dalam persediaan.

Tetapi biasanya, apabila anda mereka bentuk acara, anda tidak mahu menulisnya dengan sia-sia - anda bergantung pada fakta bahawa seseorang akan membacanya. Terdapat godaan yang tinggi untuk menulis bukan sesuatu yang telah berlaku (item_canceled, refund_refunded), tetapi sesuatu yang_harus_be_done. Contohnya, barang sedia untuk dipulangkan.

Di satu pihak, ia mencadangkan bagaimana acara itu akan digunakan. Sebaliknya, ia lebih kurang seperti nama acara biasa. Selain itu, ia tidak jauh dari sini ke arahan do_something. Tetapi anda tidak mempunyai jaminan bahawa seseorang membaca acara ini; dan jika anda membacanya, maka anda berjaya membacanya; dan jika anda membacanya dengan jayanya, maka anda melakukan sesuatu, dan sesuatu itu berjaya. Apabila sesuatu peristiwa menjadi sesuatu, maklum balas menjadi perlu, dan itu adalah masalah.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Dalam pertukaran asynchronous dalam RabbitMQ, apabila anda membaca mesej, pergi ke http, anda mempunyai respons - sekurang-kurangnya bahawa mesej telah diterima. Apabila anda menulis kepada Kafka, terdapat mesej yang anda tulis kepada Kafka, tetapi anda tidak tahu apa-apa tentang cara ia diproses.

Oleh itu, dalam kes kami, kami perlu memperkenalkan acara respons dan menyediakan pemantauan supaya jika begitu banyak acara dihantar, selepas sekian dan sekian, bilangan acara respons yang sama akan tiba. Jika ini tidak berlaku, maka ada sesuatu yang tidak kena. Sebagai contoh, jika kami menghantar acara "item_ready_to_refund", kami menjangkakan bahawa bayaran balik akan dibuat, wang akan dikembalikan kepada pelanggan dan acara "money_refunded" akan dihantar kepada kami. Tetapi ini tidak pasti, jadi pemantauan diperlukan.

Nuansa

Terdapat masalah yang agak jelas: jika anda membaca dari topik secara berurutan, dan anda mempunyai beberapa mesej yang tidak baik, pengguna akan jatuh, dan anda tidak akan pergi lebih jauh. Awak perlu hentikan semua pengguna, komit mengimbangi lagi untuk meneruskan pembacaan.

Kami tahu mengenainya, kami mengharapkannya, namun ia berlaku. Dan ini berlaku kerana acara itu sah dari sudut pandangan acara-bas, acara itu sah dari sudut pandangan validator aplikasi, tetapi ia tidak sah dari sudut pandangan PostgreSQL, kerana dalam sistem MySQL kami dengan UNSIGNED INT sistem mempunyai PostgreSQL hanya dengan INT. Saiznya lebih kecil sedikit, dan Id tidak muat. Symfony meninggal dunia dengan pengecualian. Kami, sudah tentu, menangkap pengecualian kerana kami bergantung padanya, dan akan melakukan offset ini, tetapi sebelum itu kami ingin menambah pembilang masalah, kerana mesej diproses tidak berjaya. Kaunter dalam projek ini juga berada dalam pangkalan data, dan Symfony telah menutup komunikasi dengan pangkalan data, dan pengecualian kedua membunuh keseluruhan proses tanpa peluang untuk melakukan offset.

Perkhidmatan itu berbaring untuk beberapa waktu - mujurlah, dengan Kafka ini tidak begitu buruk, kerana mesej kekal. Apabila kerja dipulihkan, anda boleh menghabiskan membacanya. Ia selesa.

Kafka mempunyai keupayaan untuk menetapkan offset sewenang-wenangnya melalui perkakas. Tetapi untuk melakukan ini, anda perlu menghentikan semua pengguna - dalam kes kami, sediakan keluaran berasingan di mana tidak akan ada pengguna, penempatan semula. Kemudian dalam Kafka anda boleh mengalihkan offset melalui perkakas, dan mesej akan diteruskan.

Satu lagi nuansa - log replikasi lwn rdkafka.so - adalah berkaitan dengan spesifik projek kami. Kami menggunakan PHP, dan dalam PHP, sebagai peraturan, semua perpustakaan berkomunikasi dengan Kafka melalui repositori rdkafka.so, dan kemudian terdapat beberapa jenis pembungkus. Mungkin ini adalah kesukaran peribadi kita, tetapi ternyata membaca semula secebis daripada apa yang telah kita baca tidak begitu mudah. Secara umum, terdapat masalah perisian.

Kembali kepada spesifik bekerja dengan partition, ia ditulis betul-betul dalam dokumentasi pengguna >= pembahagian topik. Tetapi saya mengetahui perkara ini lebih lewat daripada yang saya mahukan. Jika anda ingin membuat skala dan mempunyai dua pengguna, anda memerlukan sekurang-kurangnya dua partition. Iaitu, jika anda mempunyai satu partition di mana 20 ribu mesej telah terkumpul, dan anda membuat yang baru, bilangan mesej tidak akan disamakan tidak lama lagi. Oleh itu, untuk mempunyai dua pengguna selari, anda perlu berurusan dengan partition.

Pemantauan

Saya rasa cara kita memantau ia akan menjadi lebih jelas lagi apa masalah yang ada dalam pendekatan sedia ada.

Sebagai contoh, kami mengira berapa banyak produk dalam pangkalan data yang telah menukar statusnya baru-baru ini, dan, oleh itu, peristiwa sepatutnya berlaku berdasarkan perubahan ini, dan kami menghantar nombor ini ke sistem pemantauan kami. Kemudian dari Kafka kita dapat nombor kedua, berapa banyak peristiwa yang sebenarnya direkodkan. Jelas sekali, perbezaan antara kedua-dua nombor ini hendaklah sentiasa sifar.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Di samping itu, anda perlu memantau prestasi pengeluar, sama ada acara-bas menerima mesej, dan cara pengguna melakukannya. Contohnya, dalam carta di bawah, Alat Bayaran Balik berfungsi dengan baik, tetapi BOB jelas mempunyai beberapa masalah (puncak biru).

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Saya telah menyebut ketinggalan kumpulan pengguna. Secara kasarnya, ini ialah bilangan mesej yang belum dibaca. Secara amnya, pengguna kami bekerja dengan cepat, jadi lag biasanya 0, tetapi kadangkala terdapat kemuncak jangka pendek. Kafka boleh melakukan ini di luar kotak, tetapi anda perlu menetapkan selang waktu tertentu.

Ada projek Burrowyang akan memberi anda lebih banyak maklumat tentang Kafka. Ia hanya menggunakan API kumpulan pengguna untuk memberikan status tentang prestasi kumpulan ini. Selain OK dan Gagal, terdapat amaran, dan anda boleh mengetahui bahawa pengguna anda tidak dapat mengatasi kadar pengeluaran - mereka tidak mempunyai masa untuk membaca pruf apa yang ditulis. Sistem ini agak pintar dan mudah digunakan.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Inilah rupa tindak balas API. Berikut ialah kumpulan bob-live-fifa, partition refund.update.v1, status OK, lag 0 - offset akhir terakhir ini dan ini.

Pengalaman dalam membangunkan perkhidmatan Alat Bayaran Balik dengan API tak segerak pada Kafka

Pemantauan updated_at SLA (terperangkap) saya sudah sebutkan. Contohnya, produk telah bertukar kepada status sedia untuk dipulangkan. Kami memasang Cron, yang mengatakan bahawa jika objek ini tidak dibayar balik dalam masa 5 minit (kami memulangkan wang melalui sistem pembayaran dengan cepat), maka sesuatu pasti berlaku, dan ini pastinya merupakan kes untuk sokongan. Oleh itu, kami hanya mengambil Cron, yang membaca perkara sedemikian, dan jika ia lebih besar daripada 0, maka ia menghantar amaran.

Untuk meringkaskan, menggunakan acara adalah mudah apabila:

  • maklumat diperlukan oleh beberapa sistem;
  • hasil pemprosesan tidak penting;
  • terdapat beberapa peristiwa atau peristiwa kecil.

Nampaknya artikel itu mempunyai topik yang sangat khusus - API tak segerak pada Kafka, tetapi berkaitan dengannya saya ingin mengesyorkan banyak perkara sekaligus.
Pertama, seterusnya HighLoad ++ kita perlu menunggu sehingga November, pada bulan April akan ada versi St. Petersburg, dan pada bulan Jun kita akan bercakap tentang beban tinggi di Novosibirsk.
Kedua, pengarang laporan, Sergei Zaika, adalah ahli Jawatankuasa Program persidangan baharu kami mengenai pengurusan pengetahuan KnowledgeConf. Persidangan itu satu hari, akan berlangsung pada 26 April, tetapi programnya sangat sengit.
Dan ia akan berlaku pada bulan Mei PHP Rusia ΠΈ RIT++ (dengan disertakan DevOpsConf) - anda juga boleh mencadangkan topik anda di sana, bercakap tentang pengalaman anda dan mengadu tentang kon sumbat anda.

Sumber: www.habr.com

Tambah komen