Ing pungkasan
- Njaluk-respon
- Request-Chunked Response
- Respon karo Request
- Nerbitake-langganan
- Inverted Publish-langganan
- Distribusi tugas
SOA, MSA lan Pesen
SOA, MSA minangka arsitektur sistem sing nemtokake aturan kanggo sistem bangunan, nalika olahpesen nyedhiyakake primitif kanggo implementasine.
Aku ora pengin ningkatakΓ© arsitektur sistem iki utawa sing. Aku nggunakake praktik sing paling efektif lan migunani kanggo proyek lan bisnis tartamtu. Punapa mawon paradigma kita milih, iku luwih apik kanggo nggawe pamblokiran sistem karo mripat ing Unix-cara: komponen karo panyambungan minimal, tanggung jawab kanggo entitas individu. Cara API nindakake tumindak sing paling gampang karo entitas.
Olahpesen, kaya jeneng kasebut, broker pesen. Tujuan utamane yaiku kanggo nampa lan ngirim pesen. Tanggung jawab kanggo antarmuka kanggo ngirim informasi, pambentukan saluran logis kanggo ngirim informasi ing sistem, nuntun lan imbangan, uga penanganan kesalahan ing tingkat sistem.
Pesen sing dikembangake ora nyoba saingan utawa ngganti rabbitmq. Fitur utama:
- Distribusi.
Titik ijol-ijolan bisa digawe ing kabeh kelenjar kluster, sabisa-bisa kode sing digunakake. - Kesederhanaan
Fokus kanggo nyilikake kode boilerplate lan gampang digunakake. - Kinerja sing luwih apik.
Kita ora nyoba mbaleni fungsi rabbitmq, nanging mung nyorot lapisan arsitektur lan transportasi, sing pas karo OTP kanthi gampang, nyuda biaya. - Fleksibilitas.
Saben layanan bisa nggabungake akeh template ijol-ijolan. - Resiliensi dening desain.
- Skalabilitas.
Olahpesen tuwuh kanthi aplikasi. Nalika beban mundhak, sampeyan bisa mindhah titik ijol-ijolan menyang mesin individu.
Cathetan. Ing babagan organisasi kode, meta-proyek cocog kanggo sistem Erlang / Elixir sing kompleks. Kabeh kode proyek dumunung ing siji gudang - proyek payung. Ing wektu sing padha, layanan mikro diisolasi kanthi maksimal lan nindakake operasi prasaja sing tanggung jawab kanggo entitas sing kapisah. Kanthi pendekatan iki, gampang kanggo njaga API kabeh sistem, gampang nggawe owah-owahan, trep kanggo nulis tes unit lan integrasi.
Komponen sistem interaksi langsung utawa liwat makelar. Saka perspektif olahpesen, saben layanan duwe sawetara fase urip:
- Inisialisasi layanan.
Ing tahap iki, proses lan dependensi sing nglakokake layanan dikonfigurasi lan diluncurake. - Nggawe titik ijol-ijolan.
Layanan kasebut bisa nggunakake titik ijol-ijolan statis sing ditemtokake ing konfigurasi simpul, utawa nggawe titik ijol-ijolan kanthi dinamis. - Registrasi layanan.
Supaya layanan bisa nglayani panjalukan, kudu didaftar ing titik ijol-ijolan. - Fungsi normal.
Layanan kasebut ngasilake karya sing migunani. - mateni.
Ana 2 jinis mati bisa: normal lan darurat. Sajrone operasi normal, layanan kasebut pedhot saka titik ijol-ijolan lan mandheg. Ing kahanan darurat, olahpesen nglakokake salah sawijining skrip failover.
Iku katon cukup rumit, nanging kode ora kabeh sing medeni. Conto kode karo komentar bakal diwenehi ing analisis cithakan mengko.
Exchanges
Exchange point minangka proses olahpesen sing ngetrapake logika interaksi karo komponen ing cithakan olahpesen. Ing kabeh conto sing ditampilake ing ngisor iki, komponen kasebut sesambungan liwat titik ijol-ijolan, kombinasi sing dadi olahpesen.
Pola tukar pesan (MEPs)
Sacara global, pola ijol-ijolan bisa dipΓ©rang dadi rong arah lan siji arah. Tilas nuduhake respon kanggo pesen sing mlebu, sing terakhir ora. Conto klasik saka pola rong arah ing arsitektur klien-server yaiku pola Request-response. Ayo katon ing cithakan lan modifikasi.
Request-respon utawa RPC
RPC digunakake nalika kita kudu nampa respon saka proses liyane. Proses iki bisa uga mlaku ing simpul sing padha utawa dumunung ing bawana sing beda. Ing ngisor iki diagram interaksi antarane klien lan server liwat olahpesen.
Amarga olahpesen pancen ora sinkron, kanggo klien ijol-ijolan dipΓ©rang dadi 2 fase:
-
Kirim request
messaging:request(Exchange, ResponseMatchingTag, RequestDefinition, HandlerProcess).
Exchange β jeneng unik saka titik ijol-ijolan
ResponseMatchingTag - label lokal kanggo ngolah respon. Contone, ing kasus ngirim sawetara panjalukan sing padha karo pangguna sing beda.
RequestDefinition - njaluk awak
Proses Handler - PID saka pawang. Proses iki bakal nampa respon saka server. -
Ngolah respon
handle_info(#'$msg'{exchange = EXCHANGE, tag = ResponseMatchingTag,message = ResponsePayload}, State)
ResponsePayload - respon server.
Kanggo server, proses kasebut uga kalebu 2 fase:
- Initializing titik ijol-ijolan
- Pangolahan panjalukan sing ditampa
Ayo digambarake cithakan iki nganggo kode. Ayo kita kudu ngleksanakake layanan prasaja sing nyedhiyakake metode wektu sing tepat.
Kode server
Ayo nambah definisi API layanan kanggo api.hrl:
%% =====================================================
%% entities
%% =====================================================
-record(time, {
unixtime :: non_neg_integer(),
datetime :: binary()
}).
-record(time_error, {
code :: non_neg_integer(),
error :: term()
}).
%% =====================================================
%% methods
%% =====================================================
-record(time_req, {
opts :: term()
}).
-record(time_resp, {
result :: #time{} | #time_error{}
}).
Ayo dadi netepake controller layanan ing time_controller.erl
%% Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ ΡΠΎΠ»ΡΠΊΠΎ Π·Π½Π°ΡΠΈΠΌΡΠΉ ΠΊΠΎΠ΄. ΠΡΡΠ°Π²ΠΈΠ² Π΅Π³ΠΎ Π² ΡΠ°Π±Π»ΠΎΠ½ gen_server ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ°Π±ΠΎΡΠΈΠΉ ΡΠ΅ΡΠ²ΠΈΡ.
%% ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ gen_server
init(Args) ->
%% ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΠΎΡΠΊΠ΅ ΠΎΠ±ΠΌΠ΅Π½Π°
messaging:monitor_exchange(req_resp, ?EXCHANGE, default, self())
{ok, #{}}.
%% ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΎΠ±ΡΡΠΈΡ ΠΏΠΎΡΠ΅ΡΠΈ ΡΠ²ΡΠ·ΠΈ Ρ ΡΠΎΡΠΊΠΎΠΉ ΠΎΠ±ΠΌΠ΅Π½Π°. ΠΡΠΎ ΠΆΠ΅ ΡΠΎΠ±ΡΡΠΈΠ΅ ΠΏΡΠΈΡ
ΠΎΠ΄ΠΈΡ, Π΅ΡΠ»ΠΈ ΡΠΎΡΠΊΠ° ΠΎΠ±ΠΌΠ΅Π½Π° Π΅ΡΠ΅ Π½Π΅ Π·Π°ΠΏΡΡΡΠΈΠ»Π°ΡΡ.
handle_info(#exchange_die{exchange = ?EXCHANGE}, State) ->
erlang:send(self(), monitor_exchange),
{noreply, State};
%% ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° API
handle_info(#time_req{opts = _Opts}, State) ->
messaging:response_once(Client, #time_resp{
result = #time{ unixtime = time_utils:unixtime(now()), datetime = time_utils:iso8601_fmt(now())}
});
{noreply, State};
%% Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΡ gen_server
terminate(_Reason, _State) ->
messaging:demonitor_exchange(req_resp, ?EXCHANGE, default, self()),
ok.
Kode klien
Kanggo ngirim panjalukan menyang layanan kasebut, sampeyan bisa nelpon API panjalukan olahpesen ing ngendi wae ing klien:
case messaging:request(?EXCHANGE, tag, #time_req{opts = #{}}, self()) of
ok -> ok;
_ -> %% repeat or fail logic
end
Ing sistem sing disebarake, konfigurasi komponen bisa beda banget lan nalika panyuwunan, olahpesen bisa uga durung diwiwiti, utawa pengontrol layanan ora bakal siyap kanggo nglayani panyuwunan kasebut. Mulane, kita kudu mriksa respon olahpesen lan nangani kasus kegagalan.
Sawise sukses ngirim, klien bakal nampa respon utawa kesalahan saka layanan.
Ayo nangani loro kasus ing handle_info:
handle_info(#'$msg'{exchange = ?EXCHANGE, tag = tag, message = #time_resp{result = #time{unixtime = Utime}}}, State) ->
?debugVal(Utime),
{noreply, State};
handle_info(#'$msg'{exchange = ?EXCHANGE, tag = tag, message = #time_resp{result = #time_error{code = ErrorCode}}}, State) ->
?debugVal({error, ErrorCode}),
{noreply, State};
Request-Chunked Response
Sing paling apik supaya ora ngirim pesen gedhe. Responsiveness lan operasi stabil kabeh sistem gumantung iki. Yen nanggepi pitakonan mbutuhake akeh memori, banjur dibagi dadi bagean wajib.
Ayo kula menehi sawetara conto kasus kasebut:
- Komponen kasebut ngganti data binar, kayata file. Mbusak respon dadi bagean cilik mbantu sampeyan nggarap file kanthi ukuran apa wae lan ngindhari overflows memori.
- Listings. Contone, kita kudu milih kabeh cathetan saka tabel ageng ing database lan nransfer menyang komponen liyane.
Aku nelpon respon iki lokomotif. Ing kasus apa wae, 1024 pesen 1 MB luwih apik tinimbang pesen siji 1 GB.
Ing kluster Erlang, entuk manfaat tambahan - nyuda beban ing titik ijol-ijolan lan jaringan, amarga tanggapan langsung dikirim menyang panampa, ngliwati titik ijol-ijolan.
Respon karo Request
Iki minangka modifikasi pola RPC sing rada langka kanggo mbangun sistem dialog.
Publish-subscribe (pohon distribusi data)
Sistem sing didorong acara ngirim menyang konsumen sanalika data wis siyap. Mangkono, sistem luwih rentan kanggo model push tinimbang model tarik utawa polling. Fitur iki ngidini sampeyan supaya ora mbuang sumber daya kanthi terus-terusan njaluk lan ngenteni data.
Tokoh kasebut nuduhake proses nyebarake pesen menyang konsumen sing langganan topik tartamtu.
Conto klasik nggunakake pola iki distribusi negara: donya game ing game komputer, data pasar ing ijol-ijolan, informasi migunani ing feed data.
Ayo ndeleng kode langganan:
init(_Args) ->
%% ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°Π΅ΠΌΡΡ Π½Π° ΠΎΠ±ΠΌΠ΅Π½Π½ΠΈΠΊ, ΠΊΠ»ΡΡ = key
messaging:subscribe(?SUBSCRIPTION, key, tag, self()),
{ok, #{}}.
handle_info(#exchange_die{exchange = ?SUBSCRIPTION}, State) ->
%% Π΅ΡΠ»ΠΈ ΡΠΎΡΠΊΠ° ΠΎΠ±ΠΌΠ΅Π½Π° Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½Π°, ΡΠΎ ΠΏΡΡΠ°Π΅ΠΌΡΡ ΠΏΠ΅ΡΠ΅ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡΡΡ
messaging:subscribe(?SUBSCRIPTION, key, tag, self()),
{noreply, State};
%% ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ ΠΏΡΠΈΡΠ΅Π΄ΡΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ
handle_info(#'$msg'{exchange = ?SUBSCRIPTION, message = Msg}, State) ->
?debugVal(Msg),
{noreply, State};
%% ΠΏΡΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ - ΠΎΡΠΊΠ»ΡΡΠ°Π΅ΠΌΡΡ ΠΎΡ ΡΠΎΡΠΊΠΈ ΠΎΠ±ΠΌΠ΅Π½Π°
terminate(_Reason, _State) ->
messaging:unsubscribe(?SUBSCRIPTION, key, tag, self()),
ok.
Sumber bisa nelpon fungsi kasebut kanggo nerbitake pesen ing papan sing trep:
messaging:publish_message(Exchange, Key, Message).
Exchange - jeneng titik ijol-ijolan,
Key - tombol nuntun
Pesen - muatan
Inverted Publish-langganan
Kanthi ngembangake pub-sub, sampeyan bisa entuk pola sing trep kanggo logging. Kumpulan sumber lan konsumen bisa beda-beda. Tokoh kasebut nuduhake kasus karo siji konsumen lan macem-macem sumber.
Pola distribusi tugas
Meh saben proyek kalebu tugas pangolahan sing ditundha, kayata ngasilake laporan, ngirim kabar, lan njupuk data saka sistem pihak katelu. Output saka sistem sing nindakake tugas kasebut bisa gampang diukur kanthi nambah panangan. Kabeh sing isih ana kanggo kita yaiku mbentuk kluster pemroses lan nyebarake tugas kanthi rata ing antarane.
Ayo ndeleng kahanan sing muncul nggunakake conto 3 pawang. Malah ing tataran distribusi tugas, pitakonan babagan keadilan distribusi lan kebanjiran pawang muncul. Distribusi round-robin bakal tanggung jawab kanggo keadilan, lan kanggo ngindhari kahanan kebanjiran pawang, kita bakal ngenalake watesan. prefetch_limit. Ing kahanan sementara prefetch_limit bakal nyegah siji handler saka nampa kabeh tugas.
Pesen ngatur antrian lan prioritas pangolahan. Prosesor nampa tugas nalika teka. Tugas bisa rampung kanthi sukses utawa gagal:
messaging:ack(Tack)
- disebut yen pesen wis kasil diprosesmessaging:nack(Tack)
- disebut ing kabeh kahanan darurat. Sawise tugas kasebut bali, olahpesen bakal dikirim menyang pawang liyane.
Upamane ana kegagalan kompleks nalika ngolah telung tugas: prosesor 1, sawise nampa tugas kasebut, tabrakan tanpa wektu kanggo nglaporake apa wae menyang titik ijol-ijolan. Ing kasus iki, titik ijol-ijolan bakal nransfer tugas kanggo handler liyane sawise wektu entek ack wis kadaluwarsa. Kanggo sawetara alasan, pawang 3 nilar tugas kasebut lan ngirim nack; minangka asil, tugas kasebut uga ditransfer menyang pawang liyane sing kasil ngrampungake.
Ringkesan awal
Kita wis nutupi blok bangunan dhasar sistem sing disebarake lan entuk pangerten dhasar babagan panggunaan ing Erlang / Elixir.
Kanthi nggabungake pola dhasar, sampeyan bisa mbangun paradigma rumit kanggo ngatasi masalah sing muncul.
Ing bagΓ©an pungkasan saka seri, kita bakal katon ing masalah umum ngatur layanan, nuntun lan imbangan, lan uga ngomong bab sisih praktis saka kaukur lan toleransi fault saka sistem.
Pungkasan bagean kapindho.
Photography
Ilustrasi disiapake nggunakake websequencediagrams.com
Source: www.habr.com