Mgbakwunye ụdị BPM

Mgbakwunye ụdị BPM

Ndewo Habr!

Anyị ụlọ ọrụ specializes na mmepe nke ERP-klas software ngwọta, ọdụm òkè nke na-ji na azụmahịa usoro na a nnukwu ego nke azụmahịa mgbagha na akwụkwọ eruba a la EDMS. Ụdị ngwaahịa anyị dị ugbu a dabere na teknụzụ JavaEE, mana anyị na-eji obere ọrụ na-anwale ike. Otu n'ime nsogbu kachasị njọ nke ngwọta ndị dị otú ahụ bụ njikọta nke sistemụ subsystem dị iche iche dị na ngalaba ndị dị n'akụkụ. Nsogbu mbanye na-enye anyị nnukwu isi ọwụwa mgbe niile, n'agbanyeghị ụdị ụkpụrụ ụlọ, teknụzụ teknụzụ na usoro anyị na-eji, mana n'oge na-adịbeghị anya enweela ọganihu n'ịdozi nsogbu ndị dị otú ahụ.

N'ime edemede m na-ewetara gị, m ga-ekwu maka ahụmịhe na nyocha ụlọ nke NPO Krista nwere na mpaghara a họpụtara. Anyị ga-elekwa anya n'ihe atụ nke ngwọta dị mfe maka nsogbu ntinye aka site na echiche nke onye mmepụta ngwa ma chọpụta ihe zoro ezo n'azụ ịdị mfe a.

Nkwuputa

Ngwọta ụkpụrụ ụlọ na teknụzụ akọwara n'isiokwu a bụ nke m tụrụ aro dabere na ahụmịhe nkeonwe na ọnọdụ nke ọrụ akọwapụtara. Ngwọta ndị a anaghị ekwu na ọ bụ ụwa niile ma nwee ike ọ gaghị adị mma n'okpuru ọnọdụ ojiji ndị ọzọ.

Kedu ihe jikọrọ BPM na ya?

Iji zaa ajụjụ a, anyị kwesịrị inyocha ntakịrị omimi n'ime nkọwa nke nsogbu etinyere nke ngwọta anyị. Akụkụ bụ isi nke mgbagha azụmaahịa na sistemụ azụmahịa anyị na-ahụkarị bụ ịbanye data n'ime nchekwa data site na ntanetị onye ọrụ, akwụkwọ ntuziaka na nkwenye akpaghị aka nke data a, na-eme ya site na usoro ụfọdụ, na-ebipụta ya na sistemụ ọzọ / nchekwa data nyocha / ebe nchekwa, na-ewepụta akụkọ. . Ya mere, isi ọrụ nke usoro maka ndị ahịa bụ akpaaka nke usoro azụmahịa ha dị n'ime.

Maka ịdị mma, anyị na-eji okwu ahụ bụ "akwụkwọ" na nzikọrịta ozi dị ka ụfọdụ abstraction nke otu data jikọtara ya na igodo nkịtị nke ụfọdụ usoro ọrụ nwere ike "jikọọ".
Ma gịnị banyere mgbagha mwekota? A sị ka e kwuwe, ọrụ ntinye aka na-emepụta site na nhazi nke usoro ahụ, nke a na-ebipụ n'ime akụkụ ọ bụghị na arịrịọ nke onye ahịa, kama n'okpuru mmetụta nke ihe dị iche iche:

  • n'okpuru iwu Conway;
  • n'ihi ijikwa subsystem nke emebere mbụ maka ngwaahịa ndị ọzọ;
  • n'aka onye na-ese ụkpụrụ ụlọ, dabere na ihe ndị na-adịghị arụ ọrụ chọrọ.

