Pola arsitektur sing trep

Hey Habr!

Amarga kedadeyan saiki amarga koronavirus, sawetara layanan Internet wis wiwit nampa beban sing tambah. Tuladhane, Salah sawijining rantai ritel Inggris mung mandhegake situs pesenan online., amarga ana ora cukup kapasitas. Lan ora mesthi bisa nyepetake server kanthi mung nambah peralatan sing luwih kuat, nanging panjaluk klien kudu diproses (utawa bakal menyang pesaing).

Ing artikel iki, aku bakal ngomong babagan praktik populer sing bakal ngidini sampeyan nggawe layanan sing cepet lan tahan kesalahan. Nanging, saka rencana pangembangan sing bisa ditindakake, aku mung milih sing saiki gampang kanggo nggunakake. Kanggo saben item, sampeyan duwe perpustakaan sing wis siap, utawa sampeyan duwe kesempatan kanggo ngatasi masalah kasebut kanthi nggunakake platform awan.

Skala horisontal

Titik paling gampang lan paling kondhang. Secara konvensional, rong skema distribusi beban sing paling umum yaiku skala horisontal lan vertikal. Ing kasus kapisan sampeyan ngidini layanan kanggo mbukak ing podo karo, mangkono nyebarake mbukak antarane wong-wong mau. Ing kaloro sampeyan supaya server luwih kuat utawa ngoptimalake kode.

Contone, aku bakal njupuk panyimpenan file awan abstrak, yaiku, sawetara analog saka OwnCloud, OneDrive, lan liya-liyane.

Gambar standar sirkuit kasebut ing ngisor iki, nanging mung nuduhake kerumitan sistem kasebut. Sawise kabeh, kita kudu nyinkronake layanan kasebut. Apa sing kedadeyan yen pangguna nyimpen file saka tablet banjur pengin ndeleng saka telpon?

Pola arsitektur sing trep
Bentenipun ing antarane pendekatan: ing skala vertikal, kita siyap nambah kekuwatan simpul, lan ing skala horisontal, kita siap nambah simpul anyar kanggo nyebarake beban.

CQRS

Pamisahan Tanggung Jawab Query Command Pola sing rada penting, amarga ngidini klien sing beda ora mung nyambung menyang layanan sing beda-beda, nanging uga bisa nampa aliran acara sing padha. Mupangat kasebut ora jelas kanggo aplikasi sing gampang, nanging penting banget (lan prasaja) kanggo layanan sing sibuk. Intine: aliran data mlebu lan metu kudu ora intersect. Tegese, sampeyan ora bisa ngirim panjalukan lan ngarep-arep respon; tinimbang, sampeyan ngirim panjalukan menyang layanan A, nanging nampa respon saka layanan B.

Bonus pisanan saka pendekatan iki yaiku kemampuan kanggo break sambungan (ing pangertèn sing wiyar saka tembung) nalika nglakokaké request dawa. Contone, ayo njupuk urutan sing luwih utawa kurang standar:

  1. Klien ngirim panjaluk menyang server.
  2. Server miwiti wektu pangolahan sing dawa.
  3. Server nanggapi klien kanthi asil.

Ayo mbayangno yen ing titik 2 sambungan kasebut rusak (utawa jaringan disambungake maneh, utawa pangguna menyang kaca liya, ngilangi sambungan kasebut). Ing kasus iki, server bakal angel ngirim tanggapan menyang pangguna kanthi informasi babagan apa sing diproses. Nggunakake CQRS, urutane bakal rada beda:

  1. Klien wis langganan nganyari.
  2. Klien ngirim panjaluk menyang server.
  3. Server mangsuli "panyuwunan ditampa."
  4. Server nanggapi kanthi asil liwat saluran saka titik "1".

Pola arsitektur sing trep

Kaya sing sampeyan ngerteni, skema kasebut rada rumit. Kajaba iku, pendekatan panjalukan-respon intuisi ora ana ing kene. Nanging, kaya sing sampeyan ngerteni, pemutus sambungan nalika ngolah panjaluk ora bakal nyebabake kesalahan. Menapa malih, yen nyatane pangguna disambungake menyang layanan saka sawetara piranti (contone, saka telpon seluler lan saka tablet), sampeyan bisa nggawe manawa respon teka menyang piranti loro-lorone.

