Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Nan tan lontan an Atik nou te analize fondasyon yo teyorik nan achitekti reyaktif. Li lè pou nou pale sou koule done, fason pou aplike sistèm reyaktif Erlang/Elixir, ak modèl mesaj ladan yo:

  • Demann-repons
  • Demann-Repons an fragman
  • Repons ak demann
  • Pibliye-abònman
  • Envèse Pibliye Abònman
  • Distribisyon travay

SOA, MSA ak messagerie

SOA, MSA se achitekti sistèm ki defini règ yo pou sistèm bilding, pandan y ap mesaj bay primitif pou aplikasyon yo.

Mwen pa vle difize achitekti sistèm sa a oswa sa a. Mwen se pou aplikasyon an nan pratik ki pi efikas ak itil pou yon pwojè patikilye ak biznis. Kèlkeswa paradigm nou chwazi, li pi bon pou kreye blòk sistèm ak yon je sou fason Unix la: konpozan ki gen koneksyon minimòm, responsab pou antite endividyèl yo. Metòd API fè aksyon ki pi senp ak antite.

Mesaj - jan non an implique - yon koutye mesaj. Objektif prensipal li se resevwa ak voye mesaj. Li responsab pou koòdone yo pou voye enfòmasyon, fòmasyon nan chanèl lojik pou transmèt enfòmasyon nan sistèm nan, routage ak balanse, osi byen ke manyen echèk nan nivo sistèm nan.
Mesaj yo devlope pa eseye fè konpetisyon ak oswa ranplase rabbitmq. Karakteristik prensipal li yo:

  • Distribisyon.
    Pwen echanj yo ka kreye sou tout nœuds nan gwoup la, pi pre ke posib nan kòd ki sèvi ak yo.
  • Senplisite.
    Konsantre sou minimize kòd boilerplate ak fasilite pou itilize.
  • Pi bon pèfòmans.
    Nou pa ap eseye repete fonksyonalite rabbitmq, men nou chwazi sèlman kouch achitekti ak transpò, ke nou anfòm nan OTP kòm tou senpleman posib, minimize depans yo.
  • Fleksibilite.
    Chak sèvis ka konbine anpil modèl echanj.
  • Rezilyans pa konsepsyon.
  • Évolutivité.
    Mesaj ap grandi ak app a. Kòm chaj la ogmante, ou ka deplase pwen echanj yo nan machin separe.

Remak. An tèm de òganizasyon kòd, meta-pwojè yo byen adapte pou sistèm konplèks Erlang / Elixir. Tout kòd pwojè a se nan yon sèl depo - yon pwojè parapli. An menm tan an, mikwosèvis yo izole otank posib epi fè operasyon senp ki responsab pou yon antite separe. Avèk apwòch sa a, li fasil pou kenbe API nan tout sistèm nan, li fasil pou fè chanjman, li se pratik yo ekri tès inite ak entegrasyon.

Konpozan sistèm yo kominike dirèkteman oswa atravè yon koutye. Soti nan pozisyon nan mesaj, chak sèvis gen plizyè faz lavi:

  • Inisyalizasyon sèvis.
    Nan etap sa a, konfigirasyon an ak lansman pwosesis la egzekite sèvis la ak depandans pran plas.
  • Kreye yon pwen echanj.
    Sèvis la ka itilize yon pwen echanj estatik ki espesifye nan konfigirasyon lame a, oswa kreye pwen echanj dinamik.
  • Enskripsyon sèvis.
    Pou sèvis la sèvi demann, li dwe anrejistre sou pwen echanj la.
  • Operasyon nòmal.
    Sèvis la fè travay itil.
  • Fini travay.
    Gen 2 kalite fèmen: regilye ak ijans. Avèk yon sèvis regilye, li dekonekte nan pwen echanj la epi li sispann. Nan ka ijans, messagerie egzekite youn nan senaryo failover yo.

Li sanble byen konplike, men kòd la pa tèlman pè. Egzanp Kòd ak kòmantè yo pral bay nan analiz modèl yo yon ti kras pita.

Echanj nan

