BPM ara Integration

BPM ara Integration

Kaabo, Habr!

Ile-iṣẹ wa ṣe amọja ni idagbasoke awọn solusan sọfitiwia kilasi ERP, ipin kiniun ti eyiti o wa nipasẹ awọn ọna ṣiṣe iṣowo pẹlu iye nla ti oye iṣowo ati ṣiṣan iwe a la EDMS. Awọn ẹya lọwọlọwọ ti awọn ọja wa da lori awọn imọ-ẹrọ JavaEE, ṣugbọn a tun n ṣe idanwo pẹlu awọn iṣẹ microservices. Ọkan ninu awọn agbegbe iṣoro julọ ti iru awọn solusan ni isọpọ ti awọn oriṣiriṣi awọn ọna ṣiṣe ti o jẹ ti awọn agbegbe ti o wa nitosi. Awọn iṣoro iṣọpọ nigbagbogbo ti fun wa ni orififo nla kan, laibikita awọn aṣa ayaworan, awọn akopọ imọ-ẹrọ ati awọn ilana ti a lo, ṣugbọn laipẹ ilọsiwaju ti wa ni didaju iru awọn iṣoro bẹ.

Ninu nkan ti Mo mu wa si akiyesi rẹ, Emi yoo sọrọ nipa iriri ati iwadii ayaworan ti NPO Krista ni agbegbe ti a yan. A yoo tun wo apẹẹrẹ ti ojutu ti o rọrun si iṣoro iṣọpọ kan lati oju wiwo ti olupilẹṣẹ ohun elo kan ati rii ohun ti o farapamọ lẹhin ayedero yii.

AlAIgBA

Awọn ojutu ayaworan ati imọ-ẹrọ ti a ṣalaye ninu nkan naa ni a dabaa nipasẹ mi ti o da lori iriri ti ara ẹni ni agbegbe ti awọn iṣẹ ṣiṣe kan pato. Awọn ojutu wọnyi ko beere pe o jẹ gbogbo agbaye ati pe o le ma dara julọ labẹ awọn ipo lilo miiran.

Kini BPM ni lati ṣe pẹlu rẹ?

Lati dahun ibeere yii, a nilo lati jinlẹ diẹ si awọn pato ti awọn iṣoro ti a lo ti awọn ojutu wa. Apa akọkọ ti imọ-ọrọ iṣowo ni eto iṣowo iṣowo aṣoju wa ni titẹ data sinu aaye data nipasẹ awọn atọkun olumulo, afọwọṣe ati ijẹrisi adaṣe ti data yii, ṣiṣe nipasẹ diẹ ninu ṣiṣan iṣẹ, titẹjade si eto miiran / data itupalẹ / ile-ipamọ, ati awọn ijabọ ti ipilẹṣẹ. . Nitorinaa, iṣẹ bọtini ti eto fun awọn alabara jẹ adaṣe ti awọn ilana iṣowo inu wọn.

Fun irọrun, a lo ọrọ naa “iwe-iwe” ni ibaraẹnisọrọ bi diẹ ninu awọn abstraction ti ṣeto data kan ti a ṣọkan nipasẹ bọtini ti o wọpọ si eyiti iṣan-iṣẹ kan le jẹ “isopọmọ”.
Ṣugbọn kini nipa ọgbọn iṣọpọ? Lẹhin gbogbo ẹ, iṣẹ iṣọpọ jẹ ipilẹṣẹ nipasẹ faaji ti eto, eyiti o “ge” si awọn apakan KO ni ibeere ti alabara, ṣugbọn labẹ ipa ti awọn ifosiwewe ti o yatọ patapata:

  • koko ọrọ si Conway ká ofin;
  • bi abajade ti ilotunlo awọn ọna ṣiṣe ti o ti dagbasoke tẹlẹ fun awọn ọja miiran;
  • ni lakaye ayaworan, da lori ti kii-ti iṣẹ-ṣiṣe awọn ibeere.

Idanwo nla kan wa lati yapa kannaa isọpọ lati inu imọ-ọrọ iṣowo ti iṣan-iṣẹ akọkọ, nitorinaa ki o má ba ṣe aimọye ọgbọn iṣowo pẹlu awọn ohun-ọṣọ isọpọ ati yọkuro olupilẹṣẹ ohun elo lati iwulo lati ṣawari sinu awọn pato ti ala-ilẹ ayaworan ti eto naa. Ọna yii ni awọn anfani pupọ, ṣugbọn adaṣe ṣe afihan ailagbara rẹ:

  • lohun awọn iṣoro iṣọpọ nigbagbogbo ṣubu pada si awọn aṣayan ti o rọrun julọ ni irisi awọn ipe amuṣiṣẹpọ nitori awọn aaye ifaagun to lopin ni imuse ti iṣan-iṣẹ akọkọ (awọn aila-nfani ti isọpọ amuṣiṣẹpọ ni a sọrọ ni isalẹ);
  • Integration artifacts si tun penetrate mojuto owo kannaa nigba ti esi lati miiran subsystem wa ni ti beere;
  • Olùgbéejáde ìṣàfilọ́lẹ̀ kọ ìṣọ̀kan náà sí àti pé ó lè fọ́ ọ lọ́rùn nípa yíyí ìṣàtúnṣe iṣẹ́ padà;
  • Eto naa dawọ lati jẹ odidi kan lati oju wiwo olumulo, “awọn okun” laarin awọn eto-ipin di akiyesi, ati pe awọn iṣẹ olumulo laiṣe han, bẹrẹ gbigbe data lati inu eto-ipin kan si ekeji.