Sing nggumunake, kode kanggo ngolah pesen sing mlebu dadi padha (ora 100%) kanggo acara sing dipengaruhi dening klien dhewe, lan kanggo acara liyane, kalebu saka klien liyane.

Nanging, ing kasunyatan, kita entuk bonus tambahan amarga kasunyatane aliran unidirectional bisa ditangani kanthi gaya fungsional (nggunakake RX lan padha). Lan iki wis dadi plus serius, amarga ing intine aplikasi bisa rampung reaktif, lan uga nggunakake pendekatan fungsi. Kanggo program lemak, iki bisa ngirit sumber daya pangembangan lan dhukungan.

Yen kita gabungke pendekatan iki karo skala horisontal, banjur minangka bonus, kita entuk kemampuan kanggo ngirim panjalukan menyang server siji lan nampa respon saka liyane. Mangkono, klien bisa milih layanan sing trep kanggo dheweke, lan sistem ing njero isih bisa ngolah acara kanthi bener.

Sumber Acara

Kaya sing sampeyan ngerteni, salah sawijining fitur utama sistem sing disebarake yaiku ora ana wektu umum, bagean kritis umum. Kanggo siji proses, sampeyan bisa nindakake sinkronisasi (ing mutex sing padha), sing sampeyan yakin ora ana wong liya sing nglakokake kode iki. Nanging, iki mbebayani kanggo sistem sing disebarake, amarga bakal mbutuhake nduwur sirah, lan uga bakal mateni kabeh kaendahan skala - kabeh komponen isih bakal ngenteni siji.

Saka kene kita entuk kasunyatan sing penting - sistem distribusi cepet ora bisa disinkronake, amarga banjur bakal nyuda kinerja. Ing tangan liyane, kita asring mbutuhake konsistensi tartamtu antarane komponen. Lan kanggo iki sampeyan bisa nggunakake pendekatan karo konsistensi pungkasanipun, sing dijamin yen ora ana owah-owahan data kanggo sawetara wektu sawise nganyari pungkasan ("pungkasane"), kabeh pitakon bakal ngasilake nilai sing dianyari pungkasan.

Penting kanggo ngerti manawa kanggo database klasik asring digunakake konsistensi kuwat, ing ngendi saben simpul nduweni informasi sing padha (iki asring digayuh yen transaksi kasebut dianggep mung sawise server kapindho nanggapi). Ana sawetara relaksasi ing kene amarga tingkat isolasi, nanging ide umum tetep padha - sampeyan bisa urip ing jagad sing harmonis.

Nanging, ayo bali menyang tugas asli. Yen bagéan saka sistem bisa dibangun karo konsistensi pungkasanipun, banjur kita bisa mbangun diagram ing ngisor iki.

Pola arsitektur sing trep

Fitur penting saka pendekatan iki:

  • Saben panjalukan mlebu diselehake ing siji antrian.
  • Nalika ngolah panjaluk, layanan kasebut uga bisa nyelehake tugas ing antrian liyane.
  • Saben acara sing mlebu duwe pengenal (sing perlu kanggo deduplikasi).
  • Antrian kanthi ideologis miturut skema "mung nambah". Sampeyan ora bisa mbusak unsur saka iku utawa ngatur maneh.
  • Antrian dianggo miturut skema FIFO (ngapunten tautologi). Yen sampeyan kudu nindakake eksekusi paralel, banjur ing siji tahap sampeyan kudu mindhah obyek menyang antrian sing beda.

Ayo kula ngelingake yen kita nimbang kasus panyimpenan file online. Ing kasus iki, sistem bakal katon kaya iki:

Pola arsitektur sing trep

Penting yen layanan ing diagram kasebut ora ateges server sing kapisah. Malah proses bisa uga padha. Bab liya sing penting: kanthi ideologis, barang-barang kasebut dipisahake kanthi cara supaya skala horisontal bisa gampang ditrapake.