Yon pwen echanj se yon pwosesis messagerie ki aplike lojik entèraksyon ak eleman ki nan modèl mesaj la. Nan tout egzanp ki anba yo, eleman yo kominike atravè pwen echanj, konbinezon an ki fòme mesaj.

Modèl echanj mesaj (MEPs)

Globalman, modèl echanj yo ka divize an de-bò ak yon sèl-side. Ansyen an vle di yon repons pou mesaj k ap vini an, dènye a pa fè sa. Yon egzanp klasik yon modèl de-fason nan yon achitekti kliyan-sèvè se modèl demann-repons. Konsidere modèl la ak modifikasyon li yo.

Demann-repons oswa RPC

RPC yo itilize lè nou bezwen jwenn yon repons nan yon lòt pwosesis. Pwosesis sa a ka kouri sou menm lame a oswa sou yon kontinan diferan. Anba a se yon dyagram nan entèraksyon ki genyen ant kliyan an ak sèvè a atravè mesaj.

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Depi mesaj yo konplètman asynchrone, echanj la pou kliyan an divize an 2 faz:

  1. Voye yon demann

    messaging:request(Exchange, ResponseMatchingTag, RequestDefinition, HandlerProcess).

    echanj ‒ non inik pwen echanj
    ResponseMatchingTag ‒ etikèt lokal pou trete repons lan. Pou egzanp, nan ka voye plizyè demann ki idantik ki fè pati itilizatè diferan.
    Demann Definisyon ‒ demann kò
    HandlerProcess ‒ PID moun k ap okipe a. Pwosesis sa a pral resevwa yon repons nan men sèvè a.

  2. Pwosesis repons

    handle_info(#'$msg'{exchange = EXCHANGE, tag = ResponseMatchingTag,message = ResponsePayload}, State)

    ResponsePayload - repons sèvè.

Pou sèvè a, pwosesis la tou konsiste de 2 faz:

  1. Inisyalizasyon pwen echanj
  2. Pwosesis demann k ap vini yo

Ann ilistre modèl sa a ak kòd. Ann di ke nou bezwen aplike yon sèvis senp ki bay yon sèl metòd tan presi.

Kòd sèvè

Ann deplase definisyon API sèvis la nan 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{}
}).

Defini kontwolè sèvis la nan 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.

Kòd kliyan

Pou voye yon demann nan yon sèvis, ou ka rele API demann mesaj nenpòt kote sou kliyan an:

case messaging:request(?EXCHANGE, tag, #time_req{opts = #{}}, self()) of
    ok -> ok;
    _ -> %% repeat or fail logic
end

Nan yon sistèm distribiye, konfigirasyon konpozan yo ka trè diferan, epi nan moman demann lan, mesaj yo ka poko kòmanse, oswa kontwolè sèvis la p ap pare pou sèvi demann lan. Se poutèt sa, nou bezwen tcheke repons mesaj la ak okipe ka echèk la.
Apre yon siksè voye bay kliyan an, sèvis la pral resevwa yon repons oswa yon erè.
Ann okipe tou de ka yo nan 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};

Demann-Repons an fragman

Li pi bon pou evite voye gwo mesaj. Reyaksyon an ak operasyon ki estab nan tout sistèm nan depann sou sa a. Si repons lan nan yon demann pran anpil memwa, Lè sa a, divize obligatwa.

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Men kèk egzanp nan ka sa yo:

  • Konpozan echanj done binè, tankou dosye. Kraze repons lan an ti pati ede travay avèk efikasite ak dosye nenpòt gwosè epi yo pa trape debòde memwa.
  • Anons. Pou egzanp, nou bezwen chwazi tout dosye ki soti nan yon tab gwo nan baz done a epi pase li nan yon lòt eleman.

Mwen rele repons sa yo yon lokomotiv. Nan nenpòt ka, 1024 mesaj 1MB pi bon pase yon sèl mesaj 1GB.

Nan gwoup Erlang la, nou jwenn yon benefis adisyonèl - diminye chaj la sou pwen echanj la ak rezo a, depi repons yo imedyatman voye bay moun k ap resevwa a, contournement pwen echanj la.

Repons ak demann