Ọna miiran ni lati gbero awọn ibaraenisepo isọpọ gẹgẹbi apakan pataki ti iṣaro iṣowo akọkọ ati ṣiṣan iṣẹ. Lati ṣe idiwọ awọn afijẹẹri olupilẹṣẹ ohun elo lati ọrun, ṣiṣẹda awọn ibaraenisepo isọpọ tuntun yẹ ki o rọrun ati ailagbara, pẹlu aye to kere julọ lati yan ojutu kan. Eyi lera lati ṣe ju bi o ti dabi: ohun elo naa gbọdọ jẹ alagbara to lati pese olumulo pẹlu awọn aṣayan oriṣiriṣi ti a beere fun lilo rẹ, laisi gbigba u laaye lati “tu ararẹ si ẹsẹ.” Awọn ibeere pupọ lo wa ti ẹlẹrọ gbọdọ dahun ni aaye ti awọn iṣẹ iṣọpọ, ṣugbọn eyiti olupilẹṣẹ ohun elo ko yẹ ki o ronu nipa iṣẹ ojoojumọ rẹ: awọn aala idunadura, aitasera, atomity, aabo, iwọn, fifuye ati pinpin awọn orisun, ipa-ọna, marshaling, pinpin ati awọn ipo iyipada, bbl O jẹ dandan lati fun awọn olupilẹṣẹ ohun elo awọn awoṣe ojutu ti o rọrun ni deede ninu eyiti awọn idahun si gbogbo iru awọn ibeere ti wa ni ipamọ tẹlẹ. Awọn awoṣe wọnyi gbọdọ jẹ ailewu pupọ: awọn iyipada iṣaro iṣowo nigbagbogbo, eyiti o mu eewu ti iṣafihan awọn aṣiṣe pọ si, idiyele awọn aṣiṣe gbọdọ wa ni ipele kekere ti iṣẹtọ.

Ṣugbọn kini BPM ni lati ṣe pẹlu rẹ? Awọn aṣayan pupọ wa fun imuse ṣiṣiṣẹsiṣẹ...
Lootọ, imuse miiran ti awọn ilana iṣowo jẹ olokiki pupọ ninu awọn solusan wa - nipasẹ asọye asọye ti aworan iyipada ipinlẹ kan ati asopọ ti awọn olutọju pẹlu ọgbọn iṣowo fun awọn iyipada. Ni idi eyi, ipinle ti o ṣe ipinnu ipo ti o wa lọwọlọwọ ti "iwe" ni ilana iṣowo jẹ ẹya ti "iwe" funrararẹ.

BPM ara Integration
Eyi jẹ ohun ti ilana naa dabi ni ibẹrẹ iṣẹ akanṣe kan

Gbajumo ti imuse yii jẹ nitori ayedero ibatan ati iyara ti ṣiṣẹda awọn ilana iṣowo laini. Bibẹẹkọ, bi awọn eto sọfitiwia ṣe n di idiju diẹ sii, apakan adaṣe ti ilana iṣowo n dagba ati di eka sii. iwulo wa fun jijẹ, ilotunlo ti awọn apakan ti awọn ilana, ati awọn ilana ti ẹka ki ẹka kọọkan ṣiṣẹ ni afiwe. Labẹ iru awọn ipo bẹẹ, ọpa naa di aibalẹ, ati aworan iyipada ti ipinlẹ npadanu akoonu alaye rẹ (awọn ibaraenisepo isọpọ ko ṣe afihan ninu aworan atọka rara).

BPM ara Integration
Eyi ni ohun ti ilana naa dabi lẹhin ọpọlọpọ awọn iterations ti alaye awọn ibeere.

Awọn ọna jade ti ipo yìí wà ni Integration ti awọn engine jBPM sinu diẹ ninu awọn ọja pẹlu awọn ilana iṣowo eka julọ. Ni igba diẹ, ojutu yii ni diẹ ninu aṣeyọri: o ṣee ṣe lati ṣe awọn ilana iṣowo ti o nipọn lakoko ti o ṣetọju alaye ti o tọ ati aworan ti o yẹ ninu ami akiyesi naa. BPMN2.

BPM ara Integration
Apa kekere ti ilana iṣowo eka kan

Ni igba pipẹ, ojutu naa ko gbe ni ibamu si awọn ireti: iṣẹ ṣiṣe giga ti ṣiṣẹda awọn ilana iṣowo nipasẹ awọn irinṣẹ wiwo ko gba laaye iyọrisi awọn afihan iṣelọpọ itẹwọgba, ati pe ọpa funrararẹ di ọkan ninu awọn ti ko nifẹ julọ laarin awọn idagbasoke. Awọn ẹdun ọkan tun wa nipa eto inu ti ẹrọ naa, eyiti o yori si ifarahan ti ọpọlọpọ awọn “awọn abulẹ” ati “awọn crutches”.

Abala rere akọkọ ti lilo jBPM ni imọ ti awọn anfani ati awọn ipalara ti nini apẹẹrẹ ilana iṣowo ni ipo itẹramọṣẹ tirẹ. A tun rii iṣeeṣe ti lilo ọna ilana lati ṣe awọn ilana isọpọ eka laarin awọn ohun elo oriṣiriṣi nipa lilo awọn ibaraenisepo asynchronous nipasẹ awọn ifihan agbara ati awọn ifiranṣẹ. Iwaju ipo itẹramọṣẹ ṣe ipa pataki ninu eyi.

Da lori awọn loke, a le pari: Ọna ilana ni ara BPM ngbanilaaye lati yanju ọpọlọpọ awọn iṣẹ ṣiṣe lati ṣe adaṣe awọn ilana iṣowo ti o ni idiju, ni ibamu ni ibamu awọn iṣẹ iṣọpọ sinu awọn ilana wọnyi ati ṣetọju agbara lati ṣe afihan ilana imuse ni wiwo ti o yẹ.

Awọn aila-nfani ti awọn ipe amuṣiṣẹpọ bi apẹẹrẹ isọpọ

Isopọpọ amuṣiṣẹpọ tọka si ipe dina ti o rọrun julọ. Eto abẹlẹ kan n ṣiṣẹ bi ẹgbẹ olupin ati ṣiṣafihan API pẹlu ọna ti o nilo. Eto ihalẹ miiran n ṣiṣẹ bi ẹgbẹ alabara ati ni akoko to pe o pe ati duro de abajade. Ti o da lori faaji eto, alabara ati awọn ẹgbẹ olupin le wa boya ni ohun elo kanna ati ilana, tabi ni awọn oriṣiriṣi. Ni ọran keji, o nilo lati lo diẹ ninu imuse RPC ki o pese idawọle ti awọn paramita ati abajade ipe naa.

BPM ara Integration

Apẹrẹ iṣọpọ yii ni eto awọn aila-nfani ti o tobi pupọ, ṣugbọn o jẹ lilo pupọ ni iṣe nitori irọrun rẹ. Iyara imuse ṣe iyanilẹnu ati fi agbara mu ọ lati lo lẹẹkansi ati lẹẹkansi ni oju awọn akoko ipari titẹ, gbigbasilẹ ojutu bi gbese imọ-ẹrọ. Ṣugbọn o tun ṣẹlẹ pe awọn olupilẹṣẹ ti ko ni iriri lo o ni aimọkan, lai ṣe akiyesi awọn abajade odi.