Lan kanggo pangguna loro, diagram bakal katon kaya iki (layanan sing ditujokake kanggo pangguna sing beda dituduhake kanthi warna sing beda):

Pola arsitektur sing trep

Bonus saka kombinasi kasebut:

  • Layanan pangolahan informasi dipisahake. Antrian uga dipisahake. Yen kita kudu nambah throughput sistem, mula kita mung kudu ngluncurake layanan liyane ing server liyane.
  • Nalika kita nampa informasi saka pangguna, kita ora kudu ngenteni nganti data wis rampung disimpen. Kosok baline, kita mung kudu mangsuli "ok" banjur mboko sithik wiwit kerja. Ing wektu sing padha, antrian lancar, amarga nambah obyek anyar kanthi cepet, lan pangguna ora kudu ngenteni pass lengkap ing kabeh siklus.
  • Minangka conto, aku nambahake layanan deduplikasi sing nyoba nggabungake file sing padha. Yen bisa digunakake kanggo dangu ing 1% kasus, klien meh ora bakal sok dong mirsani (ndeleng ndhuwur), kang plus amba, amarga kita ora maneh kudu XNUMX% kacepetan lan dipercaya.

Nanging, kekurangan kasebut langsung katon:

  • Sistem kita wis ilang konsistensi sing ketat. Iki tegese yen, umpamane, sampeyan langganan layanan sing beda-beda, mula kanthi teori sampeyan bisa entuk negara sing beda (amarga salah sawijining layanan bisa uga ora duwe wektu kanggo nampa kabar saka antrian internal). Minangka akibat liyane, sistem saiki ora duwe wektu umum. Yaiku, mokal, contone, kanggo ngurutake kabeh acara mung kanthi wektu tekan, amarga jam ing antarane server bisa uga ora sinkron (maneh, ing wektu sing padha ing rong server minangka utopia).
  • Ora ana acara sing saiki bisa digulung maneh (kaya sing bisa ditindakake karo database). Nanging, sampeyan kudu nambah acara anyar − acara ganti rugi, sing bakal ngganti negara pungkasan menyang sing dibutuhake. Minangka conto saka wilayah sing padha: tanpa nulis maneh riwayat (sing ala ing sawetara kasus), sampeyan ora bisa mbalekake komit ing git, nanging sampeyan bisa nggawe khusus. komit mundur, kang ateges mung bali negara lawas. Nanging, komit sing salah lan rollback bakal tetep ana ing sejarah.
  • Skema data bisa diganti saka release kanggo release, nanging acara lawas ora bisa maneh dianyari kanggo standar anyar (amarga acara ora bisa diganti ing asas).

Kaya sing sampeyan ngerteni, Sumber Acara bisa digunakake kanthi apik karo CQRS. Kajaba iku, ngleksanakake sistem kanthi antrian sing efisien lan trep, nanging tanpa misahake aliran data, wis angel dhewe, amarga sampeyan kudu nambah titik sinkronisasi sing bakal netralake kabeh efek positif saka antrian. Nglamar loro pendekatan bebarengan, iku perlu kanggo rada nyetel kode program. Ing kasus kita, nalika ngirim file menyang server, respon mung "ok", sing mung tegese "operasi nambah file wis disimpen." Secara resmi, iki ora ateges data wis kasedhiya ing piranti liyane (contone, layanan deduplikasi bisa mbangun maneh indeks). Nanging, sawise sawetara wektu, klien bakal nampa kabar kanthi gaya "file X wis disimpen."

Akibaté:

  • Jumlah status ngirim file saya tambah: tinimbang "file dikirim" klasik, kita entuk loro: "file wis ditambahake menyang antrian ing server" lan "file wis disimpen ing panyimpenan." Sing terakhir tegese piranti liyane wis bisa miwiti nampa file (dilarasake kanggo kasunyatan sing antrian operate ing kacepetan beda).
  • Amarga kasunyatan manawa informasi pengajuan saiki liwat saluran sing beda-beda, kita kudu nggawe solusi kanggo nampa status pangolahan file kasebut. Minangka akibat saka iki: ora kaya panjalukan-respon klasik, klien bisa diwiwiti maneh nalika ngolah file, nanging status pangolahan iki bakal bener. Menapa malih, item iki dianggo, ateges, metu saka kothak. Akibaté: kita saiki luwih toleran marang kegagalan.