Sa a se yon modifikasyon olye ra nan modèl la RPC pou bati sistèm konvèsasyon.

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Pibliye-abònman (pyebwa distribisyon done)

Sistèm ki baze sou evènman yo delivre done bay konsomatè yo le pli vit ke li pare. Kidonk, sistèm yo gen plis tandans fè modèl pouse pase modèl rale oswa sondaj la. Karakteristik sa a pèmèt ou pa gaspiye resous lè w toujou ap mande epi tann done yo.
Figi a montre pwosesis pou distribye yon mesaj bay konsomatè ki abònman nan yon sijè an patikilye.

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Egzanp klasik lè l sèvi avèk modèl sa a se distribisyon an nan eta: mond lan jwèt nan jwèt sou òdinatè, done sou mache sou echanj, enfòmasyon itil nan manje done.

Konsidere kòd abònen an:

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.

Sous la ka rele fonksyon piblikasyon mesaj la nan nenpòt kote ki bon:

messaging:publish_message(Exchange, Key, Message).

echanj - non pwen echanj la,
Kle ‒ kle routage
Mesaj - chaj

Envèse Pibliye Abònman

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Lè w deplwaye pub-sub, ou ka jwenn yon modèl ki bon pou antre. Ansanm sous yo ak konsomatè yo ka konplètman diferan. Figi a montre yon ka ak yon sèl konsomatè ak anpil sous.

Modèl distribisyon travay

Nan prèske chak pwojè, gen travay nan pwosesis difere, tankou jenere rapò, livrezon notifikasyon, ak resevwa done ki soti nan sistèm twazyèm pati. Debi a nan yon sistèm ki fè travay sa yo fasil echèl pa ajoute processeurs. Tout sa ki rete pou nou se fòme yon gwoup processeurs ak respire distribye travay ant yo.

Konsidere sitiyasyon ki rive lè l sèvi avèk egzanp 3 moun kap okipe yo. Menm nan etap nan distribisyon travay yo, kesyon an nan jistis la nan distribisyon ak debòde nan moun kap okipe yo rive. Distribisyon round-robin la pral responsab pou jistis, ak nan lòd pou fè pou evite yon sitiyasyon debòde nan moun kap okipe yo, nou prezante yon restriksyon. prefetch_limit. Nan mòd tranzisyon prefetch_limit p ap pèmèt yon sèl moun kap okipe yo resevwa tout travay yo.

Messaging jere ke moun kap kriye ak priyorite pwosesis. Processeurs resevwa travay jan yo rive. Travay la ka konplete avèk siksè oswa echwe:

  • messaging:ack(Tack) ‒ rele nan ka ta gen siksè pwosesis nan mesaj la
  • messaging:nack(Tack) ‒ rele nan tout sitiyasyon ijans. Apre travay la retounen, mesaj ap pase l bay yon lòt moun kap okipe l.

Blòk konstriksyon aplikasyon distribiye. Premye apwòch

Ann sipoze ke pandan y ap trete twa travay, yon echèk konplèks te fèt: moun k ap okipe 1, apre li fin resevwa travay la, te fè aksidan san yo pa gen tan rapòte anyen nan pwen echanj la. Nan ka sa a, pwen echanj la pral transfere travay la nan yon lòt moun kap okipe apre tan ack la fin ekspire. Manadjè 3 pou kèk rezon abandone travay la epi li voye yon nack, kòm yon rezilta, travay la tou pase nan yon lòt moun k ap okipe li avèk siksè.

Rezime preliminè

Nou te kraze blòk bilding debaz yo nan sistèm distribiye ak te vin jwenn yon konpreyansyon debaz sou itilizasyon yo nan Erlang/Elixir.

Lè yo konbine modèl debaz yo, paradigm konplèks yo ka bati pou rezoud pwoblèm émergentes.

Nan pati final la nan sik la, nou pral konsidere pwoblèm jeneral nan òganize sèvis, routage ak balanse, epi tou pale sou bò pratik nan évolutivité ak tolerans fay nan sistèm yo.

Fen dezyèm pati a.

Photo tire Marius Christensen
Koutwazi ilistrasyon nan websequencediagrams.com

Sous: www.habr.com

Add nouvo kòmantè