Ni afikun si awọn julọ kedere ilosoke ninu subsystem Asopọmọra, nibẹ ni o wa tun kere kedere awọn iṣoro pẹlu "dagba" ati "na" lẹkọ. Nitootọ, ti iṣaro iṣowo ba ṣe diẹ ninu awọn iyipada, lẹhinna awọn iṣowo ko le yee, ati awọn iṣowo, ni ọna, dènà awọn ohun elo elo kan ti o ni ipa nipasẹ awọn iyipada wọnyi. Iyẹn ni, titi ti eto-ipin kan yoo duro fun esi lati ọdọ ekeji, kii yoo ni anfani lati pari idunadura naa ati yọ awọn titiipa kuro. Eyi ṣe pataki pupọ si eewu ti ọpọlọpọ awọn ipa:

  • Idahun ti eto naa ti sọnu, awọn olumulo duro de igba pipẹ fun awọn idahun si awọn ibeere;
  • olupin naa ni gbogbogbo da duro lati dahun si awọn ibeere olumulo nitori adagun okun okun ti o kunju: pupọ julọ awọn okun ti wa ni titiipa lori orisun ti o tẹdo nipasẹ idunadura kan;
  • Deadlocks bẹrẹ lati han: o ṣeeṣe ti iṣẹlẹ wọn dale lori iye akoko awọn iṣowo, iye oye iṣowo ati awọn titiipa ti o wa ninu idunadura naa;
  • Awọn aṣiṣe akoko akoko idunadura han;
  • olupin naa "kuna" pẹlu OutOfMemory ti iṣẹ-ṣiṣe ba nilo sisẹ ati iyipada awọn data ti o pọju, ati wiwa awọn iṣọpọ amuṣiṣẹpọ jẹ ki o ṣoro pupọ lati pin sisẹ si awọn iṣowo "fẹẹrẹfẹ".

Lati oju iwoye ayaworan, lilo awọn ipe dina lakoko isọpọ yori si isonu ti iṣakoso lori didara ti awọn ọna ṣiṣe ti ara ẹni kọọkan: ko ṣee ṣe lati rii daju pe awọn afihan didara ibi-afẹde ti eto-ipilẹ kan ni ipinya lati awọn itọkasi didara ti eto-iṣẹ miiran. Ti o ba ti ni idagbasoke subsystems nipa orisirisi awọn egbe, yi ni ńlá kan isoro.

Awọn nkan paapaa ni iyanilenu diẹ sii ti awọn ọna ṣiṣe ti a ṣepọ pọ ba wa ni awọn ohun elo oriṣiriṣi ati pe o nilo lati ṣe awọn ayipada amuṣiṣẹpọ ni ẹgbẹ mejeeji. Bawo ni lati rii daju awọn idunadura ti awọn wọnyi ayipada?

Ti awọn ayipada ba ṣe ni awọn iṣowo lọtọ, lẹhinna iwọ yoo nilo lati pese mimu iyasọtọ ti o gbẹkẹle ati isanpada, ati pe eyi yọkuro anfani akọkọ ti awọn iṣọpọ amuṣiṣẹpọ - ayedero.

Awọn iṣowo pinpin tun wa si ọkan, ṣugbọn a ko lo wọn ninu awọn solusan wa: o nira lati rii daju igbẹkẹle.

"Saga" bi ojutu si iṣoro idunadura naa

Pẹlu awọn dagba gbale ti microservices, awọn eletan fun Àpẹẹrẹ Saga.

Apẹẹrẹ yii ni pipe yanju awọn iṣoro ti a mẹnuba loke ti awọn iṣowo gigun, ati tun faagun awọn agbara ti iṣakoso ipo ti eto naa lati ẹgbẹ ti oye iṣowo: isanpada lẹhin idunadura ti o kuna le ma yi eto pada si ipo atilẹba rẹ, ṣugbọn pese yiyan data processing ipa-. Eyi tun gba ọ laaye lati yago fun atunwi ni aṣeyọri awọn igbesẹ ṣiṣe data ti pari ni aṣeyọri nigbati o n gbiyanju lati mu ilana naa wá si ipari “dara”.

O yanilenu, ninu awọn ọna ṣiṣe monolithic apẹẹrẹ yii tun jẹ pataki nigbati o ba de si isọpọ ti awọn ọna ṣiṣe isọpọ alaifọwọyi ati awọn ipa odi ti o fa nipasẹ awọn iṣowo ṣiṣe gigun ati awọn titiipa awọn orisun ti o baamu ni a ṣe akiyesi.

Ni ibatan si awọn ilana iṣowo wa ni aṣa BPM, o wa ni irọrun pupọ lati ṣe “Sagas”: awọn igbesẹ kọọkan ti “Saga” le ṣe pàtó bi awọn iṣẹ ṣiṣe laarin ilana iṣowo, ati ipo itẹramọṣẹ ti ilana iṣowo naa tun ipinnu awọn ti abẹnu ipinle ti awọn "Saga". Iyẹn ni, a ko nilo eyikeyi ẹrọ isọdọkan eyikeyi. Gbogbo ohun ti o nilo ni alagbata ifiranṣẹ ti o ṣe atilẹyin “o kere ju ẹẹkan” awọn iṣeduro bi gbigbe.

Ṣugbọn ojutu yii tun ni “owo” tirẹ:

  • iṣaro iṣowo di eka sii: isanpada nilo lati ṣiṣẹ jade;
  • yoo jẹ dandan lati kọ aitasera ni kikun silẹ, eyiti o le jẹ pataki ni pataki fun awọn eto monolithic;
  • Awọn faaji di kekere kan diẹ idiju, ati awọn ẹya afikun nilo fun a ifiranṣẹ alagbata han;
  • afikun ibojuwo ati awọn irinṣẹ iṣakoso yoo nilo (botilẹjẹpe ni gbogbogbo eyi dara: didara iṣẹ eto yoo pọ si).

Fun awọn ọna ṣiṣe monolithic, idalare fun lilo “Sag” ko han gbangba. Fun awọn iṣẹ microservices ati SOA miiran, nibiti o ṣeese pe alagbata ti wa tẹlẹ, ati pe a ti rubọ aitasera ni kikun ni ibẹrẹ ti iṣẹ akanṣe, awọn anfani ti lilo ilana yii le ṣe pataki ju awọn aila-nfani lọ, paapaa ti API irọrun ba wa ni ọgbọn iṣowo. ipele.

Encapsulating owo kannaa ni microservices