Nuduhake

Kaya sing kasebut ing ndhuwur, sistem sumber acara ora konsistensi sing ketat. Iki tegese kita bisa nggunakake sawetara panyimpenan tanpa sinkronisasi ing antarane. Nyedhak masalah kita, kita bisa:

  • Pisahake file miturut jinis. Contone, gambar/video bisa didekode lan format sing luwih efisien bisa dipilih.
  • Pisah akun miturut negara. Amarga akeh hukum, iki bisa uga dibutuhake, nanging skema arsitektur iki menehi kesempatan kasebut kanthi otomatis

Pola arsitektur sing trep

Yen sampeyan pengin nransfer data saka siji panyimpenan menyang liyane, tegese standar ora cukup maneh. Sayange, ing kasus iki, sampeyan kudu mungkasi antrian, nindakake migrasi, lan banjur miwiti. Ing kasus umum, data ora bisa ditransfer "ing fly", Nanging, yen antrian acara wis disimpen rampung, lan sampeyan duwe jepretan saka negara panyimpenan sadurungé, banjur kita bisa muter maneh acara kaya ing ngisor iki:

  • Ing Sumber Acara, saben acara duwe pengenal dhewe (saenipun, ora nyuda). Iki tegese kita bisa nambah lapangan kanggo panyimpenan - id saka unsur diproses pungkasan.
  • Kita duplikat antrian supaya kabeh acara bisa diproses kanggo sawetara panyimpenan independen (sing pisanan yaiku data sing wis disimpen, lan sing kapindho anyar, nanging isih kosong). Antrian kapindho, mesthi, durung diproses.
  • Kita miwiti antrian kapindho (yaiku, kita miwiti muter maneh acara).
  • Nalika antrian anyar relatif kosong (yaiku, rata-rata prabédan wektu antarane nambah unsur lan njupuk iku ditrima), sampeyan bisa miwiti ngalih nonton kanggo panyimpenan anyar.

Kaya sing sampeyan ngerteni, kita ora duwe, lan isih ora duwe konsistensi sing ketat ing sistem kita. Mung ana konsistensi pungkasan, yaiku, njamin yen acara diproses kanthi urutan sing padha (nanging bisa uga ana wektu tundha sing beda). Lan, kanthi nggunakake iki, kita bisa kanthi gampang nransfer data tanpa mandhegake sistem menyang sisih liya ndonya.

Mangkono, nerusake conto babagan panyimpenan online kanggo file, arsitektur kasebut wis menehi sawetara bonus:

  • Kita bisa mindhah obyek nyedhaki pangguna kanthi cara dinamis. Kanthi cara iki sampeyan bisa nambah kualitas layanan.
  • Kita bisa nyimpen sawetara data ing perusahaan. Contone, pangguna Enterprise asring mbutuhake data supaya disimpen ing pusat data sing dikontrol (supaya ora bocor data). Liwat sharding kita bisa kanthi gampang ndhukung iki. Lan tugas kasebut luwih gampang yen pelanggan duwe awan sing kompatibel (contone, Azure dhewe tuan rumah).
  • Lan sing paling penting yaiku kita ora kudu nindakake iki. Sawise kabeh, kanggo miwiti, kita bakal seneng banget karo siji panyimpenan kanggo kabeh akun (kanggo miwiti kerja kanthi cepet). Lan fitur utama sistem iki yaiku sanajan bisa ditambahi, ing tahap wiwitan cukup prasaja. Sampeyan mung ora kudu langsung nulis kode sing dianggo karo yuta antrian sawijining kapisah, etc. Yen perlu, iki bisa ditindakake ing mangsa ngarep.

Hosting Konten Statis

