Fl-aħħar
- Talba-tweġiba
- Rispons Talba-Chunked
- Risposta b'Talba
- Ippubblika-abbona
- Inverted Publish-abbona
- Distribuzzjoni tal-kompitu
SOA, MSA u Messaging
SOA, MSA huma arkitetturi tas-sistema li jiddefinixxu r-regoli għas-sistemi tal-bini, filwaqt li l-messaġġi jipprovdu primittivi għall-implimentazzjoni tagħhom.
Ma rridx nippromwovi din jew dik l-arkitettura tas-sistema. Jien għall-użu tal-prattiki l-aktar effettivi u utli għal proġett u negozju speċifiku. Tkun xi tkun il-paradigma li nagħżlu, huwa aħjar li noħolqu blokki tas-sistema b'għajnejk fuq il-mod Unix: komponenti b'konnettività minima, responsabbli għal entitajiet individwali. Il-metodi API jwettqu l-aktar azzjonijiet sempliċi possibbli ma 'entitajiet.
Il-messaġġi huma, kif jissuġġerixxi l-isem, sensar tal-messaġġi. L-għan ewlieni tiegħu huwa li jirċievi u jibgħat messaġġi. Huwa responsabbli għall-interfaces biex tintbagħat l-informazzjoni, il-formazzjoni ta 'kanali loġiċi għat-trażmissjoni ta' informazzjoni fis-sistema, ir-rotot u l-ibbilanċjar, kif ukoll l-immaniġġjar tal-ħsarat fil-livell tas-sistema.
Il-messagg li qed niżviluppaw mhux qed jipprova jikkompeti jew jissostitwixxi l-fenekmq. Il-karatteristiċi ewlenin tiegħu:
- Distribuzzjoni.
Jistgħu jinħolqu punti ta' skambju fuq in-nodi tal-clusters kollha, qrib kemm jista' jkun tal-kodiċi li jużahom. - Is-sempliċità
Iffoka fuq il-minimizzazzjoni tal-kodiċi tal-boilerplate u l-faċilità tal-użu. - Prestazzjoni aħjar.
Aħna mhux qed nippruvaw nirrepetu l-funzjonalità tal-fenekmq, iżda nenfasizzaw biss is-saff arkitettoniku u tat-trasport, li noqogħdu fl-OTP bl-aktar mod sempliċi possibbli, u jimminimizzaw l-ispejjeż. - Flessibilità.
Kull servizz jista 'jgħaqqad ħafna mudelli ta' skambju. - Reżiljenza mid-disinn.
- Skalabbiltà.
Il-messaġġi jikbru mal-applikazzjoni. Hekk kif it-tagħbija tiżdied, tista 'tmexxi l-punti ta' skambju għal magni individwali.
Kumment. F'termini ta 'organizzazzjoni tal-kodiċi, il-meta-proġetti huma adattati tajjeb għal sistemi Erlang/Elixir kumplessi. Il-kodiċi tal-proġett kollu jinsab f'repożitorju wieħed - proġett umbrella. Fl-istess ħin, il-mikroservizzi huma iżolati b'mod massimu u jwettqu operazzjonijiet sempliċi li huma responsabbli għal entità separata. B'dan l-approċċ, huwa faċli li tinżamm l-API tas-sistema kollha, huwa faċli li tagħmel bidliet, huwa konvenjenti li tikteb testijiet ta 'unità u integrazzjoni.
Il-komponenti tas-sistema jinteraġixxu direttament jew permezz ta 'sensar. Mill-perspettiva tal-messaġġi, kull servizz għandu diversi fażijiet tal-ħajja:
- Inizjalizzazzjoni tas-servizz.
F'dan l-istadju, il-proċess u d-dipendenzi li jeżegwixxu s-servizz huma kkonfigurati u mnedija. - Ħolqien ta 'punt ta' skambju.
Is-servizz jista 'juża punt ta' skambju statiku speċifikat fil-konfigurazzjoni tan-nodu, jew joħloq punti ta 'skambju b'mod dinamiku. - Reġistrazzjoni tas-servizz.
Sabiex is-servizz jaqdi t-talbiet, irid ikun irreġistrat fil-punt tal-iskambju. - Funzjonament normali.
Is-servizz jipproduċi xogħol utli. - Għalaq.
Hemm 2 tipi ta 'għeluq possibbli: normali u ta' emerġenza. Waqt it-tħaddim normali, is-servizz jiġi skonnettjat mill-punt tal-iskambju u jieqaf. F'sitwazzjonijiet ta' emerġenza, il-messaġġi jesegwixxi waħda mill-iskripts ta' failover.
Jidher pjuttost ikkumplikat, iżda l-kodiċi mhux dak kollu tal-biża '. Eżempji ta' kodiċi b'kummenti se jingħataw fl-analiżi tal-mudelli ftit aktar tard.
Skambji
Punt ta 'skambju huwa proċess ta' messaġġi li jimplimenta l-loġika ta 'interazzjoni ma' komponenti fi ħdan il-mudell ta 'messaġġi. Fl-eżempji kollha ppreżentati hawn taħt, il-komponenti jinteraġixxu permezz ta 'punti ta' skambju, li l-kombinazzjoni tagħhom tifforma messaġġi.
Mudelli ta' skambju ta' messaġġi (MEPs)
Globalment, mudelli ta 'skambju jistgħu jinqasmu f'żewġ direzzjonijiet u f'direzzjoni waħda. L-ewwel jimplikaw rispons għal messaġġ li jkun dieħel, l-aħħar le. Eżempju klassiku ta 'mudell bidirezzjonali fl-arkitettura klijent-server huwa l-mudell Request-response. Ejja nħarsu lejn il-mudell u l-modifiki tiegħu.
Talba-tweġiba jew RPC
RPC jintuża meta jkollna bżonn nirċievu tweġiba minn proċess ieħor. Dan il-proċess jista' jkun qed jaħdem fuq l-istess node jew jinsab f'kontinent differenti. Hawn taħt hemm dijagramma tal-interazzjoni bejn il-klijent u s-server permezz tal-messaġġi.
Peress li l-messaġġi huma kompletament asinkroniċi, għall-klijent l-iskambju huwa maqsum f'2 fażijiet:
-
Mittenti talba
messaging:request(Exchange, ResponseMatchingTag, RequestDefinition, HandlerProcess).
skambju ‒ isem uniku tal-punt tal-iskambju
ResponseMatchingTag ‒ tikketta lokali għall-ipproċessar tar-rispons. Pereżempju, fil-każ li jintbagħtu diversi talbiet identiċi li jappartjenu għal utenti differenti.
TalbaDefinizzjoni - korp tat-talba
HandlerProcess ‒ PID tal-handler. Dan il-proċess se jirċievi tweġiba mis-server. -
Ipproċessa r-rispons
handle_info(#'$msg'{exchange = EXCHANGE, tag = ResponseMatchingTag,message = ResponsePayload}, State)
RisponsPayload - rispons tas-server.
Għas-server, il-proċess jikkonsisti wkoll f'2 fażijiet:
- Inizjalizzazzjoni tal-punt tal-iskambju
- Ipproċessar ta' talbiet riċevuti
Ejja nuru dan il-mudell bil-kodiċi. Ejja ngħidu li għandna bżonn nimplimentaw servizz sempliċi li jipprovdi metodu wieħed eżatt tal-ħin.
Kodiċi tas-server
Ejja niddefinixxu l-API tas-servizz f'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{}
}).
Ejja niddefinixxu l-kontrollur tas-servizz f'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.
Kodiċi tal-klijent
Sabiex tibgħat talba lis-servizz, tista' ċċempel lill-API ta' rikjesta għall-messaġġi kullimkien fil-klijent:
case messaging:request(?EXCHANGE, tag, #time_req{opts = #{}}, self()) of
ok -> ok;
_ -> %% repeat or fail logic
end
F'sistema mqassma, il-konfigurazzjoni tal-komponenti tista 'tkun differenti ħafna u fil-ħin tat-talba, il-messaġġi jistgħu għadhom ma jibdewx, jew il-kontrollur tas-servizz mhux se jkun lest biex iservi t-talba. Għalhekk, għandna bżonn niċċekkjaw ir-rispons tal-messaġġi u nittrattaw il-każ tal-falliment.
Wara li jintbagħat b'suċċess, il-klijent jirċievi tweġiba jew żball mis-servizz.
Ejja nittrattaw iż-żewġ każijiet f'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};
Rispons Talba-Chunked
L-aħjar li tevita li tibgħat messaġġi kbar. Ir-rispons u l-operat stabbli tas-sistema kollha jiddependu minn dan. Jekk ir-rispons għal mistoqsija jieħu ħafna memorja, allura l-qsim f'partijiet huwa obbligatorju.
Ħa nagħtikom ftit eżempji ta’ każijiet bħal dawn:
- Il-komponenti jiskambjaw data binarja, bħal fajls. It-tkissir tar-rispons f'partijiet żgħar jgħinek taħdem b'mod effiċjenti b'fajls ta 'kull daqs u tevita l-overflows tal-memorja.
- Listi. Pereżempju, għandna bżonn nagħżlu r-rekords kollha minn tabella enormi fid-database u tittrasferihom għal komponent ieħor.
Jien insejjaħ dawn ir-reazzjonijiet lokomottivi. Fi kwalunkwe każ, 1024 messaġġ ta' 1 MB huma aħjar minn messaġġ wieħed ta' 1 GB.
Fil-cluster Erlang, niksbu benefiċċju addizzjonali - tnaqqas it-tagħbija fuq il-punt tal-iskambju u n-netwerk, peress li r-risposti jintbagħtu immedjatament lir-riċevitur, billi jinjora l-punt tal-iskambju.
Risposta b'Talba
Din hija modifika pjuttost rari tal-mudell RPC għall-bini ta 'sistemi ta' djalogu.
Publish-subscribe (siġra tad-distribuzzjoni tad-dejta)
Sistemi mmexxija mill-avvenimenti jwassluhom lill-konsumaturi hekk kif id-dejta tkun lesta. Għalhekk, is-sistemi huma aktar suxxettibbli għal mudell push milli għal mudell pull jew poll. Din il-karatteristika tippermettilek tevita li taħli r-riżorsi billi titlob u tistenna kontinwament id-dejta.
Il-figura turi l-proċess ta 'distribuzzjoni ta' messaġġ lill-konsumaturi abbonati għal suġġett speċifiku.
Eżempji klassiċi tal-użu ta 'dan il-mudell huma d-distribuzzjoni tal-istat: id-dinja tal-logħob fil-logħob tal-kompjuter, id-dejta tas-suq dwar l-iskambji, l-informazzjoni utli fid-data feeds.
Ejja nħarsu lejn il-kodiċi tal-abbonat:
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.
Is-sors jista' jsejjaħ il-funzjoni biex jippubblika messaġġ fi kwalunkwe post konvenjenti:
messaging:publish_message(Exchange, Key, Message).
skambju - isem il-punt tal-iskambju,
Ewlenin - ċavetta tar-rotta
messaġġ - tagħbija
Inverted Publish-abbona
Billi tespandi pub-sub, tista 'tikseb mudell konvenjenti għall-illoggjar. Is-sett ta 'sorsi u konsumaturi jistgħu jkunu kompletament differenti. Il-figura turi każ b'konsumatur wieħed u sorsi multipli.
Mudell tad-distribuzzjoni tal-kompitu
Kważi kull proġett jinvolvi ħidmiet ta' pproċessar differit, bħall-ġenerazzjoni ta' rapporti, it-twassil ta' notifiki, u l-irkupru ta' data minn sistemi ta' partijiet terzi. It-throughput tas-sistema li twettaq dawn il-kompiti jista 'jiġi skalat faċilment billi jiżdiedu handlers. Kulma jibqa' għalina huwa li niffurmaw grupp ta' proċessuri u nqassmu l-kompiti bejniethom b'mod ugwali.
Ejja nħarsu lejn is-sitwazzjonijiet li jinqalgħu billi tuża l-eżempju ta '3 handlers. Anke fl-istadju tad-distribuzzjoni tal-kompiti, tqum il-kwistjoni tal-ġustizzja tad-distribuzzjoni u l-overflow tal-handlers. Id-distribuzzjoni round-robin se tkun responsabbli għall-ġustizzja, u biex tiġi evitata sitwazzjoni ta 'overflow ta' handlers, se nintroduċu restrizzjoni prefetch_limit. F'kundizzjonijiet temporanji prefetch_limit se jipprevjeni handler wieħed milli jirċievi l-kompiti kollha.
Il-messaġġi jimmaniġġjaw il-kjuwijiet u l-prijorità tal-ipproċessar. Il-proċessuri jirċievu kompiti hekk kif jaslu. Il-kompitu jista’ jitlesta b’suċċess jew ifalli:
messaging:ack(Tack)
- imsejħa jekk il-messaġġ jiġi pproċessat b'suċċessmessaging:nack(Tack)
- imsejjaħ fis-sitwazzjonijiet kollha ta' emerġenza. Ladarba l-kompitu jiġi rritornat, il-messaġġi jgħadduha lil handler ieħor.
Ejja nassumu li seħħet falliment kumpless waqt l-ipproċessar ta 'tliet kompiti: il-proċessur 1, wara li rċieva l-kompitu, ġġarraf mingħajr ma kellu ħin biex jirrapporta xejn lill-punt tal-iskambju. F'dan il-każ, il-punt tal-iskambju se jittrasferixxi l-kompitu lil handler ieħor wara li l-ack timeout ikun skada. Għal xi raġuni, handler 3 abbanduna l-kompitu u bagħat nack; bħala riżultat, il-kompitu ġie trasferit ukoll lil handler ieħor li temmha b'suċċess.
Sommarju preliminari
Aħna koprejna l-blokki bażiċi ta 'sistemi distribwiti u ksibna fehim bażiku tal-użu tagħhom f'Erlang/Elixir.
Billi tgħaqqad mudelli bażiċi, tista 'tibni paradigmi kumplessi biex issolvi problemi emerġenti.
Fil-parti finali tas-serje, se nħarsu lejn kwistjonijiet ġenerali ta 'organizzazzjoni tas-servizzi, rotta u bilanċjar, u nitkellmu wkoll dwar in-naħa prattika tal-iskalabbiltà u t-tolleranza tal-ħsarat tas-sistemi.
Tmiem it-tieni parti.
Фото
Illustrazzjonijiet ippreparati bl-użu tal-websequencediagrams.com
Sors: www.habr.com