Nigba ti a bẹrẹ idanwo pẹlu awọn microservices, ibeere ti o ni oye kan dide: nibo ni lati gbe ọgbọn iṣowo agbegbe ni ibatan si iṣẹ ti o ṣe idaniloju itẹramọṣẹ data agbegbe?

Nigbati o ba n wo faaji ti awọn oriṣiriṣi BPMS, o le dabi ohun ti o bọgbọnwa lati ya ọgbọn iṣowo kuro lati itẹramọṣẹ: ṣẹda Layer ti Syeed ati awọn iṣẹ microservices ominira-ašẹ ti o ṣe agbekalẹ agbegbe kan ati eiyan fun ṣiṣe iṣedede iṣowo agbegbe, ati ṣe apẹrẹ itẹramọṣẹ data agbegbe bi a lọtọ Layer ti irorun ati ki o lightweight microservices. Awọn ilana iṣowo ninu ọran yii ṣe orchestration ti awọn iṣẹ ti Layer itẹramọṣẹ.

BPM ara Integration

Ọna yii ni anfani nla pupọ: o le mu iṣẹ ṣiṣe ti pẹpẹ pọ si bi o ṣe fẹ, ati pe ipele ti o baamu nikan ti awọn iṣẹ microservices Syeed yoo di “ọra” lati eyi. Awọn ilana iṣowo lati eyikeyi agbegbe ni anfani lẹsẹkẹsẹ lati lo iṣẹ ṣiṣe tuntun ti pẹpẹ ni kete ti o ti ni imudojuiwọn.

Iwadi alaye diẹ sii ṣafihan awọn aila-nfani pataki ti ọna yii:

  • iṣẹ Syeed ti o ṣe ilana iṣowo ti ọpọlọpọ awọn ibugbe ni ẹẹkan gbe awọn eewu nla bi aaye kan ti ikuna. Awọn iyipada loorekoore si iṣaro iṣowo pọ si ewu awọn aṣiṣe ti o yori si awọn ikuna jakejado eto;
  • Awọn ọran iṣẹ: ọgbọn iṣowo n ṣiṣẹ pẹlu data rẹ nipasẹ wiwo dín ati o lọra:
    • awọn data yoo lekan si ti wa ni marshalled ati ki o fa soke nipasẹ awọn nẹtiwọki akopọ;
    • iṣẹ ìkápá kan yoo nigbagbogbo pese data diẹ sii ju ti o nilo fun ọgbọn iṣowo lati ṣe ilana nitori awọn agbara ti ko to fun awọn ibeere parameterizing ni ipele ti API ita ti iṣẹ naa;
    • ọpọlọpọ awọn ege ominira ti oye iṣowo le tun beere data kanna leralera fun sisẹ (iṣoro yii le dinku nipasẹ fifi awọn paati igba kun ti data kaṣe, ṣugbọn eyi tun ṣe idiju faaji ati ṣẹda awọn iṣoro ti ibaramu data ati invalidation kaṣe);
  • awọn iṣoro iṣowo:
    • awọn ilana iṣowo pẹlu ipo itẹramọṣẹ, eyiti o ti fipamọ nipasẹ iṣẹ pẹpẹ, ko ni ibamu pẹlu data agbegbe, ati pe ko si awọn ọna ti o rọrun lati yanju iṣoro yii;
    • gbigbe data agbegbe didi ni ita idunadura naa: ti oye iṣowo agbegbe nilo lati ṣe awọn ayipada lẹhin iṣayẹwo akọkọ ti data lọwọlọwọ, o jẹ dandan lati yọkuro iṣeeṣe ti iyipada ifigagbaga ninu data ti a ṣe ilana. Dinamọ data ita le ṣe iranlọwọ lati yanju iṣoro naa, ṣugbọn iru ojutu kan ni awọn eewu afikun ati dinku igbẹkẹle gbogbogbo ti eto naa;
  • awọn iṣoro afikun nigba mimudojuiwọn: ni awọn igba miiran, iṣẹ itẹramọṣẹ ati ọgbọn iṣowo nilo lati ni imudojuiwọn ni iṣiṣẹpọ tabi ni ọna ti o muna.

Nikẹhin, a ni lati pada si awọn ipilẹ: ṣafikun data agbegbe ati ọgbọn iṣowo agbegbe sinu microservice kan. Ọna yii jẹ ki oye ti microservice jẹ ki o rọrun bi ẹya ara ẹrọ ti eto ati pe ko fun awọn iṣoro ti o wa loke. Eyi tun ko fun ni ọfẹ:

  • Aṣewọn API ni a nilo fun ibaraenisepo pẹlu iṣaro iṣowo (ni pataki, lati pese awọn iṣẹ olumulo gẹgẹbi apakan ti awọn ilana iṣowo) ati awọn iṣẹ pẹpẹ API; nilo ifarabalẹ ṣọra diẹ sii si awọn iyipada API, ibaramu siwaju ati sẹhin;
  • o jẹ dandan lati ṣafikun awọn ile-ikawe akoko asiko afikun lati rii daju iṣẹ ṣiṣe ti oye iṣowo gẹgẹ bi apakan ti iru microservice kọọkan, ati pe eyi yoo fun awọn ibeere tuntun fun iru awọn ile-ikawe bẹ: ina ati o kere ju awọn igbẹkẹle irekọja;
  • Awọn olupilẹṣẹ oye oye iṣowo nilo lati ṣe atẹle awọn ẹya ile-ikawe: ti microservice ko ba ti pari fun igba pipẹ, lẹhinna o ṣee ṣe pupọ julọ ni ẹya ti igba atijọ ti awọn ile-ikawe. Eyi le jẹ idiwọ airotẹlẹ si fifi ẹya tuntun kun ati pe o le nilo ṣiṣawakiri ọgbọn iṣowo atijọ ti iru iṣẹ kan si awọn ẹya tuntun ti awọn ile ikawe ti awọn iyipada ibaramu ba wa laarin awọn ẹya.

BPM ara Integration

Layer ti awọn iṣẹ Syeed tun wa ni iru faaji, ṣugbọn Layer yii ko tun ṣe eiyan kan fun ṣiṣe adaṣe iṣowo iṣowo agbegbe, ṣugbọn agbegbe rẹ nikan, pese awọn iṣẹ “Syeed” iranlọwọ. Iru Layer yii ni a nilo kii ṣe lati ṣetọju iseda iwuwo fẹẹrẹ ti awọn iṣẹ microservices agbegbe, ṣugbọn tun lati ṣe iṣakoso aarin.