E nwere oké ọnwụnwa ikewa mwekota mgbagha si azụmahịa mgbagha nke isi workflow, nke mere ka ọ ghara imerụ azụmahịa mgbagha na mwekota artifacts na-azọpụta ngwa Mmepụta si mkpa delve n'ime atụmatụ nke architectural odida obodo nke usoro. Ụzọ a nwere ọtụtụ uru, mana omume na-egosi adịghị arụ ọrụ ya:

  • idozi nsogbu mwekota na-adaba azụ na nhọrọ ndị kachasị mfe n'ụdị oku na-emekọrịta ihe n'ihi njedebe ndọtị dị oke na mmejuputa isi ọrụ (a na-atụle adịghị ike nke njikọta synchronous n'okpuru ebe a);
  • arịa mwekota ka na-abanye n'echiche azụmaahịa mgbe achọrọ nzaghachi sitere na sistemụ ọzọ;
  • onye nrụpụta ngwa na-eleghara ntinye aka ma nwee ike imebi ya ngwa ngwa site n'ịgbanwe usoro ọrụ;
  • Sistemu na-akwụsị ịbụ otu dum site n'echiche onye ọrụ, "nhịahụ" n'etiti subsystems na-apụta ìhè, na ọrụ ndị ọrụ na-adịghị arụ ọrụ na-apụta, na-amalite ịnyefe data site na otu subsystem gaa na nke ọzọ.

Ụzọ ọzọ bụ ịtụle mmekọrịta mmekọrịta dị ka akụkụ dị mkpa nke isi mgbagha azụmahịa na usoro ọrụ. Iji gbochie ntozu onye nrụpụta ngwa ka ọ ghara ịdị elu, ịmepụta mmekọrịta ọhụrụ nke njikọta kwesịrị ịdị mfe na enweghị mgbalị, yana nhọrọ kacha nta maka ịhọrọ ngwọta. Nke a siri ike ime karịa ka o siri dị: ngwá ọrụ ahụ aghaghị ịdị ike nke ukwuu iji nye onye ọrụ nhọrọ dịgasị iche iche achọrọ maka ojiji ya, na-enyeghị ya ohere "gbaa onwe ya n'ụkwụ." Enwere ọtụtụ ajụjụ onye injinia ga-aza n'ihe gbasara ọrụ ntinye aka, mana nke onye nrụpụta ngwa ekwesịghị iche echiche n'ọrụ ya kwa ụbọchị: oke azụmahịa, nkwụsi ike, atomity, nchekwa, scaling, ibu na nkesa akụrụngwa, ụzọ ụgbọ mmiri, ịhịa aka n'ahụ. nkesa na ịmafe ọnọdụ, wdg Ọ dị mkpa na-enye ngwa mmepe pụtara mfe ngwọta ndebiri nke azịza niile dị otú ahụ ajụjụ na-ama zoro ezo. Ndebiri ndị a ga-adị mma nke ọma: mgbanwe mgbagha azụmahịa na-agbanwe ọtụtụ oge, nke na-abawanye ohere nke iwebata njehie, ọnụ ahịa njehie ga-anọgide na ọkwa dị ala.

Mana kedu ihe jikọrọ BPM na ya? Enwere ọtụtụ nhọrọ iji mejuputa usoro ọrụ ...
N'ezie, ọzọ mmejuputa iwu usoro azụmahịa bụ nnọọ ewu ewu na anyị ngwọta - site declarative nkọwa nke a steeti mgbanwe eserese na njikọ nke handlers na azụmahịa mgbagha maka mgbanwe. N'okwu a, steeti na-ekpebi ọnọdụ dị ugbu a nke "akwụkwọ" na usoro azụmahịa bụ àgwà nke "akwụkwọ" n'onwe ya.

Mgbakwunye ụdị BPM
Nke a bụ otú usoro a si dị na mmalite nke ọrụ

Ihe ewu ewu nke mmejuputa a bụ n'ihi ịdị mfe dị mfe na ọsọ nke ịmepụta usoro azụmahịa linear. Agbanyeghị, ka sistemụ sọftụwia na-aga n'ihu na-adị mgbagwoju anya, akụkụ akpaaka nke usoro azụmaahịa na-eto ma na-adịkwa mgbagwoju anya. Enwere mkpa maka ire ere, iji akụkụ nke usoro, yana usoro alaka nke mere na alaka ọ bụla na-egbu ya n'otu oge. N'okpuru ọnọdụ ndị dị otú ahụ, ngwá ọrụ ahụ na-aghọ ihe na-adịghị mma, na eserese mgbanwe nke steeti na-efunahụ ọdịnaya ozi ya (mmekọrịta mmekọrịta adịghị egosipụta na eserese ahụ ma ọlị).

Mgbakwunye ụdị BPM
Nke a bụ ihe usoro a dị ka mgbe ọtụtụ iteration nke nkọwa chọrọ.

Ụzọ isi na ọnọdụ a bụ njikọ nke engine jBPM n'ime ụfọdụ ngwaahịa na ndị kasị mgbagwoju azụmahịa usoro. N'oge dị mkpirikpi, ngwọta a nwere ụfọdụ ihe ịga nke ọma: ọ bịara kwe omume ịmejuputa usoro azụmahịa dị mgbagwoju anya mgbe ị na-ejigide ihe ngosi ziri ezi na nke dị mkpa na ntinye akwụkwọ. BPMN2.

Mgbakwunye ụdị BPM
Obere akụkụ nke usoro azụmahịa dị mgbagwoju anya

N'ime ogologo oge, ihe ngwọta ahụ emeghị ka ihe ndị a tụrụ anya ya: nnukwu ọrụ ike nke ịmepụta usoro azụmahịa site na ngwá ọrụ a na-ahụ anya ekweghị ka ọ nweta ihe ngosi mmepụta ihe a na-anabata, na ngwá ọrụ ahụ n'onwe ya ghọrọ otu n'ime ndị na-emepụta ihe na-enweghị mmasị na ya. E nwekwara mkpesa banyere nhazi ime nke engine, nke mere ka ọtụtụ "patches" na "crutches" pụta ìhè.

Akụkụ dị mma nke iji jBPM bụ ịmara uru na ọghọm dị n'inwe usoro azụmaahịa nke onwe ya na-adịgide adịgide. Anyị hụkwara ohere nke iji usoro usoro iji mejuputa usoro nkwekọrịta mgbagwoju anya n'etiti ngwa dị iche iche site na iji mmekọrịta asynchronous site na akara na ozi. Ọnụnọ nke steeti na-adịgide adịgide na-ekere òkè dị mkpa na nke a.

Dabere na nke dị n'elu, anyị nwere ike ikwubi: Usoro usoro n'ụdị BPM na-enye anyị ohere idozi ọtụtụ ọrụ iji megharịa usoro azụmahịa siri ike na-esiwanye ike, nkwekọ dabara adaba na mmemme ntinye n'ime usoro ndị a ma nọgide na-enwe ike iji anya na-egosipụta usoro etinyere n'akwụkwọ dị mma.

Ọdịmma nke oku na-emekọrịta ihe dị ka ụkpụrụ njikọta

Njikọ mmekọrịta na-ezo aka na nkwụsị kacha mfe. Otu obere sistemụ na-arụ ọrụ dị ka akụkụ nkesa wee kpughee API site na usoro achọrọ. Sistemụ subsystem ọzọ na-arụ ọrụ dị ka akụkụ ndị ahịa na n'oge kwesịrị ekwesị na-akpọ oku wee chere nsonaazụ ya. Dabere na usoro nhazi usoro, ndị ahịa na akụkụ nkesa nwere ike ịnọ n'otu ngwa na usoro, ma ọ bụ na ndị dị iche iche. N'okwu nke abụọ, ịkwesịrị itinye ụfọdụ mmejuputa RPC ma nye nhazi nke paramita na nsonaazụ oku a.

Mgbakwunye ụdị BPM

Usoro nchikota a nwere nnukwu ihe ọghọm, mana a na-ejikarị ya eme ihe n'ihi ịdị mfe ya. The ọsọ nke mmejuputa iwu captivates na-amanye gị na-eji ya ugboro ugboro na ihu nke ịpị deadlines, na-edekọ ihe ngwọta dị ka teknuzu ụgwọ. Ma ọ na-emekwa na ndị mmepe na-enweghị ahụmahụ na-eji ya eme ihe n'amaghị ama, na-aghọtaghị ihe ọjọọ na-esi na ya pụta.

Na mgbakwunye na mmụba kachasị pụta ìhè na njikọta nke sistemụ subsystem, enwekwara nsogbu ndị na-apụtachaghị ìhè na azụmahịa "eto eto" na "ịgbatị". N'ezie, ọ bụrụ na mgbagha azụmahịa na-eme mgbanwe ụfọdụ, mgbe ahụ, azụmahịa enweghị ike ịzere, na azụmahịa, n'aka nke ya, gbochie ụfọdụ ngwa ngwa nke mgbanwe ndị a na-emetụta. Ya bụ, ruo mgbe otu subsystem na-echere nzaghachi site na nke ọzọ, ọ gaghị enwe ike mezue azụmahịa ma wepụ ihe mkpuchi. Nke a na-abawanye nke ukwuu ohere nke mmetụta dị iche iche:

  • Nzaghachi nke usoro ahụ furu efu, ndị ọrụ na-echere ogologo oge maka azịza nke ajụjụ;
  • ihe nkesa na-akwụsịkarị ịza arịrịọ onye ọrụ n'ihi ọdọ mmiri erijujujuju: a na-ekpochi ọtụtụ eri na akụrụngwa nke azụmahịa nwere;
  • Deadlocks na-amalite ịpụta: ohere nke ihe omume ha na-adabere na ogologo oge nke azụmahịa, ọnụ ọgụgụ nke mgbagha azụmahịa na mkpọchi na-etinye aka na azụmahịa ahụ;
  • njehie oge nkwụsị azụmahịa pụtara;
  • ihe nkesa ahụ "ada" na OutOfMemory ma ọ bụrụ na ọrụ ahụ chọrọ nhazi na ịgbanwe nnukwu data, na ọnụnọ nke njikọta synchronous na-eme ka ọ sie ike ikewa nhazi n'ime azụmahịa "ọkụ ọkụ".

Site n'echiche nke ụkpụrụ ụlọ, ojiji nke igbochi oku n'oge njikọta na-eduga n'ịbelata njikwa ogo nke subsystems nke ọ bụla: ọ gaghị ekwe omume iji hụ na egosi akara ngosi nke otu subsystem dịpụrụ adịpụ site na njiri mara mma nke subsystem ọzọ. Ọ bụrụ na ndị otu dị iche iche mepụtara subsystems, nke a bụ nnukwu nsogbu.

Ihe na-adọrọ mmasị karị ma ọ bụrụ na sistemụ subsystem a na-ejikọta dị na ngwa dị iche iche ma ịkwesịrị ịme mgbanwe mmekọrịta n'akụkụ abụọ. Olee otú iji hụ na azụmahịa mgbanwe ndị a?

Ọ bụrụ na a na-eme mgbanwe na azụmahịa dị iche iche, mgbe ahụ, ị ​​​​ga-achọ ịnye njikwa na nkwụghachi ụgwọ a pụrụ ịdabere na ya, nke a na-ewepụ kpamkpam uru bụ isi nke njikọta synchronous - ịdị mfe.

Azụmahịa ekesa na-abatakwa n'uche, mana anyị anaghị eji ha eme ihe na ngwọta anyị: ọ siri ike ịhụ na a pụrụ ịdabere na ya.

"Saga" dị ka ihe ngwọta maka nsogbu azụmahịa

Na-eto eto na-ewu ewu nke microservices, ọchịchọ nke Ụkpụrụ Saga.

Nke a ụkpụrụ n'ụzọ zuru okè solves n'elu-e kwuru nsogbu nke ogologo azụmahịa, na-agbasawanye ike nke ijikwa steeti nke usoro si n'akụkụ nke azụmahịa mgbagha: akwụ ụgwọ mgbe a dara azụmahịa nwere ike ọ gaghị tụgharịa azụ usoro ya mbụ ala, ma nye ya. ụzọ nhazi data ọzọ. Nke a na-enye gị ohere ịzenarị ịmegharị usoro nhazi data emechara nke ọma mgbe ị na-agbalị iweta usoro ahụ na njedebe "dị mma".

N'ụzọ na-akpali mmasị, na usoro monolithic ụkpụrụ a dịkwa mkpa ma a bịa n'ịmekọrịta nke subsystems na-adịghị ejikọta ya na mmetụta ọjọọ nke azụmahịa na-eme ogologo oge na-akpata na a na-ahụ mkpọchi akụ dabara.

N'ihe metụtara usoro azụmahịa anyị na ụdị BPM, ọ na-apụta na ọ dị mfe iji mejuputa "Sagas": usoro nke "Saga" nke ọ bụla nwere ike ịkọwa dị ka ihe omume n'ime usoro azụmahịa, yana ọnọdụ azụmahịa na-adịgide adịgide. na-ekpebi ime obodo nke "Saga". Ya bụ, anyị achọghị usoro nhazi ọzọ ọ bụla. Naanị ihe ị chọrọ bụ onye na-ere ahịa ozi na-akwado nkwa “opekata mpe otu oge” dịka ụgbọ njem.

Mana ngwọta a nwekwara “ọnụahịa” nke ya:

  • mgbagha azụmahịa na-aghọwanye mgbagwoju anya: nkwụghachi ụgwọ kwesịrị ịrụ ọrụ;
  • ọ ga-adị mkpa ịhapụ nkwụsi ike zuru oke, nke nwere ike ịdị nro karịsịa maka usoro monolithic;
  • Ihe owuwu ahụ na-aghọ ntakịrị mgbagwoju anya, na mkpa ọzọ maka onye na-ere ahịa ozi pụtara;
  • A ga-achọrọ nlekota ọzọ na ngwaọrụ nchịkwa (ọ bụ ezie na n'ozuzu nke a dị mma: àgwà nke ọrụ usoro ga-abawanye).

Maka usoro monolithic, izi ezi maka iji "Sag" abụghị ihe doro anya. Maka microservices na SOA ndị ọzọ, ebe o yikarịrị ka enweelarị onye na-ere ahịa, na a na-achụkwa nkwụsi ike zuru ezu na mmalite nke ọrụ ahụ, uru nke iji ụkpụrụ a nwere ike ịkawanye njọ, karịsịa ma ọ bụrụ na e nwere API dị mma na mgbagha azụmahịa. ọkwa.

Na-akwalite mgbagha azụmahịa na microservices

Mgbe anyị malitere ịnwale na microservices, ajụjụ ezi uche dị na ya bilitere: ebe ị ga-etinye mgbagha azụmahịa nke ngalaba n'ihe metụtara ọrụ ahụ na-eme ka nkwụsi ike nke data ngalaba?

Mgbe ị na-eleba anya na nhazi nke BPMS dị iche iche, ọ nwere ike iyi ihe ezi uche dị na ya ikewapụta echiche azụmahịa na nnọgidesi ike: mepụta oyi akwa nke ikpo okwu na ngalaba na-adabere na microservices nke na-etolite gburugburu na akpa maka imezu ebumnuche azụmahịa ngalaba, ma chepụta nnọgidesi ike nke data ngalaba dị ka oyi akwa dị iche iche nke microservices dị mfe ma dị fechaa. Usoro azụmahịa na nke a na-arụ ọrụ orchestration nke ọrụ nke ntachi obi.

Mgbakwunye ụdị BPM

Ụzọ a nwere nnukwu uru: ị nwere ike ịbawanye ọrụ nke ikpo okwu dị ka ịchọrọ, na naanị oyi akwa nke microservices nke ikpo okwu ga-abụ "abụba" site na nke a. Usoro azụmahịa sitere na ngalaba ọ bụla na-enwe ike ozugbo iji ọrụ ọhụrụ nke ikpo okwu ozugbo emelitere.

Nnyocha e mere n'ụzọ zuru ezu gosipụtara nnukwu ọghọm dị na ụzọ a:

  • ọrụ ikpo okwu nke na-eme atụmatụ azụmahịa nke ọtụtụ ngalaba n'otu oge na-ebu nnukwu ihe ize ndụ dị ka otu ebe ọdịda. Mgbanwe ugboro ugboro na mgbagha azụmahịa na-abawanye ohere nke njehie na-eduga na ọdịda nke sistemu;
  • nsogbu arụmọrụ: mgbagha azụmahịa na-arụ ọrụ na data ya site na interface dị warara na ngwa ngwa:
    • A ga-ekpochapụ data ahụ ọzọ wee gbasaa site na nchịkọta netwọkụ;
    • ọrụ ngalaba ga-enyekarị data karịa ka achọrọ maka mgbagha azụmahịa iji hazie n'ihi enweghị ike zuru oke maka itinye arịrịọ na ọkwa API mpụga nke ọrụ ahụ;
    • ọtụtụ akụkụ nke nnwere onwe nke azụmahịa nwere ike ịrịọ otu data ahụ ugboro ugboro maka nhazi (nsogbu a nwere ike ibelata site n'ịgbakwunye akụkụ nnọkọ nke na-echekwa data, ma nke a na-eme ka nhazi ahụ dịkwuo mgbagwoju anya ma na-emepụta nsogbu nke data mkpa na cache invalidation);
  • nsogbu azụmahịa:
    • Usoro azụmahịa na steeti na-adịgide adịgide, nke a na-echekwa site na ọrụ ikpo okwu, na-ekwekọghị na data ngalaba, ọ dịghịkwa ụzọ dị mfe iji dozie nsogbu a;
    • ịtụkwasị data ngalaba na-egbochi n'èzí azụmahịa ahụ: ọ bụrụ na mgbagha azụmahịa nke ngalaba kwesịrị ime mgbanwe mgbe mbụ ịlele izi ezi nke data dị ugbu a, ọ dị mkpa iji wepụ ohere nke mgbanwe asọmpi na data nhazi. Mgbochi data mpụga nwere ike inye aka dozie nsogbu ahụ, mana ngwọta dị otú ahụ na-ebute ihe ize ndụ ndị ọzọ ma belata ntụkwasị obi zuru ezu nke usoro ahụ;
  • ihe isi ike ndị ọzọ mgbe ị na-emelite: n'ọnọdụ ụfọdụ, ọrụ nnọgidesi ike na mgbagha azụmaahịa kwesịrị imelite ya n'otu oge ma ọ bụ n'usoro siri ike.

N'ikpeazụ, anyị ga-alaghachi na isi ihe: tinye data ngalaba na mgbagha azụmahịa n'ime otu microservice. Ụzọ a na-eme ka nghọta nke microservice dị mfe dị ka akụkụ dị mkpa nke usoro ahụ ma ọ dịghị ebute nsogbu ndị dị n'elu. Anaghịkwa nke a n'efu:

  • Achọrọ nhazi API maka mmekọrịta ya na mgbagha azụmahịa (karịsịa, iji nye ọrụ ndị ọrụ dịka akụkụ nke usoro azụmahịa) na ọrụ ikpo okwu API; chọrọ nlebara anya nke ọma na mgbanwe API, ndakọrịta n'ihu na azụ;
  • ọ dị mkpa ịgbakwunye ọba akwụkwọ oge ọzọ iji hụ na arụ ọrụ nke mgbagha azụmahịa dị ka akụkụ nke microservice nke ọ bụla, nke a na-ebutekwa ihe ọhụrụ a chọrọ maka ụlọ akwụkwọ ndị dị otú ahụ: ìhè na opekempe nke ndabere transitive;
  • Ndị mmepe mgbagha azụmaahịa kwesịrị inyocha ụdị ọba akwụkwọ: ọ bụrụ na emechabeghị microservice ogologo oge, mgbe ahụ ọ ga-abụrịrị na ọ nwere ụdị ọba akwụkwọ ochie. Nke a nwere ike ịbụ ihe mgbochi a na-atụghị anya ya n'ịgbakwunye atụmatụ ọhụrụ yana nwere ike ịchọ ịkwaga mgbagha azụmahịa ochie nke ọrụ dị otú ahụ gaa na ụdị ọba akwụkwọ ọhụrụ ma ọ bụrụ na enwere mgbanwe na-ekwekọghị n'etiti nsụgharị.

Mgbakwunye ụdị BPM

A oyi akwa nke n'elu ikpo okwu ọrụ na-dị na dị otú ahụ architecture, ma oyi akwa anaghịzi emepụta akpa maka imezu ngalaba azụmahịa mgbagha, ma naanị ya gburugburu ebe obibi, na-enye inyeaka "ikpo okwu" ọrụ. Ụdị oyi akwa dị otú ahụ dị mkpa ọ bụghị nanị iji nọgide na-enwe ọdịdị dị arọ nke ngalaba microservices, kamakwa iji dozie njikwa.

Dịka ọmụmaatụ, ọrụ onye ọrụ na usoro azụmahịa na-emepụta ọrụ. Agbanyeghị, mgbe ị na-arụ ọrụ, onye ọrụ ga-ahụrịrị ọrụ sitere na ngalaba niile na ndepụta izugbe, nke pụtara na a ga-enwerịrị ọrụ ndebanye aha n'elu ikpo okwu kwekọrọ, kpochapụrụ na mgbagha azụmahịa ngalaba. Ịnọgide na-enwe mmetụta nke mgbagha azụmahịa n'ọnọdụ dị otú ahụ bụ nnọọ nsogbu, nke a bụkwa ihe ọzọ na-emebi ụkpụrụ ụlọ a.

Njikọ nke usoro azụmahịa site n'anya onye mmepụta ngwa

Dịka ekwuru n'elu, a ga-ewepụrịrị onye nrụpụta ngwa site na njirimara teknụzụ na injinia nke imejuputa mmekọrịta nke ọtụtụ ngwa ka mmadụ wee nwee ike ịdabere na nrụpụta mmepe dị mma.

Ka anyị gbalịa dozie nsogbu mwekota siri ike, nke emepụtara maka edemede ahụ. Nke a ga-abụ ọrụ "egwuregwu" gụnyere ngwa atọ, ebe nke ọ bụla n'ime ha na-akọwa otu ngalaba aha: "app1", "app2", "app3".

N'ime ngwa ọ bụla, a na-amalite usoro azụmahịa nke na-amalite "egwu bọọlụ" site na bọs ntinye. Ozi nwere aha "Bọọlụ" ga-arụ ọrụ dị ka bọọlụ.

Iwu nke egwuregwu ahụ:

  • mbụ l'iphe bụ onye ishi. Ọ na-akpọ ndị egwuregwu ndị ọzọ òkù ịbịa egwuregwu ahụ, malite egwuregwu ahụ ma nwee ike ịkwụsị ya n'oge ọ bụla;
  • ndị egwuregwu ndị ọzọ na-ekwupụta na ha na-ekere òkè na egwuregwu ahụ, "mara" ibe ha na onye ọkpụkpọ mbụ;
  • mgbe ọ natachara bọọlụ ahụ, onye ọkpụkpọ na-ahọrọ onye ọkpụkpọ ọzọ na-esonye ma nyefee ya bọọlụ ahụ. A na-agụta ọnụ ọgụgụ nke nnyefe;
  • Onye ọkpụkpọ ọ bụla nwere “ike” nke na-ebelata site na ngafe ọ bụla nke bọọlụ onye ọkpụkpọ ahụ. Mgbe ike gwụrụ, onye ọkpụkpọ na-ahapụ egwuregwu ahụ, na-ekwupụta arụkwaghịm ya;
  • ọ bụrụ na onye ọkpụkpọ ahụ hapụrụ naanị ya, ọ na-ekwupụta na ọ ga-apụ ozugbo;
  • Mgbe ewepụrụ ndị egwuregwu niile, onye ọkpụkpọ mbụ na-ekwupụta egwuregwu ahụ agwụla. Ọ bụrụ na ọ hapụ egwuregwu ahụ n'oge, ọ na-anọgide na-eso egwuregwu ahụ iji wuchaa ya.

Iji dozie nsogbu a, m ga-eji DSL anyị maka usoro achụmnta ego, nke na-enye anyị ohere ịkọwa echiche dị na Kotlin n'otu n'otu, na opekempe nke efere efere.

Usoro azụmahịa nke onye ọkpụkpọ mbụ (aka onye mmalite egwuregwu) ga-arụ ọrụ na ngwa ngwa 1:

klas InitialPlayer

import ru.krista.bpm.ProcessInstance
import ru.krista.bpm.runtime.ProcessImpl
import ru.krista.bpm.runtime.constraint.UniqueConstraints
import ru.krista.bpm.runtime.dsl.processModel
import ru.krista.bpm.runtime.dsl.taskOperation
import ru.krista.bpm.runtime.instance.MessageSendInstance

data class PlayerInfo(val name: String, val domain: String, val id: String)

class PlayersList : ArrayList<PlayerInfo>()

// Это класс экземпляра процесса: инкапсулирует его внутреннее состояние
class InitialPlayer : ProcessImpl<InitialPlayer>(initialPlayerModel) {
    var playerName: String by persistent("Player1")
    var energy: Int by persistent(30)
    var players: PlayersList by persistent(PlayersList())
    var shotCounter: Int = 0
}

// Это декларация модели процесса: создается один раз, используется всеми
// экземплярами процесса соответствующего класса
val initialPlayerModel = processModel<InitialPlayer>(name = "InitialPlayer",
                                                     version = 1) {

    // По правилам, первый игрок является инициатором игры и должен быть единственным
    uniqueConstraint = UniqueConstraints.singleton

    // Объявляем активности, из которых состоит бизнес-процесс
    val sendNewGameSignal = signal<String>("NewGame")
    val sendStopGameSignal = signal<String>("StopGame")
    val startTask = humanTask("Start") {
        taskOperation {
            processCondition { players.size > 0 }
            confirmation { "Подключилось ${players.size} игроков. Начинаем?" }
        }
    }
    val stopTask = humanTask("Stop") {
        taskOperation {}
    }
    val waitPlayerJoin = signalWait<String>("PlayerJoin") { signal ->
        players.add(PlayerInfo(
                signal.data!!,
                signal.sender.domain,
                signal.sender.processInstanceId))
        println("... join player ${signal.data} ...")
    }
    val waitPlayerOut = signalWait<String>("PlayerOut") { signal ->
        players.remove(PlayerInfo(
                signal.data!!,
                signal.sender.domain,
                signal.sender.processInstanceId))
        println("... player ${signal.data} is out ...")
    }
    val sendPlayerOut = signal<String>("PlayerOut") {
        signalData = { playerName }
    }
    val sendHandshake = messageSend<String>("Handshake") {
        messageData = { playerName }
        activation = {
            receiverDomain = process.players.last().domain
            receiverProcessInstanceId = process.players.last().id
        }
    }
    val throwStartBall = messageSend<Int>("Ball") {
        messageData = { 1 }
        activation = { selectNextPlayer() }
    }
    val throwBall = messageSend<Int>("Ball") {
        messageData = { shotCounter + 1 }
        activation = { selectNextPlayer() }
        onEntry { energy -= 1 }
    }
    val waitBall = messageWaitData<Int>("Ball") {
        shotCounter = it
    }

    // Теперь конструируем граф процесса из объявленных активностей
    startFrom(sendNewGameSignal)
            .fork("mainFork") {
                next(startTask)
                next(waitPlayerJoin).next(sendHandshake).next(waitPlayerJoin)
                next(waitPlayerOut)
                        .branch("checkPlayers") {
                            ifTrue { players.isEmpty() }
                                    .next(sendStopGameSignal)
                                    .terminate()
                            ifElse().next(waitPlayerOut)
                        }
            }
    startTask.fork("afterStart") {
        next(throwStartBall)
                .branch("mainLoop") {
                    ifTrue { energy < 5 }.next(sendPlayerOut).next(waitBall)
                    ifElse().next(waitBall).next(throwBall).loop()
                }
        next(stopTask).next(sendStopGameSignal)
    }

    // Навешаем на активности дополнительные обработчики для логирования
    sendNewGameSignal.onExit { println("Let's play!") }
    sendStopGameSignal.onExit { println("Stop!") }
    sendPlayerOut.onExit { println("$playerName: I'm out!") }
}

private fun MessageSendInstance<InitialPlayer, Int>.selectNextPlayer() {
    val player = process.players.random()
    receiverDomain = player.domain
    receiverProcessInstanceId = player.id
    println("Step ${process.shotCounter + 1}: " +
            "${process.playerName} >>> ${player.name}")
}

Na mgbakwunye na imezu echiche azụmahịa, koodu dị n'elu nwere ike ịmepụta ihe nlereanya nke usoro azụmahịa, nke nwere ike ịhụ anya n'ụdị eserese. Anyị emebeghị ihe ngosi ahụ, yabụ anyị ga-etinye obere oge ịbịaru (ebe a ka m mere ntakịrị nkọwa BPMN gbasara iji ọnụ ụzọ ámá iji meziwanye ngbanwe nke eserese ahụ na koodu dị n'okpuru):

Mgbakwunye ụdị BPM

app2 ga-agụnye usoro azụmahịa nke onye ọkpụkpọ nke ọzọ:

klas RandomPlayer

import ru.krista.bpm.ProcessInstance
import ru.krista.bpm.runtime.ProcessImpl
import ru.krista.bpm.runtime.dsl.processModel
import ru.krista.bpm.runtime.instance.MessageSendInstance

data class PlayerInfo(val name: String, val domain: String, val id: String)

class PlayersList: ArrayList<PlayerInfo>()

class RandomPlayer : ProcessImpl<RandomPlayer>(randomPlayerModel) {

    var playerName: String by input(persistent = true, 
                                    defaultValue = "RandomPlayer")
    var energy: Int by input(persistent = true, defaultValue = 30)
    var players: PlayersList by persistent(PlayersList())
    var allPlayersOut: Boolean by persistent(false)
    var shotCounter: Int = 0

    val selfPlayer: PlayerInfo
        get() = PlayerInfo(playerName, env.eventDispatcher.domainName, id)
}

val randomPlayerModel = processModel<RandomPlayer>(name = "RandomPlayer", 
                                                   version = 1) {

    val waitNewGameSignal = signalWait<String>("NewGame")
    val waitStopGameSignal = signalWait<String>("StopGame")
    val sendPlayerJoin = signal<String>("PlayerJoin") {
        signalData = { playerName }
    }
    val sendPlayerOut = signal<String>("PlayerOut") {
        signalData = { playerName }
    }
    val waitPlayerJoin = signalWaitCustom<String>("PlayerJoin") {
        eventCondition = { signal ->
            signal.sender.processInstanceId != process.id 
                && !process.players.any { signal.sender.processInstanceId == it.id}
        }
        handler = { signal ->
            players.add(PlayerInfo(
                    signal.data!!,
                    signal.sender.domain,
                    signal.sender.processInstanceId))
        }
    }
    val waitPlayerOut = signalWait<String>("PlayerOut") { signal ->
        players.remove(PlayerInfo(
                signal.data!!,
                signal.sender.domain,
                signal.sender.processInstanceId))
        allPlayersOut = players.isEmpty()
    }
    val sendHandshake = messageSend<String>("Handshake") {
        messageData = { playerName }
        activation = {
            receiverDomain = process.players.last().domain
            receiverProcessInstanceId = process.players.last().id
        }
    }
    val receiveHandshake = messageWait<String>("Handshake") { message ->
        if (!players.any { message.sender.processInstanceId == it.id}) {
            players.add(PlayerInfo(
                    message.data!!, 
                    message.sender.domain, 
                    message.sender.processInstanceId))
        }
    }
    val throwBall = messageSend<Int>("Ball") {
        messageData = { shotCounter + 1 }
        activation = { selectNextPlayer() }
        onEntry { energy -= 1 }
    }
    val waitBall = messageWaitData<Int>("Ball") {
        shotCounter = it
    }

    startFrom(waitNewGameSignal)
            .fork("mainFork") {
                next(sendPlayerJoin)
                        .branch("mainLoop") {
                            ifTrue { energy < 5 || allPlayersOut }
                                    .next(sendPlayerOut)
                                    .next(waitBall)
                            ifElse()
                                    .next(waitBall)
                                    .next(throwBall)
                                    .loop()
                        }
                next(waitPlayerJoin).next(sendHandshake).next(waitPlayerJoin)
                next(waitPlayerOut).next(waitPlayerOut)
                next(receiveHandshake).next(receiveHandshake)
                next(waitStopGameSignal).terminate()
            }

    sendPlayerJoin.onExit { println("$playerName: I'm here!") }
    sendPlayerOut.onExit { println("$playerName: I'm out!") }
}

private fun MessageSendInstance<RandomPlayer, Int>.selectNextPlayer() {
    val player = if (process.players.isNotEmpty()) 
        process.players.random() 
    else 
        process.selfPlayer
    receiverDomain = player.domain
    receiverProcessInstanceId = player.id
    println("Step ${process.shotCounter + 1}: " +
            "${process.playerName} >>> ${player.name}")
}

Eserese:

Mgbakwunye ụdị BPM

N'ime ngwa ngwa 3 anyị ga-eme onye ọkpụkpọ nwere omume dịtụ iche: kama ịhọrọ onye ọkpụkpọ na-esote, ọ ga-eme ihe dịka okirikiri robin algọridim:

klas RoundRobinPlayer

import ru.krista.bpm.ProcessInstance
import ru.krista.bpm.runtime.ProcessImpl
import ru.krista.bpm.runtime.dsl.processModel
import ru.krista.bpm.runtime.instance.MessageSendInstance

data class PlayerInfo(val name: String, val domain: String, val id: String)

class PlayersList: ArrayList<PlayerInfo>()

class RoundRobinPlayer : ProcessImpl<RoundRobinPlayer>(roundRobinPlayerModel) {

    var playerName: String by input(persistent = true, 
                                    defaultValue = "RoundRobinPlayer")
    var energy: Int by input(persistent = true, defaultValue = 30)
    var players: PlayersList by persistent(PlayersList())
    var nextPlayerIndex: Int by persistent(-1)
    var allPlayersOut: Boolean by persistent(false)
    var shotCounter: Int = 0

    val selfPlayer: PlayerInfo
        get() = PlayerInfo(playerName, env.eventDispatcher.domainName, id)
}

val roundRobinPlayerModel = processModel<RoundRobinPlayer>(
        name = "RoundRobinPlayer", 
        version = 1) {

    val waitNewGameSignal = signalWait<String>("NewGame")
    val waitStopGameSignal = signalWait<String>("StopGame")
    val sendPlayerJoin = signal<String>("PlayerJoin") {
        signalData = { playerName }
    }
    val sendPlayerOut = signal<String>("PlayerOut") {
        signalData = { playerName }
    }
    val waitPlayerJoin = signalWaitCustom<String>("PlayerJoin") {
        eventCondition = { signal ->
            signal.sender.processInstanceId != process.id 
                && !process.players.any { signal.sender.processInstanceId == it.id}
        }
        handler = { signal ->
            players.add(PlayerInfo(
                    signal.data!!, 
                    signal.sender.domain, 
                    signal.sender.processInstanceId))
        }
    }
    val waitPlayerOut = signalWait<String>("PlayerOut") { signal ->
        players.remove(PlayerInfo(
                signal.data!!, 
                signal.sender.domain, 
                signal.sender.processInstanceId))
        allPlayersOut = players.isEmpty()
    }
    val sendHandshake = messageSend<String>("Handshake") {
        messageData = { playerName }
        activation = {
            receiverDomain = process.players.last().domain
            receiverProcessInstanceId = process.players.last().id
        }
    }
    val receiveHandshake = messageWait<String>("Handshake") { message ->
        if (!players.any { message.sender.processInstanceId == it.id}) {
            players.add(PlayerInfo(
                    message.data!!, 
                    message.sender.domain, 
                    message.sender.processInstanceId))
        }
    }
    val throwBall = messageSend<Int>("Ball") {
        messageData = { shotCounter + 1 }
        activation = { selectNextPlayer() }
        onEntry { energy -= 1 }
    }
    val waitBall = messageWaitData<Int>("Ball") {
        shotCounter = it
    }

    startFrom(waitNewGameSignal)
            .fork("mainFork") {
                next(sendPlayerJoin)
                        .branch("mainLoop") {
                            ifTrue { energy < 5 || allPlayersOut }
                                    .next(sendPlayerOut)
                                    .next(waitBall)
                            ifElse()
                                    .next(waitBall)
                                    .next(throwBall)
                                    .loop()
                        }
                next(waitPlayerJoin).next(sendHandshake).next(waitPlayerJoin)
                next(waitPlayerOut).next(waitPlayerOut)
                next(receiveHandshake).next(receiveHandshake)
                next(waitStopGameSignal).terminate()
            }

    sendPlayerJoin.onExit { println("$playerName: I'm here!") }
    sendPlayerOut.onExit { println("$playerName: I'm out!") }
}

private fun MessageSendInstance<RoundRobinPlayer, Int>.selectNextPlayer() {
    var idx = process.nextPlayerIndex + 1
    if (idx >= process.players.size) {
        idx = 0
    }
    process.nextPlayerIndex = idx
    val player = if (process.players.isNotEmpty()) 
        process.players[idx] 
    else 
        process.selfPlayer
    receiverDomain = player.domain
    receiverProcessInstanceId = player.id
    println("Step ${process.shotCounter + 1}: " +
            "${process.playerName} >>> ${player.name}")
}

Ma ọ bụghị ya, omume onye ọkpụkpọ adịghị iche na nke gara aga, ya mere eserese ahụ adịghị agbanwe.

Ugbu a, anyị chọrọ ule iji mee ihe a niile. M ga-enye naanị koodu nke ule ahụ n'onwe ya, ka ọ ghara ịkatọ akụkọ ahụ na mmiri ọkụ (n'ezie, ejiri m ebe nyocha nke e kere na mbụ iji nwalee ntinye nke usoro azụmahịa ndị ọzọ):

egwuregwu ule()

@Test
public void testGame() throws InterruptedException {
    String pl2 = startProcess(app2, "RandomPlayer", playerParams("Player2", 20));
    String pl3 = startProcess(app2, "RandomPlayer", playerParams("Player3", 40));
    String pl4 = startProcess(app3, "RoundRobinPlayer", playerParams("Player4", 25));
    String pl5 = startProcess(app3, "RoundRobinPlayer", playerParams("Player5", 35));
    String pl1 = startProcess(app1, "InitialPlayer");
    // Теперь нужно немного подождать, пока игроки "познакомятся" друг с другом.
    // Ждать через sleep - плохое решение, зато самое простое. 
    // Не делайте так в серьезных тестах!
    Thread.sleep(1000);
    // Запускаем игру, закрывая пользовательскую активность
    assertTrue(closeTask(app1, pl1, "Start"));
    app1.getWaiting().waitProcessFinished(pl1);
    app2.getWaiting().waitProcessFinished(pl2);
    app2.getWaiting().waitProcessFinished(pl3);
    app3.getWaiting().waitProcessFinished(pl4);
    app3.getWaiting().waitProcessFinished(pl5);
}

private Map<String, Object> playerParams(String name, int energy) {
    Map<String, Object> params = new HashMap<>();
    params.put("playerName", name);
    params.put("energy", energy);
    return params;
}

Ka anyị gbaa ule wee lelee ndekọ:

mmepụta console

Взята блокировка ключа lock://app1/process/InitialPlayer
Let's play!
Снята блокировка ключа lock://app1/process/InitialPlayer
Player2: I'm here!
Player3: I'm here!
Player4: I'm here!
Player5: I'm here!
... join player Player2 ...
... join player Player4 ...
... join player Player3 ...
... join player Player5 ...
Step 1: Player1 >>> Player3
Step 2: Player3 >>> Player5
Step 3: Player5 >>> Player3
Step 4: Player3 >>> Player4
Step 5: Player4 >>> Player3
Step 6: Player3 >>> Player4
Step 7: Player4 >>> Player5
Step 8: Player5 >>> Player2
Step 9: Player2 >>> Player5
Step 10: Player5 >>> Player4
Step 11: Player4 >>> Player2
Step 12: Player2 >>> Player4
Step 13: Player4 >>> Player1
Step 14: Player1 >>> Player4
Step 15: Player4 >>> Player3
Step 16: Player3 >>> Player1
Step 17: Player1 >>> Player2
Step 18: Player2 >>> Player3
Step 19: Player3 >>> Player1
Step 20: Player1 >>> Player5
Step 21: Player5 >>> Player1
Step 22: Player1 >>> Player2
Step 23: Player2 >>> Player4
Step 24: Player4 >>> Player5
Step 25: Player5 >>> Player3
Step 26: Player3 >>> Player4
Step 27: Player4 >>> Player2
Step 28: Player2 >>> Player5
Step 29: Player5 >>> Player2
Step 30: Player2 >>> Player1
Step 31: Player1 >>> Player3
Step 32: Player3 >>> Player4
Step 33: Player4 >>> Player1
Step 34: Player1 >>> Player3
Step 35: Player3 >>> Player4
Step 36: Player4 >>> Player3
Step 37: Player3 >>> Player2
Step 38: Player2 >>> Player5
Step 39: Player5 >>> Player4
Step 40: Player4 >>> Player5
Step 41: Player5 >>> Player1
Step 42: Player1 >>> Player5
Step 43: Player5 >>> Player3
Step 44: Player3 >>> Player5
Step 45: Player5 >>> Player2
Step 46: Player2 >>> Player3
Step 47: Player3 >>> Player2
Step 48: Player2 >>> Player5
Step 49: Player5 >>> Player4
Step 50: Player4 >>> Player2
Step 51: Player2 >>> Player5
Step 52: Player5 >>> Player1
Step 53: Player1 >>> Player5
Step 54: Player5 >>> Player3
Step 55: Player3 >>> Player5
Step 56: Player5 >>> Player2
Step 57: Player2 >>> Player1
Step 58: Player1 >>> Player4
Step 59: Player4 >>> Player1
Step 60: Player1 >>> Player4
Step 61: Player4 >>> Player3
Step 62: Player3 >>> Player2
Step 63: Player2 >>> Player5
Step 64: Player5 >>> Player4
Step 65: Player4 >>> Player5
Step 66: Player5 >>> Player1
Step 67: Player1 >>> Player5
Step 68: Player5 >>> Player3
Step 69: Player3 >>> Player4
Step 70: Player4 >>> Player2
Step 71: Player2 >>> Player5
Step 72: Player5 >>> Player2
Step 73: Player2 >>> Player1
Step 74: Player1 >>> Player4
Step 75: Player4 >>> Player1
Step 76: Player1 >>> Player2
Step 77: Player2 >>> Player5
Step 78: Player5 >>> Player4
Step 79: Player4 >>> Player3
Step 80: Player3 >>> Player1
Step 81: Player1 >>> Player5
Step 82: Player5 >>> Player1
Step 83: Player1 >>> Player4
Step 84: Player4 >>> Player5
Step 85: Player5 >>> Player3
Step 86: Player3 >>> Player5
Step 87: Player5 >>> Player2
Step 88: Player2 >>> Player3
Player2: I'm out!
Step 89: Player3 >>> Player4
... player Player2 is out ...
Step 90: Player4 >>> Player1
Step 91: Player1 >>> Player3
Step 92: Player3 >>> Player1
Step 93: Player1 >>> Player4
Step 94: Player4 >>> Player3
Step 95: Player3 >>> Player5
Step 96: Player5 >>> Player1
Step 97: Player1 >>> Player5
Step 98: Player5 >>> Player3
Step 99: Player3 >>> Player5
Step 100: Player5 >>> Player4
Step 101: Player4 >>> Player5
Player4: I'm out!
... player Player4 is out ...
Step 102: Player5 >>> Player1
Step 103: Player1 >>> Player3
Step 104: Player3 >>> Player1
Step 105: Player1 >>> Player3
Step 106: Player3 >>> Player5
Step 107: Player5 >>> Player3
Step 108: Player3 >>> Player1
Step 109: Player1 >>> Player3
Step 110: Player3 >>> Player5
Step 111: Player5 >>> Player1
Step 112: Player1 >>> Player3
Step 113: Player3 >>> Player5
Step 114: Player5 >>> Player3
Step 115: Player3 >>> Player1
Step 116: Player1 >>> Player3
Step 117: Player3 >>> Player5
Step 118: Player5 >>> Player1
Step 119: Player1 >>> Player3
Step 120: Player3 >>> Player5
Step 121: Player5 >>> Player3
Player5: I'm out!
... player Player5 is out ...
Step 122: Player3 >>> Player5
Step 123: Player5 >>> Player1
Player5: I'm out!
Step 124: Player1 >>> Player3
... player Player5 is out ...
Step 125: Player3 >>> Player1
Step 126: Player1 >>> Player3
Player1: I'm out!
... player Player1 is out ...
Step 127: Player3 >>> Player3
Player3: I'm out!
Step 128: Player3 >>> Player3
... player Player3 is out ...
Player3: I'm out!
Stop!
Step 129: Player3 >>> Player3
Player3: I'm out!

Site na nke a niile anyị nwere ike nweta nkwubi okwu dị iche iche:

  • na ngwaọrụ ndị dị mkpa, ndị na-emepụta ngwa nwere ike ịmepụta mmekọrịta mmekọrịta n'etiti ngwa na-akwụsịghị echiche azụmahịa;
  • mgbagwoju anya nke ọrụ mwekota nke chọrọ ikike injinia nwere ike zoo n'ime usoro ahụ ma ọ bụrụ na nke a na-etinye na mbụ na nhazi nke usoro ahụ. A pụghị izobe ihe isi ike nke nsogbu, ya mere ngwọta maka nsogbu siri ike na koodu ga-adị ka ya;
  • Mgbe ị na-emepụta mgbagha njikọta, ọ dị mkpa iburu n'uche na nkwekọ na-emecha na enweghị akara nke mgbanwe na steeti ndị niile sonyere. Nke a na-amanye anyị ime ka echiche ahụ gbagwojuru anya iji mee ka ọ ghara inwe mmetụta n'usoro nke ihe omume mpụga na-eme. N'ihe atụ anyị, a na-amanye onye ọkpụkpọ ahụ itinye aka na egwuregwu ahụ mgbe o kwupụtachara ọpụpụ ya na egwuregwu ahụ: ndị egwuregwu ndị ọzọ ga-anọgide na-enyefe ya bọl ahụ ruo mgbe ozi gbasara ọpụpụ ya ruru na ndị niile sonyere na-ahazi ya. Echiche a anaghị agbaso site na iwu nke egwuregwu ahụ ma bụrụ ngwọta nkwekọrịta n'ime usoro nhazi nke ahọpụtara.

Ọzọ, anyị ga-ekwu maka ihe mgbagwoju anya dị iche iche nke ngwọta anyị, nkwekọrịta na isi ihe ndị ọzọ.

Ozi niile dị n'otu kwụ n'ahịrị

Ngwa niile agbakwunyere na-arụ ọrụ na otu ụgbọ ala ntinye, nke ewepụtara n'ụdị onye na-ere ahịa mpụga, otu BPMQueue maka ozi yana otu isiokwu BPMTopic maka akara (ihe omume). Itinye ozi niile n'otu kwụ n'ahịrị bụ n'onwe ya nkwekọrịta. N'ọkwa mgbagha azụmahịa, ị nwere ike iwebata ụdị ozi ọhụrụ dị ka ịchọrọ n'emeghị mgbanwe na nhazi usoro. Nke a bụ ihe dị mfe mfe, ma ọ na-ebu ụfọdụ ihe ize ndụ, nke na onodu nke anyị ahụkarị aga-eme na-eyighị ka ihe dị mkpa nye anyị.

Mgbakwunye ụdị BPM

Agbanyeghị, enwere otu aghụghọ ebe a: ngwa ọ bụla na-enyocha ozi “ya” sitere na kwụ n'ahịrị n'ọnụ ụzọ, site na aha ngalaba ya. Enwere ike ịkọwa ngalaba ahụ na mgbaama ma ọ bụrụ na ịchọrọ ịmachi “oke visibiliti” nke mgbama ahụ n'otu ngwa. Nke a kwesịrị ịbawanye ntinye ụgbọ ala, mana mgbagha azụmahịa ga-arụ ọrụ ugbu a na aha ngalaba: maka izi ozi ozi - iwu, maka akara - ihe na-achọsi ike.

Na-ahụ na ntụkwasị obi ụgbọ ala jikọtara ọnụ

Ntụkwasị obi nwere ọtụtụ isi ihe:

  • Onye na-ere ahịa ozi ahọpụtara bụ akụkụ dị oke egwu nke ihe owuwu ụlọ yana otu ebe ọdịda: ọ ga-abụrịrị na ọ ga-anabata nke ọma. Ị kwesịrị iji naanị mmejuputa a nwalere oge, na nkwado dị mma na nnukwu obodo;
  • ọ dị mkpa iji hụ na ọ dị elu nke onye na-ere ahịa ozi, nke ọ ga-abụrịrị ikewapụ ya n'ụzọ anụ ahụ site na ngwa ngwa agbakwunyere (ọnụahịa dị elu nke ngwa na-eji mgbagha azụmahịa etinyere bụ ihe siri ike ma dị oke ọnụ iji hụ);
  • onye na-ere ahịa ahụ kwesịrị ịnye nkwa nnyefe "opekata mpe otu". Nke a bụ ihe a chọrọ n'aka maka ịrụ ọrụ nke ụgbọ ala njikọta. Ọ dịghị mkpa maka "otu oge" ọkwa ọkwa: usoro azụmahịa, dị ka a na-achị, adịghị emetụ n'ahụ maka ọbịbịa nke ozi ma ọ bụ ihe omume ugboro ugboro, na ọrụ pụrụ iche ebe nke a dị mkpa, ọ dị mfe ịgbakwunye ego ego ọzọ na azụmahịa. mgbagha karịa iji oge niile nkwa “dị oke ọnụ”;
  • izipu ozi na akara ga-etinyerịrị na azụmahịa zuru oke na mgbanwe na steeti usoro azụmahịa na data ngalaba. Nhọrọ kacha mma ga-abụ iji ụkpụrụ Igbe azụmahịa, mana ọ ga-achọ tebụl ọzọ na nchekwa data na onye na-emegharị ya. Na ngwa JEE, enwere ike ime ka nke a dị mfe site na iji njikwa JTA mpaghara, mana njikọ nke onye na-ere ahịa ahọpụtara ga-enwerịrị ike ịrụ ọrụ na ya. XA;
  • ndị na-ahụ maka ozi na-abata na ihe omume ga-arụkwa ọrụ na azụmahịa nke na-agbanwe ọnọdụ nke usoro azụmahịa: ọ bụrụ na azụmahịa dị otú ahụ na-atụgharị azụ, mgbe ahụ, a ghaghị ịkagbu nnata nke ozi ahụ;
  • A ga-echekwarịrị ozi enweghị ike izipu n'ihi mperi na nchekwa dị iche D.L.Q. (Dead Letter Queue). Maka ebumnuche a, anyị mepụtara microservice dị iche iche nke na-echekwa ozi dị otú ahụ na nchekwa ya, na-edepụta ha site na njirimara (maka nchịkọta ngwa ngwa na ọchụchọ), ma kpughee API maka ikiri, na-eziga na adreesị ebe ị na-aga, na ihichapụ ozi. Ndị na-ahụ maka sistemụ nwere ike ịrụ ọrụ na ọrụ a site na ntanetị weebụ ha;
  • N'ime ntọala onye na-ere ahịa, ịkwesịrị ịhazigharị ọnụọgụ nke nnyefe na igbu oge n'etiti nnyefe iji belata ohere nke ozi ịbanye na DLQ (ọ fọrọ nke nta ka ọ bụrụ na ọ gaghị ekwe omume ịgbakọ paramita kachasị mma, mana ị nwere ike ime ihe n'ụzọ na-enweghị atụ ma dozie ha n'oge ọrụ. );
  • A ga-enyocharịrị ụlọ ahịa DLQ mgbe niile, na sistemụ nleba anya ga-amarịrị ndị na-ahụ maka sistemu ka mgbe ozi na-ebughị ụzọ mee, ha nwere ike ịzaghachi ngwa ngwa o kwere mee. Nke a ga-ebelata "mpaghara emetụtara" nke ọdịda ma ọ bụ njehie azụmahịa;
  • ụgbọ ala ntinye ga-abụ nke na-adịghị emetụ n'ahụ maka enweghị ngwa ngwa nwa oge: ndenye aha na isiokwu ga-adịgide adịgide, na ngalaba aha ngwa ahụ ga-abụ ihe pụrụ iche nke mere na mgbe ngwa ahụ adịghị, onye ọzọ agaghị anwa ịhazi ozi ya site na kwụ n'ahịrị.

Ịhụ na eri nchekwa nke azụmahịa mgbagha

Otu ihe atụ nke usoro azụmahịa nwere ike ịnweta ọtụtụ ozi na ihe omume n'otu oge, nhazi nke ga-amalite n'otu oge. N'otu oge ahụ, maka onye mmepụta ngwa, ihe niile kwesịrị ịdị mfe na eri-nchekwa.

Echiche azụmaahịa nke usoro na-ahazi ihe omume mpụga ọ bụla na-emetụta usoro azụmaahịa ahụ n'otu n'otu. Ihe omume ndị dị otú ahụ nwere ike ịbụ:

  • ịmalite usoro azụmahịa ihe atụ;
  • omume onye ọrụ metụtara ọrụ n'ime usoro azụmahịa;
  • nnata ozi ma ọ bụ mgbaama nke edebanye aha usoro azụmahịa;
  • ịkpalite ngụ oge setịpụrụ site na ihe atụ usoro azụmahịa;
  • njikwa ọrụ site na API (dịka ọmụmaatụ, nkwụsị usoro).

Ihe omume ọ bụla dị otú ahụ nwere ike ịgbanwe ọnọdụ nke usoro azụmahịa: ụfọdụ ihe omume nwere ike ịkwụsị na ndị ọzọ nwere ike ịmalite, na ụkpụrụ nke ihe onwunwe na-adịgide adịgide nwere ike ịgbanwe. Imechi ọrụ ọ bụla nwere ike bute ịgbalite otu ma ọ bụ karịa n'ime mmemme ndị a. Ndị ahụ, n'aka nke ya, nwere ike ịkwụsị ichere ihe omume ndị ọzọ ma ọ bụ, ọ bụrụ na ha achọghị data ọzọ, nwere ike mezue n'otu azụmahịa ahụ. Tupu imechi azụmahịa ahụ, a na-echekwa ọnọdụ ọhụrụ nke usoro azụmahịa na nchekwa data, ebe ọ ga-echere ihe omume mpụga ọzọ ga-eme.

Data usoro azụmahịa na-adịgide adịgide echekwara na nchekwa data mmekọrịta bụ ebe dị mma maka ịmekọrịta nhazi ma ọ bụrụ na ị na-eji HỌRỌ KA Nwelite. Ọ bụrụ na otu azụmahịa jisiri ike nweta ọnọdụ nke usoro azụmahịa site na ntọala maka ịgbanwe ya, mgbe ahụ ọ dịghị azụmahịa ọzọ dị na ya ga-enwe ike ịnweta otu steeti maka mgbanwe ọzọ, na mgbe emechara azụmahịa mbụ, nke abụọ bụ nke abụọ. ekwela nkwa ịnata steeti agbanweela.

Iji mkpọchi enweghị nchekwube n'akụkụ DBMS, anyị na-emezu ihe niile achọrọ Acid, ma na-ejigide ikike ijikọ ngwa ahụ site na mgbagha azụmahịa site n'ịbawanye ọnụ ọgụgụ ndị na-agba ọsọ.

Agbanyeghị, mkpọchi enweghị nchekwube na-eyi anyị egwu ọnwụ, nke pụtara na ahọpụtara maka mmelite ka ga-ejedebe na oge ụfọdụ ezi uche dị na ya ma ọ bụrụ na mkpọchi anwụ na-eme na ụfọdụ ikpe jọgburu onwe ya na mgbagha azụmaahịa.

Nsogbu ọzọ bụ mmekọrịta nke mmalite nke usoro azụmahịa. Ọ bụ ezie na ọ dịghị ihe atụ nke usoro azụmahịa, ọ dịghị steeti na nchekwa data, ya mere usoro a kọwara agaghị arụ ọrụ. Ọ bụrụ na ịchọrọ ịhụ na ọpụrụiche nke usoro azụmaahịa n'ụdị a kapịrị ọnụ, mgbe ahụ ị ga-achọ ụdị ihe mmekọrịta jikọtara ya na klaasị usoro yana oke kwekọrọ. Iji dozie nsogbu a, anyị na-eji usoro mkpọchi dị iche nke na-enye anyị ohere iwere mkpọchi na akụrụngwa aka ike akọwapụtara site na igodo dị na usoro URI site na ọrụ mpụga.

N'ihe atụ anyị, usoro azụmaahịa nke InitialPlayer nwere nkwupụta

uniqueConstraint = UniqueConstraints.singleton

Ya mere, ndekọ ahụ nwere ozi gbasara iwere na ịtọhapụ mkpọchi igodo kwekọrọ. Enweghị ozi dị otú ahụ maka usoro azụmahịa ndị ọzọ: edobeghị ihe mgbochi pụrụ iche.

Nsogbu nke usoro azụmahịa na steeti na-adịgide adịgide

Mgbe ụfọdụ inwe ọnọdụ na-adịgide adịgide ọ bụghị naanị na-enyere aka, kamakwa n'ezie na-egbochi mmepe.
Nsogbu na-amalite mgbe ọ dị mkpa ka eme mgbanwe na mgbagha azụmahịa na/ma ọ bụ usoro azụmahịa. Ọ bụghị mgbanwe ọ bụla dị otú ahụ kwekọrọ na ọnọdụ ochie nke usoro azụmahịa. Ọ bụrụ na enwere ọtụtụ ihe dị ndụ na nchekwa data, mgbe ahụ ime mgbanwe ndị na-ekwekọghị ekwekọ nwere ike ịkpata ọtụtụ nsogbu, nke anyị na-ezutekarị mgbe anyị na-eji jBPM.

Dabere na omimi mgbanwe, ị nwere ike ime n'ụzọ abụọ:

  1. mepụta ụdị usoro azụmahịa ọhụrụ ka ị ghara ime mgbanwe na-ekwekọghị na nke ochie, ma jiri ya kama nke ochie mgbe ị na-ebupụta ihe ọhụrụ. Ụdị ochie ga-anọgide na-arụ ọrụ "dị ka ọ dị na mbụ";
  2. ịkwaga ọnọdụ na-adịgide adịgide nke usoro azụmahịa mgbe ị na-emelite mgbagha azụmahịa.

Ụzọ nke mbụ dị mfe, ma nwere njedebe na adịghị ike ya, dịka ọmụmaatụ:

  • mbiputegharị nke mgbagha azụmahịa n'ọtụtụ ụdị usoro azụmahịa, na-abawanye olu nke mgbagha azụmahịa;
  • Ọtụtụ mgbe, a na-achọ mgbanwe ozugbo na mgbagha azụmahịa ọhụrụ (n'ihe gbasara ọrụ ntinye - ọ fọrọ nke nta ka ọ bụrụ mgbe niile);
  • onye nrụpụta ahụ amaghị ebe enwere ike ihichapụ ụdị ochie ochie.

Na omume anyị na-eji ụzọ abụọ a, mana anyị emeela ọtụtụ mkpebi iji mee ka ndụ anyị dịkwuo mfe:

  • Na nchekwa data, a na-echekwa ọnọdụ na-adịgide adịgide nke usoro azụmahịa n'ụdị a na-agụ ngwa ngwa na nke dị mfe: na eriri usoro JSON. Nke a na-enye ohere ka eme njem n'ime ngwa ma na mpụga. Dị ka ihe ikpeazụ, ị nwere ike iji aka dozie ya (karịsịa bara uru na mmepe n'oge nbipu);
  • mgbagha azụmahịa nke njikọta anaghị eji aha nke usoro azụmahịa, nke mere na n'oge ọ bụla ọ ga-ekwe omume iji dochie mmejuputa nke otu n'ime usoro ntinye aka na nke ọhụrụ nwere aha ọhụrụ (dịka ọmụmaatụ, "InitialPlayerV2"). Njikọ ahụ na-apụta site na ozi na aha akara;
  • usoro usoro nwere nọmba mbipute, nke anyị na-abawanye ma ọ bụrụ na anyị na-eme mgbanwe na-ekwekọghị na ihe nlereanya a, a na-echekwa nọmba a yana ọnọdụ nke usoro ihe atụ;
  • A na-agụ ọnọdụ na-adịgide adịgide nke usoro ahụ site na nchekwa data mbụ n'ime ihe nlereanya ihe dị mma, nke usoro njem ahụ nwere ike ịrụ ọrụ ma ọ bụrụ na nọmba ụdị ụdị agbanweela;
  • A na-etinye usoro mbugharị n'akụkụ mgbagha azụmahịa ma kpọọ ya "ume-ngwu" maka ihe atụ ọ bụla nke usoro azụmahịa n'oge mweghachi ya na nchekwa data;
  • Ọ bụrụ na ịchọrọ ịkwaga ọnọdụ usoro usoro niile ngwa ngwa na n'otu oge, a na-eji ngwọta mbugharị nchekwa data kpochapụwo karịa, mana ị ga-arụ ọrụ na JSON.

Ị chọrọ usoro ọzọ maka usoro azụmahịa?

Ngwọta ndị a kọwara n'isiokwu ahụ nyere anyị ohere ime ka ndụ anyị dị mfe nke ukwuu, gbasaa ọtụtụ nsogbu edoziri na ọkwa mmepe ngwa, ma mee ka echiche nke ikewapụta echiche azụmaahịa n'ime microservices mara mma. Iji mezuo nke a, a rụrụ ọtụtụ ọrụ, a na-emepụta usoro "dị arọ" nke ukwuu maka usoro azụmahịa, yana akụkụ ọrụ iji dozie nsogbu ndị a chọpụtara na nsogbu dị iche iche nke ngwa ngwa. Anyị nwere ọchịchọ ịkesa nsonaazụ ndị a ma mee ka mmepe nke ihe ndị a na-ahụkarị na-emeghe ohere n'okpuru ikikere efu. Nke a ga-achọ mgbalị na oge ụfọdụ. Ịghọta ihe achọrọ maka ngwọta ndị dị otú ahụ nwere ike ịbụrụ anyị ihe mkpali ọzọ. N'isiokwu a na-atụ aro, a na-akwụ ụgwọ obere nlebara anya na ikike nke usoro ahụ n'onwe ya, ma ụfọdụ n'ime ha na-ahụ anya site na ihe atụ ndị a gosipụtara. Ọ bụrụ na anyị ebipụta usoro anyị, a ga-etinye akụkọ dị iche na ya. Ka ọ dị ugbu a, anyị ga-enwe ekele ma ọ bụrụ na ị hapụ ntakịrị nzaghachi site na ịza ajụjụ a:

Naanị ndị ọrụ edebanyere aha nwere ike isonye na nyocha a. banye, Biko.

Ị chọrọ usoro ọzọ maka usoro azụmahịa?

  • 18,8%Ee, m na-achọ ihe dị ka nke a ogologo oge

  • 12,5%Enwere m mmasị ịmụtakwu gbasara mmejuputa gị, ọ nwere ike ịba uru2

  • 6,2%Anyị na-eji otu n'ime usoro dị adị, mana anyị na-eche maka dochie1

  • 18,8%Anyị na-eji otu n'ime usoro ndị dị ugbu a, ihe niile dị mma3

  • 18,8%anyị jikwaa enweghị framework3

  • 25,0%dee nke gi4

Ndị ọrụ 16 tụrụ vootu. Ndị ọrụ 7 anabataghị.

isi: www.habr.com

Tinye a comment