Titik iki bisa uga katon jelas, nanging isih perlu kanggo aplikasi sing dimuat kanthi standar. Intine prasaja: kabeh konten statis disebar ora saka server sing padha ing ngendi aplikasi kasebut, nanging saka sing khusus khusus kanggo tugas iki. Akibaté, operasi iki ditindakake luwih cepet (nginx kondisional nglayani file luwih cepet lan luwih murah tinimbang server Java). Ditambah arsitektur CDN (Jaringan Konten Konten) ngidini kita nemokake file sing luwih cedhak karo pangguna pungkasan, sing nduwe pengaruh positif kanggo kepenak nggarap layanan kasebut.

Conto paling gampang lan paling standar saka konten statis yaiku sakumpulan skrip lan gambar kanggo situs web. Kabeh iku prasaja karo wong-wong mau - padha dikenal ing advance, banjur arsip diunggah menyang server CDN, saka ngendi padha disebarake kanggo pangguna pungkasan.

Nanging, ing kasunyatan, kanggo konten statis, sampeyan bisa nggunakake pendekatan sing meh padha karo arsitektur lambda. Ayo bali menyang tugas (panyimpenan file online), ing ngendi kita kudu nyebarake file menyang pangguna. Solusi sing paling gampang yaiku nggawe layanan sing, kanggo saben panyuwunan pangguna, nindakake kabeh pamriksa sing dibutuhake (wewenang, lsp), banjur ndownload file kasebut langsung saka panyimpenan. Kerugian utama pendekatan iki yaiku konten statis (lan file kanthi revisi tartamtu, nyatane, konten statis) disebarake dening server sing padha sing ngemot logika bisnis. Nanging, sampeyan bisa nggawe diagram ing ngisor iki:

  • Server nyedhiyakake URL download. Bisa saka wangun file_id + tombol, ngendi tombol iku tandha mini-digital sing menehi hak kanggo ngakses sumber daya kanggo sabanjuré XNUMX jam.
  • File kasebut disebarake kanthi nginx prasaja kanthi pilihan ing ngisor iki:
    • Caching isi. Wiwit layanan iki bisa dumunung ing server kapisah, kita wis ninggalake awake dhewe cadangan kanggo mangsa karo kemampuan kanggo nyimpen kabeh file sing diundhuh paling anyar ing disk.
    • Priksa tombol nalika nggawe sambungan
  • Opsional: pangolahan konten streaming. Contone, yen kita compress kabeh file ing layanan, banjur kita bisa nindakake unzipping langsung ing modul iki. Akibaté: operasi IO rampung ing ngendi. Arsip ing Jawa bakal gampang nyedhiyakake akeh memori ekstra, nanging nulis ulang layanan kanthi logika bisnis menyang syarat Rust / C ++ uga ora efektif. Ing kasus kita, macem-macem proses (utawa malah layanan) digunakake, lan mulane kita bisa kanthi efektif misahake logika bisnis lan operasi IO.

Pola arsitektur sing trep

Skema iki ora mirip banget karo nyebarake konten statis (amarga kita ora ngunggah kabeh paket statis ing endi wae), nanging ing kasunyatan, pendekatan iki pancen gegayutan karo nyebarake data sing ora bisa diganti. Kajaba iku, skema iki bisa digeneralisasi kanggo kasus liyane sing isi ora mung statis, nanging bisa diwakili minangka set blok sing ora bisa diganti lan ora bisa dibusak (sanajan bisa ditambahake).

Minangka conto liyane (kanggo penguatan): yen sampeyan wis kerjo karo Jenkins / TeamCity, sampeyan ngerti yen loro solusi ditulis ing Jawa. Loro-lorone minangka proses Jawa sing nangani orkestrasi lan manajemen konten. Utamane, dheweke duwe tugas kaya "mindhah file / folder saka server." Contone: nerbitake artefak, nransfer kode sumber (nalika agen ora ngundhuh kode langsung saka gudang, nanging server nindakake kanggo dheweke), akses menyang log. Kabeh tugas iki beda-beda ing beban IO. Tegese, ternyata server sing tanggung jawab kanggo logika bisnis sing kompleks kudu ing wektu sing padha bisa kanthi efektif nyurung aliran data sing akeh. Lan sing paling menarik yaiku operasi kasebut bisa didelegasikan menyang nginx sing padha miturut skema sing padha (kajaba kunci data kudu ditambahake menyang panyuwunan).