Fun apẹẹrẹ, awọn iṣẹ olumulo ni awọn ilana iṣowo ṣe awọn iṣẹ ṣiṣe. Bibẹẹkọ, nigbati o ba n ṣiṣẹ pẹlu awọn iṣẹ-ṣiṣe, olumulo gbọdọ rii awọn iṣẹ-ṣiṣe lati gbogbo awọn ibugbe ni atokọ gbogbogbo, eyiti o tumọ si pe o gbọdọ jẹ iṣẹ iforukọsilẹ iṣẹ-ṣiṣe iru ẹrọ ti o baamu, ti sọ di mimọ ti oye iṣowo agbegbe. Mimu imudani ti oye iṣowo ni iru ipo kan jẹ iṣoro pupọ, ati pe eyi jẹ adehun miiran ti faaji yii.

Ijọpọ awọn ilana iṣowo nipasẹ awọn oju ti olupilẹṣẹ ohun elo

Gẹgẹbi a ti sọ loke, olupilẹṣẹ ohun elo gbọdọ jẹ abstraction lati imọ-ẹrọ ati awọn ẹya ẹrọ ti imuse ibaraenisepo ti awọn ohun elo pupọ ki eniyan le gbẹkẹle iṣelọpọ idagbasoke to dara.

Jẹ ki a gbiyanju lati yanju iṣoro iṣọpọ ti o nira pupọ, ti a ṣe ni pataki fun nkan naa. Eyi yoo jẹ iṣẹ-ṣiṣe “ere” kan ti o kan awọn ohun elo mẹta, nibiti ọkọọkan wọn ṣe asọye orukọ ìkápá kan: “app1”, “app2”, “app3”.

Ninu ohun elo kọọkan, awọn ilana iṣowo ti ṣe ifilọlẹ ti o bẹrẹ lati “mu bọọlu” nipasẹ ọkọ akero iṣọpọ. Awọn ifiranṣẹ pẹlu orukọ "Ball" yoo ṣiṣẹ bi bọọlu kan.

Гравила игры:

  • akọkọ player ni initiator. O pe awọn oṣere miiran si ere, bẹrẹ ere ati pe o le pari rẹ nigbakugba;
  • miiran awọn ẹrọ orin sọ wọn ikopa ninu awọn ere, "gba lati mọ" kọọkan miiran ati awọn akọkọ player;
  • lẹhin gbigba bọọlu, ẹrọ orin yan ẹrọ orin miiran ti o kopa ati fi bọọlu fun u. Nọmba apapọ ti awọn gbigbe ni a ka;
  • Ẹrọ orin kọọkan ni "agbara" ti o dinku pẹlu igbasilẹ kọọkan ti rogodo nipasẹ ẹrọ orin naa. Nigbati agbara ba jade, ẹrọ orin naa lọ kuro ni ere, n kede ifisilẹ rẹ;
  • ti ẹrọ orin ba fi silẹ nikan, o kede ilọkuro rẹ lẹsẹkẹsẹ;
  • Nigbati gbogbo awọn ẹrọ orin ba ti yọkuro, ẹrọ orin akọkọ sọ ere naa ti pari. Ti o ba lọ kuro ni ere ni kutukutu, o wa lati tẹle ere lati pari.

Lati yanju iṣoro yii, Emi yoo lo DSL wa fun awọn ilana iṣowo, eyiti o fun wa laaye lati ṣe apejuwe ọgbọn ni Kotlin ni iwapọ, pẹlu o kere ju ti igbomikana.

Ilana iṣowo ti oṣere akọkọ (aka olupilẹṣẹ ere) yoo ṣiṣẹ ninu ohun elo app1:

kilasi 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}")
}

Ni afikun si ṣiṣe iṣedede iṣowo, koodu ti o wa loke le ṣe agbejade awoṣe ohun kan ti ilana iṣowo kan, eyiti o le ṣe akiyesi ni irisi aworan atọka kan. A ko ti ṣe imuse wiwo naa sibẹsibẹ, nitorinaa a ni lati lo akoko diẹ yiya (nibi Mo jẹ ki akiyesi BPMN jẹ irọrun diẹ nipa lilo awọn ẹnu-ọna lati mu imudara ti aworan naa pọ si pẹlu koodu ti o wa ni isalẹ):

BPM ara Integration

app2 yoo pẹlu ilana iṣowo ẹrọ orin miiran:

kilasi 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}")
}

Aworan:

BPM ara Integration

Ninu ohun elo app3 a yoo ṣe oṣere kan pẹlu ihuwasi ti o yatọ diẹ: dipo yiyan laileto ẹrọ orin atẹle, yoo ṣiṣẹ ni ibamu si algorithm-robin:

kilasi 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}")
}

Bibẹẹkọ, ihuwasi ẹrọ orin ko yatọ si ti iṣaaju, nitorinaa aworan atọka ko yipada.

Bayi a nilo idanwo kan lati ṣiṣe gbogbo eyi. Emi yoo fun koodu nikan ti idanwo naa funrararẹ, nitorinaa ki o ma ṣe daamu nkan naa pẹlu igbomikana (ni otitọ, Mo lo agbegbe idanwo ti a ṣẹda tẹlẹ lati ṣe idanwo isọpọ ti awọn ilana iṣowo miiran):

Ere idanwo()

@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;
}

Jẹ ki a ṣiṣẹ idanwo naa ki o wo akọọlẹ naa:

console o wu

Взята блокировка ключа 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!

Lati gbogbo eyi a le fa ọpọlọpọ awọn ipinnu pataki:

  • pẹlu awọn irinṣẹ pataki, awọn olupilẹṣẹ ohun elo le ṣẹda awọn ibaraenisepo isọpọ laarin awọn ohun elo laisi idilọwọ ọgbọn iṣowo;
  • idiju ti iṣẹ-ṣiṣe iṣọpọ ti o nilo awọn oye imọ-ẹrọ le wa ni pamọ laarin ilana ti eyi ba wa ni ibẹrẹ akọkọ ninu faaji ti ilana naa. Iṣoro ti iṣoro ko le farapamọ, nitorina ojutu si iṣoro ti o nira ni koodu yoo dabi rẹ;
  • Nigbati o ba n dagbasoke ọgbọn iṣọpọ, o jẹ dandan lati ṣe akiyesi aitasera iṣẹlẹ ati aini laini ti awọn ayipada ni ipo ti gbogbo awọn olukopa isọpọ. Eyi fi agbara mu wa lati ṣe idiju ọgbọn naa lati jẹ ki o jẹ aibikita si aṣẹ ninu eyiti awọn iṣẹlẹ ita waye. Ninu apẹẹrẹ wa, ẹrọ orin naa ti fi agbara mu lati kopa ninu ere lẹhin ti o sọ ijade rẹ lati ere: awọn oṣere miiran yoo tẹsiwaju lati fi bọọlu fun u titi ti alaye nipa ijade rẹ yoo de ati ti gbogbo awọn olukopa ṣe ilana. Imọye yii ko tẹle lati awọn ofin ti ere ati pe o jẹ ojutu adehun laarin ilana ti faaji ti o yan.

Nigbamii ti, a yoo sọrọ nipa orisirisi awọn intricacies ti wa ojutu, compromises ati awọn miiran ojuami.

Gbogbo awọn ifiranṣẹ wa ni isinyi kan

Gbogbo ese ohun elo ṣiṣẹ pẹlu ọkan Integration akero, eyi ti o ti gbekalẹ ni awọn fọọmu ti ita alagbata, ọkan BPMQueue fun awọn ifiranṣẹ ati ọkan BPMTopic koko fun awọn ifihan agbara (awọn iṣẹlẹ). Gbigbe gbogbo awọn ifiranṣẹ nipasẹ isinyi kan funrararẹ jẹ adehun. Ni ipele oye iṣowo, o le ṣafihan bi ọpọlọpọ awọn iru ifiranṣẹ tuntun bi o ṣe fẹ laisi ṣiṣe awọn ayipada si eto eto. Eyi jẹ simplification pataki, ṣugbọn o gbejade awọn eewu kan, eyiti o wa ni ipo ti awọn iṣẹ-ṣiṣe aṣoju wa ko dabi pataki si wa.

BPM ara Integration

Sibẹsibẹ, arekereke kan wa nibi: ohun elo kọọkan ṣe asẹ awọn ifiranṣẹ “awọn” rẹ lati isinyi ni ẹnu-ọna, nipasẹ orukọ agbegbe rẹ. Agbegbe naa tun le ṣe pato ni awọn ifihan agbara ti o ba nilo lati fi opin si “ipin ti hihan” ti ifihan si ohun elo ẹyọkan. Eyi yẹ ki o pọ si iṣiṣi ọkọ akero, ṣugbọn ọgbọn iṣowo gbọdọ ṣiṣẹ bayi pẹlu awọn orukọ ìkápá: fun sisọ awọn ifiranṣẹ - dandan, fun awọn ifihan agbara - wuni.

Aridaju Integration Bus Gbẹkẹle

Igbẹkẹle ni awọn aaye pupọ:

  • Alagbata ifiranṣẹ ti o yan jẹ paati pataki ti faaji ati aaye ikuna kan: o gbọdọ jẹ ọlọdun ẹbi to. O yẹ ki o lo awọn imuse idanwo akoko nikan, pẹlu atilẹyin to dara ati agbegbe nla;
  • o jẹ dandan lati rii daju wiwa giga ti alagbata ifiranṣẹ, fun eyiti o gbọdọ jẹ ti ara niya lati awọn ohun elo ti a ṣepọ (wiwa giga ti awọn ohun elo pẹlu ọgbọn iṣowo ti a lo jẹ pupọ sii nira ati gbowolori lati rii daju);
  • alagbata jẹ dandan lati pese awọn iṣeduro ifijiṣẹ "o kere ju ẹẹkan". Eyi jẹ ibeere dandan fun iṣẹ igbẹkẹle ti ọkọ akero iṣọpọ. Ko si iwulo fun awọn iṣeduro ipele “gangan ni ẹẹkan”: awọn ilana iṣowo, bi ofin, ko ni itara si dide ti awọn ifiranṣẹ tabi awọn iṣẹlẹ leralera, ati ni awọn iṣẹ ṣiṣe pataki nibiti eyi ṣe pataki, o rọrun lati ṣafikun awọn sọwedowo afikun si iṣowo naa. ọgbọn ju lati lo nigbagbogbo awọn iṣeduro “gbowolori” ”;
  • fifiranṣẹ awọn ifiranṣẹ ati awọn ifihan agbara gbọdọ ni ipa ninu idunadura gbogbogbo pẹlu awọn ayipada ni ipo awọn ilana iṣowo ati data agbegbe. Aṣayan ti o fẹ julọ yoo jẹ lati lo apẹrẹ kan Apoti Idunadura, ṣugbọn o yoo beere afikun tabili ni database ati ki o kan repeater. Ninu awọn ohun elo JEE, eyi le jẹ irọrun nipasẹ lilo oluṣakoso JTA agbegbe, ṣugbọn asopọ si alagbata ti o yan gbọdọ ni anfani lati ṣiṣẹ ni XA;
  • awọn olutọju ti awọn ifiranṣẹ ti nwọle ati awọn iṣẹlẹ gbọdọ tun ṣiṣẹ pẹlu iṣowo ti o ṣe iyipada ipo ti ilana iṣowo: ti iru iṣowo bẹẹ ba ti yiyi pada, lẹhinna gbigba ifiranṣẹ naa gbọdọ fagile;
  • awọn ifiranṣẹ ti ko le jiṣẹ nitori awọn aṣiṣe gbọdọ wa ni ipamọ ni ibi ipamọ ọtọtọ D.L.Q. (Òkú Lẹta isinyi). Fun idi eyi, a ṣẹda microservice Syeed ọtọtọ ti o tọju iru awọn ifiranṣẹ sinu ibi ipamọ rẹ, ṣe atọkasi wọn nipasẹ awọn abuda (fun kikojọ iyara ati wiwa), ati ṣiṣafihan API kan fun wiwo, fifiranṣẹ si adirẹsi ibi ti o nlo, ati piparẹ awọn ifiranṣẹ. Awọn alakoso eto le ṣiṣẹ pẹlu iṣẹ yii nipasẹ wiwo wẹẹbu wọn;
  • ninu awọn eto alagbata, o nilo lati ṣatunṣe nọmba awọn atunwi ifijiṣẹ ati awọn idaduro laarin awọn ifijiṣẹ lati dinku iṣeeṣe ti awọn ifiranṣẹ ti nwọle sinu DLQ (o fẹrẹ jẹ ko ṣee ṣe lati ṣe iṣiro awọn aye to dara julọ, ṣugbọn o le ṣiṣẹ ni agbara ati ṣatunṣe wọn lakoko iṣẹ. );
  • Ile itaja DLQ gbọdọ wa ni abojuto nigbagbogbo, ati pe eto ibojuwo gbọdọ ṣe akiyesi awọn alabojuto eto pe nigbati awọn ifiranṣẹ ti a ko firanṣẹ ba waye, wọn le dahun ni yarayara bi o ti ṣee. Eyi yoo dinku "agbegbe ti o kan" ti ikuna tabi aṣiṣe iṣowo;
  • ọkọ akero iṣọpọ gbọdọ jẹ aibikita si isansa igba diẹ ti awọn ohun elo: ṣiṣe alabapin si koko-ọrọ gbọdọ jẹ ti o tọ, ati pe orukọ ìkápá ti ohun elo naa gbọdọ jẹ alailẹgbẹ nitori pe nigba ti ohun elo naa ko si, ẹlomiran kii yoo gbiyanju lati ṣe ilana awọn ifiranṣẹ rẹ lati ọdọ isinyi.