Nanging, yen kita bali menyang sistem, kita entuk diagram sing padha:

Pola arsitektur sing trep

Kaya sing sampeyan ngerteni, sistem kasebut dadi luwih rumit. Saiki ora mung proses mini sing nyimpen file sacara lokal. Saiki sing dibutuhake dudu dhukungan sing paling gampang, kontrol versi API, lsp. Mulane, sawise kabeh diagram wis digambar, iku paling apik kanggo ngevaluasi rinci apa extensibility worth biaya. Nanging, yen sampeyan pengin bisa nggedhekake sistem kasebut (kalebu nggarap pangguna sing luwih akeh), mula sampeyan kudu golek solusi sing padha. Nanging, minangka asil, sistem arsitektur siap kanggo nambah beban (meh saben komponen bisa dikloning kanggo skala horisontal). Sistem bisa dianyari tanpa mandheg (mung sawetara operasi bakal rada kalem).

Kaya sing dakkandhakake ing wiwitan, saiki sawetara layanan Internet wiwit nampa beban sing tambah. Lan sawetara mung wiwit mandheg kerja kanthi bener. Nyatane, sistem kasebut gagal pas nalika bisnis kasebut kudu entuk dhuwit. Tegese, tinimbang pangiriman sing ditundha, tinimbang menehi saran marang para pelanggan "ngrencanakake pangiriman sampeyan ing sasi sing bakal teka," sistem kasebut mung ujar "lunga menyang pesaing sampeyan." Nyatane, iki minangka rega produktivitas sing kurang: kerugian bakal kedadeyan nalika bathi paling dhuwur.

kesimpulan

Kabeh pendekatan iki wis dikenal sadurunge. VK sing padha wis suwe nggunakake ide Hosting Konten Statis kanggo nampilake gambar. Akeh game online nggunakake skema Sharding kanggo dibagi pemain menyang wilayah utawa kanggo misahake lokasi game (yen donya dhewe). Pendekatan Sumber Acara aktif digunakake ing email. Umume aplikasi dagang ing ngendi data terus ditampa bener-bener dibangun ing pendekatan CQRS supaya bisa nyaring data sing ditampa. Ya, skala horisontal wis digunakake ing pirang-pirang layanan suwene suwe.

Nanging, sing paling penting, kabeh pola kasebut dadi gampang banget kanggo aplikasi modern (yen cocok, mesthi). Awan nawakake Sharding lan skala horisontal, sing luwih gampang tinimbang pesen server khusus sing beda ing pusat data sing beda-beda. CQRS dadi luwih gampang, yen mung amarga pangembangan perpustakaan kayata RX. Kira-kira 10 taun kepungkur, situs web langka bisa ndhukung iki. Acara Sourcing uga gampang banget kanggo nyiyapake amarga wadhah sing wis siap karo Apache Kafka. 10 taun kepungkur iki bakal dadi inovasi, saiki wis umum. Iku padha karo Hosting Konten Statis: amarga teknologi sing luwih trep (kalebu kasunyatan sing ana dokumentasi rinci lan database jawaban sing gedhe), pendekatan iki dadi luwih gampang.

Akibaté, implementasine saka sawetara pola arsitektur rada Komplek saiki wis dadi luwih prasaja, kang tegese iku luwih apik kanggo njupuk dipikir ing advance. Yen ing aplikasi sing umur sepuluh taun, salah sawijining solusi ing ndhuwur ditinggalake amarga biaya implementasine lan operasi sing dhuwur, saiki, ing aplikasi anyar, utawa sawise refactoring, sampeyan bisa nggawe layanan sing wis arsitektur bisa extensible ( babagan kinerja) lan siap kanggo panjalukan anyar saka klien (contone, kanggo lokal data pribadhi).

Lan sing paling penting: aja nggunakake pendekatan kasebut yen sampeyan duwe aplikasi sing gampang. Ya, padha ayu lan menarik, nanging kanggo situs kanthi kunjungan puncak 100 wong, sampeyan bisa kerep njaluk karo monolit klasik (paling ora ing njaba, kabeh nang bisa dipérang dadi modul, etc.).

Source: www.habr.com

Add a comment