Aridaju aabo okun ti oye iṣowo

Apẹẹrẹ kanna ti ilana iṣowo le gba awọn ifiranṣẹ pupọ ati awọn iṣẹlẹ ni ẹẹkan, sisẹ eyiti yoo bẹrẹ ni afiwe. Ni akoko kanna, fun olupilẹṣẹ ohun elo, ohun gbogbo yẹ ki o rọrun ati okun-ailewu.

Imọye iṣowo ti ilana kan ṣe ilana iṣẹlẹ ita kọọkan ti o kan ilana iṣowo yẹn ni ẹyọkan. Iru awọn iṣẹlẹ le jẹ:

  • ifilọlẹ apẹẹrẹ ilana iṣowo;
  • igbese olumulo ti o ni ibatan si iṣẹ ṣiṣe laarin ilana iṣowo;
  • gbigba ifiranṣẹ tabi ifihan agbara si eyiti apẹẹrẹ ilana iṣowo ti ṣe alabapin;
  • nfa aago ṣeto nipasẹ apẹẹrẹ ilana iṣowo;
  • igbese iṣakoso nipasẹ API (fun apẹẹrẹ, idalọwọduro ilana).

Iru iṣẹlẹ kọọkan le yi ipo ilana iṣowo pada: diẹ ninu awọn iṣe le pari ati awọn miiran le bẹrẹ, ati awọn iye ti awọn ohun-ini itẹramọ le yipada. Pipade iṣẹ ṣiṣe eyikeyi le ja si imuṣiṣẹ ti ọkan tabi diẹ ẹ sii ti awọn iṣẹ atẹle. Awọn, ni ọna, le da duro fun awọn iṣẹlẹ miiran tabi, ti wọn ko ba nilo eyikeyi data afikun, le pari ni idunadura kanna. Ṣaaju ki o to pa idunadura naa, ipo titun ti ilana iṣowo ti wa ni ipamọ ni ibi ipamọ data, nibiti yoo duro fun iṣẹlẹ ita ti o tẹle lati ṣẹlẹ.

Awọn data ilana iṣowo igbagbogbo ti o fipamọ sinu aaye data ibatan jẹ aaye ti o rọrun pupọ fun sisẹ mimuuṣiṣẹpọ ti o ba lo Yan FUN imudojuiwọn. Ti iṣowo kan ba ṣakoso lati gba ipo ti ilana iṣowo lati ipilẹ fun iyipada rẹ, lẹhinna ko si iṣowo miiran ni afiwe yoo ni anfani lati gba ipo kanna fun iyipada miiran, ati lẹhin ipari ti iṣowo akọkọ, ekeji jẹ ẹri lati gba awọn tẹlẹ yi pada ipinle.

Lilo awọn titiipa ireti ni ẹgbẹ DBMS, a mu gbogbo awọn ibeere pataki ṣẹ ACID, ati tun ṣe idaduro agbara lati ṣe iwọn ohun elo naa pẹlu ọgbọn iṣowo nipa jijẹ nọmba awọn iṣẹlẹ ti nṣiṣẹ.

Bibẹẹkọ, awọn titiipa aifokanbalẹ n halẹ mọ wa pẹlu awọn titiipa, eyi ti o tumọ si pe YAN FUN Imudojuiwọn yẹ ki o tun ni opin si diẹ ninu akoko asiko ti o ni oye ti awọn titiipa ba waye lori diẹ ninu awọn ọran ti o buruju ninu ọgbọn iṣowo.

Iṣoro miiran ni mimuuṣiṣẹpọ ti ibẹrẹ ilana iṣowo kan. Lakoko ti ko si apẹẹrẹ ti ilana iṣowo, ko si ipinlẹ ninu ibi ipamọ data, nitorinaa ọna ti a ṣalaye kii yoo ṣiṣẹ. Ti o ba nilo lati rii daju iyasọtọ ti apẹẹrẹ ilana iṣowo ni aaye kan pato, lẹhinna iwọ yoo nilo diẹ ninu iru ohun mimuuṣiṣẹpọ ti o ni nkan ṣe pẹlu kilasi ilana ati ipari ti o baamu. Lati yanju iṣoro yii, a lo ọna titiipa ti o yatọ ti o fun wa laaye lati mu titiipa kan lori orisun lainidii ti a ṣalaye nipasẹ bọtini kan ni ọna kika URI nipasẹ iṣẹ ita.

Ninu awọn apẹẹrẹ wa, ilana iṣowo InitialPlayer ni ikede kan ninu

uniqueConstraint = UniqueConstraints.singleton

Nitorinaa, akọọlẹ naa ni awọn ifiranṣẹ nipa gbigbe ati jijade titiipa bọtini ibaamu naa. Ko si iru awọn ifiranṣẹ fun awọn ilana iṣowo miiran: uniqueConstraint ko ṣeto.

Awọn iṣoro ti awọn ilana iṣowo pẹlu ipo itẹramọṣẹ

Nigba miiran nini ipo itẹramọṣẹ kii ṣe iranlọwọ nikan, ṣugbọn tun ṣe idiwọ idagbasoke gaan.
Awọn iṣoro bẹrẹ nigbati awọn ayipada nilo lati ṣe si iṣaro iṣowo ati/tabi awoṣe ilana iṣowo. Kii ṣe gbogbo iru iyipada bẹ ni ibamu pẹlu ipo atijọ ti awọn ilana iṣowo. Ti ọpọlọpọ awọn iṣẹlẹ laaye ni ibi ipamọ data, lẹhinna ṣiṣe awọn iyipada ti ko ni ibamu le fa wahala pupọ, eyiti a nigbagbogbo pade nigba lilo jBPM.

Da lori ijinle awọn iyipada, o le ṣe ni awọn ọna meji:

  1. ṣẹda iru ilana iṣowo titun kan ki o má ba ṣe awọn iyipada ti ko ni ibamu si atijọ, ki o lo o dipo ti atijọ nigbati o ba bẹrẹ awọn iṣẹlẹ titun. Awọn ẹda atijọ yoo tẹsiwaju lati ṣiṣẹ “bi tẹlẹ”;
  2. jade lọ si ipo itẹramọṣẹ ti awọn ilana iṣowo nigbati o n ṣe imudojuiwọn ọgbọn iṣowo.

Ọna akọkọ jẹ rọrun, ṣugbọn o ni awọn idiwọn ati awọn alailanfani rẹ, fun apẹẹrẹ:

  • atunkọ ti iṣiro iṣowo ni ọpọlọpọ awọn awoṣe ilana iṣowo, jijẹ iwọn didun ti iṣiro iṣowo;
  • Nigbagbogbo iyipada lẹsẹkẹsẹ si ọgbọn iṣowo tuntun ni a nilo (ni awọn ofin ti awọn iṣẹ-ṣiṣe iṣọpọ - fẹrẹẹ nigbagbogbo);
  • Olùgbéejáde ko mọ ni aaye wo ni awọn awoṣe ti igba atijọ le paarẹ.

Ni iṣe a lo awọn ọna mejeeji, ṣugbọn ti ṣe ọpọlọpọ awọn ipinnu lati jẹ ki igbesi aye wa rọrun:

  • Ninu ibi ipamọ data, ipo itẹramọṣẹ ti ilana iṣowo kan ti wa ni ipamọ ni irọrun kika ati irọrun ni ilọsiwaju fọọmu: ni ọna kika JSON kan. Eyi ngbanilaaye awọn ijira lati ṣee ṣe mejeeji laarin ohun elo ati ni ita. Gẹgẹbi ohun asegbeyin ti o kẹhin, o le ṣe atunṣe pẹlu ọwọ (paapaa ti o wulo ni idagbasoke lakoko ti n ṣatunṣe aṣiṣe);
  • Ilana iṣowo iṣọpọ ko lo awọn orukọ ti awọn ilana iṣowo, nitorinaa ni eyikeyi akoko o ṣee ṣe lati rọpo imuse ti ọkan ninu awọn ilana ikopa pẹlu ọkan tuntun pẹlu orukọ tuntun (fun apẹẹrẹ, “InitialPlayerV2”). Asopọmọra waye nipasẹ ifiranṣẹ ati awọn orukọ ifihan agbara;
  • awoṣe ilana naa ni nọmba ẹya, eyiti a pọ si ti a ba ṣe awọn ayipada ti ko ni ibamu si awoṣe yii, ati pe nọmba yii ti wa ni fipamọ pẹlu ipo apẹẹrẹ ilana;
  • ipo itẹramọṣẹ ti ilana naa ni a ka lati ibi ipamọ data ni akọkọ sinu awoṣe ohun ti o rọrun, eyiti ilana ijira le ṣiṣẹ pẹlu ti nọmba ẹya awoṣe ba ti yipada;
  • ilana iṣiwa ti a gbe lẹgbẹẹ ọgbọn iṣowo ati pe a pe ni “ọlẹ” fun apẹẹrẹ kọọkan ti ilana iṣowo ni akoko imupadabọ rẹ lati ibi ipamọ data;
  • ti o ba nilo lati jade ni ipo ti gbogbo awọn ilana ilana ni iyara ati ni iṣọpọ, awọn solusan ijira data Ayebaye diẹ sii ni a lo, ṣugbọn o ni lati ṣiṣẹ pẹlu JSON.

Ṣe o nilo ilana miiran fun awọn ilana iṣowo?

Awọn ojutu ti a ṣalaye ninu nkan naa gba wa laaye lati di irọrun igbesi aye wa ni pataki, faagun awọn iwọn ti awọn ọran ti a yanju ni ipele idagbasoke ohun elo, ati jẹ ki imọran ipinya ọgbọn iṣowo sinu awọn iṣẹ microservices diẹ sii ti o wuyi. Lati ṣaṣeyọri eyi, ọpọlọpọ awọn iṣẹ ti a ṣe, ilana “iwọn iwuwo” pupọ fun awọn ilana iṣowo ni a ṣẹda, ati awọn paati iṣẹ lati yanju awọn iṣoro ti a mọ ni ipo ti ọpọlọpọ awọn iṣoro ohun elo. A ni ifẹ lati pin awọn abajade wọnyi ki o jẹ ki idagbasoke awọn paati ti o wọpọ ṣii iraye si labẹ iwe-aṣẹ ọfẹ. Eyi yoo nilo igbiyanju ati akoko diẹ. Loye ibeere fun iru awọn ojutu le jẹ afikun imoriya fun wa. Ninu nkan ti a dabaa, akiyesi diẹ ni a san si awọn agbara ti ilana funrararẹ, ṣugbọn diẹ ninu wọn han lati awọn apẹẹrẹ ti a gbekalẹ. Ti a ba ṣe atẹjade ilana wa, nkan lọtọ yoo yasọtọ si. Lakoko, a yoo dupẹ ti o ba fi esi diẹ silẹ nipa didahun ibeere naa:

Awọn olumulo ti o forukọsilẹ nikan le kopa ninu iwadi naa. wọle, Jowo.

Ṣe o nilo ilana miiran fun awọn ilana iṣowo?

  • 18,8%Bẹẹni, Mo ti n wa iru eyi fun igba pipẹ

  • 12,5%Mo nifẹ si imọ diẹ sii nipa imuse rẹ, o le wulo2

  • 6,2%A lo ọkan ninu awọn ilana ti o wa tẹlẹ, ṣugbọn n ronu nipa rirọpo1

  • 18,8%A lo ọkan ninu awọn ilana ti o wa tẹlẹ, ohun gbogbo dara3

  • 18,8%a ṣakoso laisi ilana3

  • 25,0%kọ tirẹ4

16 olumulo dibo. 7 olumulo abstained.

orisun: www.habr.com

Fi ọrọìwòye kun