பிபிஎம் பாணி ஒருங்கிணைப்பு

பிபிஎம் பாணி ஒருங்கிணைப்பு

ஹலோ ஹப்ர்!

எங்கள் நிறுவனம் ஈஆர்பி-வகுப்பு மென்பொருள் தீர்வுகளை உருவாக்குவதில் நிபுணத்துவம் பெற்றது, இதில் சிங்கத்தின் பங்கு பரிவர்த்தனை அமைப்புகளால் பெரிய அளவிலான வணிக தர்க்கம் மற்றும் பணிப்பாய்வு a la EDMS மூலம் ஆக்கிரமிக்கப்பட்டுள்ளது. எங்கள் தயாரிப்புகளின் நவீன பதிப்புகள் JavaEE தொழில்நுட்பங்களை அடிப்படையாகக் கொண்டவை, ஆனால் நாங்கள் மைக்ரோ சர்வீஸ்களிலும் தீவிரமாக பரிசோதனை செய்து வருகிறோம். அத்தகைய தீர்வுகளின் மிகவும் சிக்கலான பகுதிகளில் ஒன்று, அருகிலுள்ள டொமைன்களுடன் தொடர்புடைய பல்வேறு துணை அமைப்புகளின் ஒருங்கிணைப்பு ஆகும். நாம் பயன்படுத்தும் கட்டடக்கலை பாணிகள், தொழில்நுட்ப அடுக்குகள் மற்றும் கட்டமைப்பைப் பொருட்படுத்தாமல் ஒருங்கிணைப்பு பணிகள் எப்போதும் எங்களுக்கு பெரும் தலைவலியைக் கொடுத்துள்ளன, ஆனால் சமீபத்தில் இதுபோன்ற சிக்கல்களைத் தீர்ப்பதில் முன்னேற்றம் ஏற்பட்டுள்ளது.

உங்கள் கவனத்திற்குக் கொண்டுவரப்பட்ட கட்டுரையில், நியமிக்கப்பட்ட பகுதியில் NPO கிறிஸ்டாவின் அனுபவம் மற்றும் கட்டடக்கலை ஆராய்ச்சி பற்றி பேசுவேன். பயன்பாட்டு டெவலப்பரின் பார்வையில் இருந்து ஒருங்கிணைப்பு சிக்கலுக்கான எளிய தீர்வின் உதாரணத்தையும் நாங்கள் கருத்தில் கொள்வோம், மேலும் இந்த எளிமைக்கு பின்னால் என்ன மறைக்கப்பட்டுள்ளது என்பதைக் கண்டுபிடிப்போம்.

மறுப்பு

கட்டுரையில் விவரிக்கப்பட்டுள்ள கட்டடக்கலை மற்றும் தொழில்நுட்ப தீர்வுகள் குறிப்பிட்ட பணிகளின் சூழலில் தனிப்பட்ட அனுபவத்தின் அடிப்படையில் என்னால் வழங்கப்படுகின்றன. இந்த தீர்வுகள் உலகளாவியவை என்று கூறவில்லை மற்றும் பிற பயன்பாட்டு நிலைமைகளின் கீழ் உகந்ததாக இருக்காது.

BPM க்கும் இதற்கும் என்ன சம்பந்தம்?

இந்த கேள்விக்கு பதிலளிக்க, எங்கள் தீர்வுகளின் பயன்பாட்டு சிக்கல்களின் பிரத்தியேகங்களை நாம் சிறிது ஆராய வேண்டும். எங்கள் வழக்கமான பரிவர்த்தனை அமைப்பில் உள்ள வணிக தர்க்கத்தின் முக்கிய பகுதி, பயனர் இடைமுகங்கள் மூலம் தரவுத்தளத்தில் தரவை உள்ளிடுவது, கைமுறையாகவும் தானாகவே இந்தத் தரவைச் சரிபார்த்து, சில பணிப்பாய்வு மூலம் அதை அனுப்பவும், மற்றொரு அமைப்பு / பகுப்பாய்வு தரவுத்தளம் / காப்பகத்தில் வெளியிடுதல், அறிக்கைகளை உருவாக்குதல். எனவே, வாடிக்கையாளர்களுக்கான அமைப்பின் முக்கிய செயல்பாடு அவர்களின் உள் வணிக செயல்முறைகளின் ஆட்டோமேஷன் ஆகும்.

வசதிக்காக, ஒரு குறிப்பிட்ட பணிப்பாய்வு "இணைக்கப்படக்கூடிய" பொதுவான விசையால் ஒன்றிணைக்கப்பட்ட தரவுத் தொகுப்பின் சில சுருக்கமாக, தகவல்தொடர்புகளில் "ஆவணம்" என்ற சொல்லைப் பயன்படுத்துகிறோம்.
ஆனால் ஒருங்கிணைப்பு தர்க்கம் பற்றி என்ன? எல்லாவற்றிற்கும் மேலாக, ஒருங்கிணைப்பு பணி அமைப்பின் கட்டமைப்பால் உருவாக்கப்படுகிறது, இது வாடிக்கையாளரின் வேண்டுகோளின் பேரில் அல்ல, ஆனால் முற்றிலும் மாறுபட்ட காரணிகளின் செல்வாக்கின் கீழ் பகுதிகளாக "அறுக்கப்படுகிறது":

  • கான்வேயின் சட்டத்தின் செல்வாக்கின் கீழ்;
  • பிற தயாரிப்புகளுக்காக முன்னர் உருவாக்கப்பட்ட துணை அமைப்புகளின் மறுபயன்பாட்டின் விளைவாக;
  • செயல்படாத தேவைகளின் அடிப்படையில் கட்டிடக் கலைஞரால் முடிவு செய்யப்பட்டது.

ஒருங்கிணைப்பு கலைப்பொருட்கள் மூலம் வணிக தர்க்கத்தை மாசுபடுத்தாமல் இருக்கவும், கணினியின் கட்டடக்கலை நிலப்பரப்பின் தனித்தன்மையை ஆராய்வதில் இருந்து பயன்பாட்டு டெவலப்பரை காப்பாற்றவும், முக்கிய பணிப்பாய்வுகளின் வணிக தர்க்கத்திலிருந்து ஒருங்கிணைப்பு தர்க்கத்தை பிரிக்க ஒரு பெரிய தூண்டுதல் உள்ளது. இந்த அணுகுமுறை பல நன்மைகளைக் கொண்டுள்ளது, ஆனால் நடைமுறை அதன் திறமையின்மையைக் காட்டுகிறது:

  • ஒருங்கிணைப்பு சிக்கல்களைத் தீர்ப்பது பொதுவாக முக்கிய பணிப்பாய்வுகளை செயல்படுத்துவதில் வரையறுக்கப்பட்ட நீட்டிப்பு புள்ளிகள் காரணமாக ஒத்திசைவான அழைப்புகளின் வடிவத்தில் எளிமையான விருப்பங்களுக்குச் செல்கிறது (கீழே உள்ள ஒத்திசைவான ஒருங்கிணைப்பின் குறைபாடுகள் பற்றி மேலும்);
  • மற்றொரு துணை அமைப்பிலிருந்து பின்னூட்டம் தேவைப்படும்போது ஒருங்கிணைப்பு கலைப்பொருட்கள் முக்கிய வணிக தர்க்கத்தை இன்னும் ஊடுருவுகின்றன;
  • பயன்பாட்டு டெவலப்பர் ஒருங்கிணைப்பை புறக்கணித்து, பணிப்பாய்வுகளை மாற்றுவதன் மூலம் அதை எளிதாக உடைக்க முடியும்;
  • பயனரின் பார்வையில் இருந்து கணினி முழுவதுமாக இருப்பதை நிறுத்துகிறது, துணை அமைப்புகளுக்கு இடையே உள்ள "சீம்கள்" கவனிக்கத்தக்கதாக மாறும், தேவையற்ற பயனர் செயல்பாடுகள் தோன்றும், அவை ஒரு துணை அமைப்பிலிருந்து மற்றொரு துணை அமைப்பிற்கு தரவு பரிமாற்றத்தைத் தொடங்குகின்றன.

மற்றொரு அணுகுமுறை ஒருங்கிணைப்பு தொடர்புகளை முக்கிய வணிக தர்க்கம் மற்றும் பணிப்பாய்வு ஆகியவற்றின் ஒருங்கிணைந்த பகுதியாகக் கருதுவதாகும். அப்ளிகேஷன் டெவலப்பர்களின் திறன் தேவைகள் உயராமல் இருக்க, ஒரு தீர்வைத் தேர்ந்தெடுப்பதற்கான குறைந்தபட்ச விருப்பங்களுடன், புதிய ஒருங்கிணைப்பு தொடர்புகளை உருவாக்குவது எளிதாகவும் இயற்கையாகவும் செய்யப்பட வேண்டும். இது தோற்றமளிப்பதை விட மிகவும் கடினம்: கருவியானது பயனருக்குத் தேவையான பல்வேறு விருப்பங்களை அதன் பயன்பாட்டிற்கு வழங்குவதற்கு போதுமானதாக இருக்க வேண்டும், அதே நேரத்தில் தங்களைக் காலில் சுட அனுமதிக்காது. ஒருங்கிணைப்பு பணிகளின் பின்னணியில் ஒரு பொறியாளர் பதிலளிக்க வேண்டிய பல கேள்விகள் உள்ளன, ஆனால் ஒரு பயன்பாட்டு டெவலப்பர் தங்கள் அன்றாட வேலையில் சிந்திக்கக்கூடாது: பரிவர்த்தனை எல்லைகள், நிலைத்தன்மை, அணுசக்தி, பாதுகாப்பு, அளவிடுதல், சுமை மற்றும் வள விநியோகம், ரூட்டிங், மார்ஷலிங், பரப்புதல் மற்றும் மாறுதல் சூழல்கள் போன்றவை. பயன்பாட்டு டெவலப்பர்களுக்கு மிகவும் எளிமையான முடிவு டெம்ப்ளேட்களை வழங்குவது அவசியம், அதில் இதுபோன்ற அனைத்து கேள்விகளுக்கான பதில்களும் ஏற்கனவே மறைக்கப்பட்டுள்ளன. இந்த வடிவங்கள் போதுமான பாதுகாப்பாக இருக்க வேண்டும்: வணிக தர்க்கம் அடிக்கடி மாறுகிறது, இது பிழைகளை அறிமுகப்படுத்தும் அபாயத்தை அதிகரிக்கிறது, பிழைகளின் விலை மிகவும் குறைந்த மட்டத்தில் இருக்க வேண்டும்.

ஆனாலும், BPM க்கும் இதற்கும் என்ன சம்பந்தம்? பணிப்பாய்வு செயல்படுத்த பல விருப்பங்கள் உள்ளன ...
உண்மையில், வணிக செயல்முறைகளின் மற்றொரு செயல்படுத்தல் எங்கள் தீர்வுகளில் மிகவும் பிரபலமானது - மாநில மாற்ற வரைபடத்தின் அறிவிப்பு அமைப்பு மற்றும் மாற்றங்களுக்கு வணிக தர்க்கத்துடன் கையாளுபவர்களை இணைப்பதன் மூலம். அதே நேரத்தில், வணிகச் செயல்பாட்டில் "ஆவணத்தின்" தற்போதைய நிலையை நிர்ணயிக்கும் நிலை "ஆவணத்தின்" ஒரு பண்பு ஆகும்.

பிபிஎம் பாணி ஒருங்கிணைப்பு
திட்டத்தின் தொடக்கத்தில் செயல்முறை இப்படித்தான் இருக்கும்

அத்தகைய செயலாக்கத்தின் புகழ், நேரியல் வணிக செயல்முறைகளை உருவாக்கும் ஒப்பீட்டளவில் எளிமை மற்றும் வேகம் காரணமாகும். இருப்பினும், மென்பொருள் அமைப்புகள் மிகவும் சிக்கலானதாக இருப்பதால், வணிக செயல்முறையின் தானியங்கு பகுதி வளர்ந்து மேலும் சிக்கலானதாகிறது. சிதைவு, செயல்முறைகளின் பகுதிகளை மறுபயன்பாடு, அதே போல் ஒவ்வொரு கிளையும் இணையாக செயல்படுத்தப்பட வேண்டும். இத்தகைய நிலைமைகளின் கீழ், கருவி சிரமமாகிறது, மேலும் மாநில மாற்றம் வரைபடம் அதன் தகவல் உள்ளடக்கத்தை இழக்கிறது (ஒருங்கிணைப்பு தொடர்புகள் வரைபடத்தில் பிரதிபலிக்காது).

பிபிஎம் பாணி ஒருங்கிணைப்பு
தேவைகளை தெளிவுபடுத்துவதற்கான பல மறு செய்கைகளுக்குப் பிறகு இந்த செயல்முறை தோன்றுகிறது

இந்த சூழ்நிலையிலிருந்து வெளியேறும் வழி இயந்திரத்தின் ஒருங்கிணைப்பு ஆகும் jBPM மிகவும் சிக்கலான வணிக செயல்முறைகளைக் கொண்ட சில தயாரிப்புகளில். குறுகிய காலத்தில், இந்த தீர்வு சில வெற்றிகளைப் பெற்றது: குறியீட்டில் மிகவும் தகவலறிந்த மற்றும் புதுப்பித்த வரைபடத்தை பராமரிக்கும் போது சிக்கலான வணிக செயல்முறைகளை செயல்படுத்த முடிந்தது. பிபிஎம்என்2.

பிபிஎம் பாணி ஒருங்கிணைப்பு
சிக்கலான வணிக செயல்முறையின் ஒரு சிறிய பகுதி

நீண்ட காலத்திற்கு, தீர்வு எதிர்பார்ப்புகளுக்கு ஏற்ப வாழவில்லை: காட்சி கருவிகள் மூலம் வணிக செயல்முறைகளை உருவாக்கும் அதிக உழைப்பு தீவிரம் ஏற்றுக்கொள்ளக்கூடிய உற்பத்தித்திறன் குறிகாட்டிகளை அடைய அனுமதிக்கவில்லை, மேலும் கருவி டெவலப்பர்களிடையே மிகவும் விரும்பப்படாத ஒன்றாகும். இயந்திரத்தின் உள் அமைப்பு பற்றிய புகார்களும் இருந்தன, இது பல "இணைப்புகள்" மற்றும் "ஊன்றுகோல்" தோற்றத்திற்கு வழிவகுத்தது.

jBPM ஐப் பயன்படுத்துவதன் முக்கிய நேர்மறையான அம்சம், ஒரு வணிக செயல்முறை நிகழ்விற்கு அதன் சொந்த நிலையான நிலையைக் கொண்டிருப்பதால் ஏற்படும் நன்மைகள் மற்றும் தீங்குகளை உணர்ந்துகொள்வது ஆகும். சிக்னல்கள் மற்றும் செய்திகள் மூலம் ஒத்திசைவற்ற தொடர்புகளைப் பயன்படுத்தி வெவ்வேறு பயன்பாடுகளுக்கு இடையே சிக்கலான ஒருங்கிணைப்பு நெறிமுறைகளைச் செயல்படுத்த செயல்முறை அணுகுமுறையைப் பயன்படுத்துவதற்கான சாத்தியத்தையும் நாங்கள் கண்டோம். ஒரு நிலையான மாநிலத்தின் இருப்பு இதில் முக்கிய பங்கு வகிக்கிறது.

மேற்கூறியவற்றின் அடிப்படையில், நாம் முடிவுக்கு வரலாம்: BPM பாணியில் உள்ள செயல்முறை அணுகுமுறை, மிகவும் சிக்கலான வணிக செயல்முறைகளை தானியக்கமாக்குவதற்கான பரந்த அளவிலான பணிகளைத் தீர்க்க அனுமதிக்கிறது, இந்த செயல்முறைகளில் ஒருங்கிணைப்பு செயல்பாடுகளை இணக்கமாக பொருத்துகிறது மற்றும் செயல்படுத்தப்பட்ட செயல்முறையை பொருத்தமான குறிப்பில் பார்வைக்குக் காண்பிக்கும் திறனைத் தக்க வைத்துக் கொள்கிறது.

ஒருங்கிணைப்பு வடிவமாக ஒத்திசைவான அழைப்புகளின் தீமைகள்

ஒத்திசைவு ஒருங்கிணைப்பு என்பது எளிமையான தடுப்பு அழைப்பைக் குறிக்கிறது. ஒரு துணை அமைப்பு சர்வர் பக்கமாக செயல்படுகிறது மற்றும் விரும்பிய முறையில் API ஐ வெளிப்படுத்துகிறது. மற்றொரு துணை அமைப்பு ஒரு கிளையன்ட் பக்கமாக செயல்படுகிறது மற்றும் சரியான நேரத்தில், முடிவை எதிர்பார்த்து அழைப்பை செய்கிறது. கணினியின் கட்டமைப்பைப் பொறுத்து, கிளையன்ட் மற்றும் சர்வர் பக்கங்களை ஒரே பயன்பாடு மற்றும் செயல்பாட்டில் அல்லது வெவ்வேறுவற்றில் ஹோஸ்ட் செய்யலாம். இரண்டாவது வழக்கில், நீங்கள் RPC இன் சில செயல்படுத்தலைப் பயன்படுத்த வேண்டும் மற்றும் அளவுருக்களின் மார்ஷலிங் மற்றும் அழைப்பின் முடிவை வழங்க வேண்டும்.

பிபிஎம் பாணி ஒருங்கிணைப்பு

இத்தகைய ஒருங்கிணைப்பு முறை மிகவும் பெரிய குறைபாடுகளைக் கொண்டுள்ளது, ஆனால் அதன் எளிமை காரணமாக இது மிகவும் பரவலாக நடைமுறையில் பயன்படுத்தப்படுகிறது. செயல்படுத்தும் வேகம் கவர்ந்திழுக்கிறது மற்றும் "எரியும்" காலக்கெடுவின் நிலைமைகளில் அதை மீண்டும் மீண்டும் பயன்படுத்துகிறது, தீர்வை தொழில்நுட்ப கடனில் எழுதுகிறது. ஆனால் அனுபவமற்ற டெவலப்பர்கள் எதிர்மறையான விளைவுகளை உணராமல், அறியாமலேயே அதைப் பயன்படுத்துகிறார்கள்.

துணை அமைப்புகளின் இணைப்பில் மிகவும் வெளிப்படையான அதிகரிப்புக்கு கூடுதலாக, "பரவுதல்" மற்றும் "நீட்டுதல்" பரிவர்த்தனைகளில் குறைவான வெளிப்படையான சிக்கல்கள் உள்ளன. உண்மையில், வணிக தர்க்கம் ஏதேனும் மாற்றங்களைச் செய்தால், பரிவர்த்தனைகள் இன்றியமையாதவை, மேலும் பரிவர்த்தனைகள் இந்த மாற்றங்களால் பாதிக்கப்பட்ட சில பயன்பாட்டு ஆதாரங்களை பூட்டுகின்றன. அதாவது, ஒரு துணை அமைப்பு மற்றொருவரின் பதிலுக்காக காத்திருக்கும் வரை, பரிவர்த்தனையை முடித்து பூட்டுகளை வெளியிட முடியாது. இது பல்வேறு விளைவுகளின் அபாயத்தை கணிசமாக அதிகரிக்கிறது:

  • கணினி மறுமொழி இழக்கப்படுகிறது, பயனர்கள் கோரிக்கைகளுக்கான பதில்களுக்காக நீண்ட நேரம் காத்திருக்கிறார்கள்;
  • நிரம்பி வழியும் த்ரெட் பூல் காரணமாக சர்வர் பொதுவாக பயனர் கோரிக்கைகளுக்கு பதிலளிப்பதை நிறுத்துகிறது: பெரும்பாலான த்ரெட்கள் பரிவர்த்தனையால் ஆக்கிரமிக்கப்பட்ட வளத்தின் பூட்டில் "நிற்பவை";
  • முட்டுக்கட்டைகள் தோன்றத் தொடங்குகின்றன: அவை நிகழும் நிகழ்தகவு பரிவர்த்தனைகளின் காலம், வணிக தர்க்கத்தின் அளவு மற்றும் பரிவர்த்தனையில் ஈடுபட்டுள்ள பூட்டுகள் ஆகியவற்றைப் பொறுத்தது;
  • பரிவர்த்தனை காலாவதி காலாவதி பிழைகள் தோன்றும்;
  • பணிக்கு அதிக அளவிலான தரவை செயலாக்குதல் மற்றும் மாற்றுதல் தேவைப்பட்டால், சேவையகம் OutOfMemory இல் "விழும்", மேலும் ஒத்திசைவான ஒருங்கிணைப்புகளின் இருப்பு செயலாக்கத்தை "இலகுவான" பரிவர்த்தனைகளாகப் பிரிப்பதை மிகவும் கடினமாக்குகிறது.

கட்டடக்கலைக் கண்ணோட்டத்தில், ஒருங்கிணைப்பின் போது அழைப்புகளைத் தடுப்பது தனிப்பட்ட துணை அமைப்புகளின் தரக் கட்டுப்பாட்டை இழக்க வழிவகுக்கிறது: ஒரு துணை அமைப்பின் தர இலக்குகளை மற்றொரு துணை அமைப்பின் தர இலக்குகளிலிருந்து தனிமைப்படுத்துவது சாத்தியமில்லை. துணை அமைப்புகள் வெவ்வேறு குழுக்களால் உருவாக்கப்பட்டால், இது ஒரு பெரிய பிரச்சனை.

ஒருங்கிணைக்கப்படும் துணை அமைப்புகள் வெவ்வேறு பயன்பாடுகளில் இருந்தால், இரண்டு பக்கங்களிலும் ஒத்திசைவான மாற்றங்கள் செய்யப்பட வேண்டும் என்றால் விஷயங்கள் இன்னும் சுவாரஸ்யமாக இருக்கும். இந்த மாற்றங்களை எவ்வாறு பரிவர்த்தனையாக மாற்றுவது?

தனிப்பட்ட பரிவர்த்தனைகளில் மாற்றங்கள் செய்யப்பட்டால், வலுவான விதிவிலக்கு கையாளுதல் மற்றும் இழப்பீடு வழங்கப்பட வேண்டும், மேலும் இது ஒத்திசைவான ஒருங்கிணைப்புகளின் முக்கிய நன்மையை முற்றிலும் நீக்குகிறது - எளிமை.

விநியோகிக்கப்பட்ட பரிவர்த்தனைகளும் நினைவுக்கு வருகின்றன, ஆனால் அவற்றை நாங்கள் எங்கள் தீர்வுகளில் பயன்படுத்துவதில்லை: நம்பகத்தன்மையை உறுதிப்படுத்துவது கடினம்.

பரிவர்த்தனைகளின் சிக்கலுக்கு தீர்வாக "சாகா"

மைக்ரோ சர்வீஸின் பிரபலமடைந்து வருவதால், அதற்கான தேவை அதிகரித்து வருகிறது சாகா முறை.

இந்த முறை நீண்ட பரிவர்த்தனைகளின் மேற்கூறிய சிக்கல்களை மிகச்சரியாக தீர்க்கிறது, மேலும் வணிக தர்க்கத்தின் பக்கத்திலிருந்து அமைப்பின் நிலையை நிர்வகிப்பதற்கான சாத்தியக்கூறுகளை விரிவுபடுத்துகிறது: தோல்வியுற்ற பரிவர்த்தனைக்குப் பிறகு இழப்பீடு கணினியை அதன் அசல் நிலைக்குத் திரும்பப் பெறாது, ஆனால் மாற்றீட்டை வழங்குகிறது. தரவு செயலாக்க பாதை. நீங்கள் செயல்முறையை "நல்ல" முடிவுக்கு கொண்டு வர முயற்சிக்கும்போது, ​​வெற்றிகரமாக முடிக்கப்பட்ட தரவு செயலாக்க படிகளை மீண்டும் செய்யாமல் இருக்கவும் இது உங்களை அனுமதிக்கிறது.

சுவாரஸ்யமாக, மோனோலிதிக் அமைப்புகளில், தளர்வான இணைக்கப்பட்ட துணை அமைப்புகளின் ஒருங்கிணைப்பு மற்றும் நீண்ட பரிவர்த்தனைகள் மற்றும் தொடர்புடைய ஆதார பூட்டுகளால் எதிர்மறையான விளைவுகள் ஏற்படும் போது இந்த முறை பொருத்தமானது.

BPM பாணியில் எங்கள் வணிகச் செயல்முறைகளைப் பொறுத்தவரை, சாகாஸைச் செயல்படுத்துவது மிகவும் எளிதானது: சாகாஸின் தனிப்பட்ட படிகள் வணிகச் செயல்பாட்டிற்குள் செயல்பாடுகளாக அமைக்கப்படலாம், மேலும் வணிகச் செயல்முறையின் நிலையான நிலை மற்றவற்றுடன் தீர்மானிக்கிறது. , சகாக்களின் உள் நிலை. அதாவது, எங்களுக்கு எந்த கூடுதல் ஒருங்கிணைப்பு பொறிமுறையும் தேவையில்லை. "குறைந்த பட்சம் ஒரு முறை" உத்தரவாதத்திற்கான ஆதரவுடன் ஒரு செய்தி தரகர் உங்களுக்குத் தேவை.

ஆனால் அத்தகைய தீர்வுக்கு அதன் சொந்த "விலை" உள்ளது:

  • வணிக தர்க்கம் மிகவும் சிக்கலானதாகிறது: நீங்கள் இழப்பீடு செய்ய வேண்டும்;
  • முழு நிலைத்தன்மையையும் கைவிடுவது அவசியம், இது ஒற்றைக்கல் அமைப்புகளுக்கு குறிப்பாக உணர்திறன் கொண்டது;
  • கட்டிடக்கலை இன்னும் கொஞ்சம் சிக்கலாகிறது, ஒரு செய்தி தரகரின் கூடுதல் தேவை உள்ளது;
  • கூடுதல் கண்காணிப்பு மற்றும் நிர்வாகக் கருவிகள் தேவைப்படும் (பொதுவாக இது நன்றாக இருந்தாலும்: கணினி சேவையின் தரம் அதிகரிக்கும்).

மோனோலிதிக் அமைப்புகளுக்கு, "Sags" ஐப் பயன்படுத்துவதற்கான நியாயம் அவ்வளவு தெளிவாக இல்லை. மைக்ரோ சர்வீஸ்கள் மற்றும் பிற SOA களுக்கு, பெரும்பாலும், ஏற்கனவே ஒரு தரகர் இருக்கிறார், மேலும் திட்டத்தின் தொடக்கத்தில் முழு நிலைத்தன்மையும் தியாகம் செய்யப்பட்டது, இந்த முறையைப் பயன்படுத்துவதன் நன்மைகள் தீமைகளை விட கணிசமாக அதிகமாக இருக்கும், குறிப்பாக வசதியான API இருந்தால் வணிக தர்க்க நிலை.

மைக்ரோ சர்வீஸில் வணிக தர்க்கத்தின் இணைத்தல்

நாங்கள் மைக்ரோ சர்வீஸுடன் பரிசோதனை செய்யத் தொடங்கியபோது, ​​ஒரு நியாயமான கேள்வி எழுந்தது: டொமைன் தரவு நிலைத்தன்மையை வழங்கும் சேவையுடன் தொடர்புடைய டொமைன் வணிக தர்க்கத்தை எங்கே வைப்பது?

பல்வேறு BPMS இன் கட்டமைப்பைப் பார்க்கும்போது, ​​வணிக தர்க்கத்தை விடாமுயற்சியிலிருந்து பிரிப்பது நியாயமானதாகத் தோன்றலாம்: டொமைன் வணிக தர்க்கத்தை செயல்படுத்துவதற்கான சூழல் மற்றும் கொள்கலனை உருவாக்கும் தளம் மற்றும் டொமைன்-சுயாதீன மைக்ரோ சர்வீஸ்களின் அடுக்கை உருவாக்கவும், மேலும் டொமைன் தரவு நிலைத்தன்மையை தனித்தனியாக ஏற்பாடு செய்யவும். மிகவும் எளிமையான மற்றும் இலகுரக மைக்ரோ சர்வீஸின் அடுக்கு. இந்த வழக்கில் வணிக செயல்முறைகள் நிலைத்தன்மை அடுக்கு சேவைகளை ஒழுங்கமைக்கிறது.

பிபிஎம் பாணி ஒருங்கிணைப்பு

இந்த அணுகுமுறை மிகப் பெரிய பிளஸைக் கொண்டுள்ளது: நீங்கள் விரும்பும் அளவுக்கு இயங்குதளத்தின் செயல்பாட்டை நீங்கள் அதிகரிக்கலாம், மேலும் அதனுடன் தொடர்புடைய பிளாட்ஃபார்ம் மைக்ரோ சர்வீசஸ் அடுக்கு மட்டுமே இதிலிருந்து "கொழுப்பைப் பெறும்". எந்தவொரு டொமைனிலிருந்தும் வணிகச் செயல்முறைகள், பிளாட்ஃபார்ம் புதுப்பிக்கப்பட்டவுடன் அதன் புதிய செயல்பாட்டைப் பயன்படுத்துவதற்கான வாய்ப்பை உடனடியாகப் பெறுகின்றன.

ஒரு விரிவான ஆய்வு இந்த அணுகுமுறையின் குறிப்பிடத்தக்க குறைபாடுகளை வெளிப்படுத்தியது:

  • பல டொமைன்களின் வணிக தர்க்கத்தை ஒரே நேரத்தில் செயல்படுத்தும் ஒரு இயங்குதள சேவையானது ஒரு தோல்வியின் ஒரு புள்ளியாக பெரும் அபாயங்களைக் கொண்டுள்ளது. வணிக தர்க்கத்தில் அடிக்கடி ஏற்படும் மாற்றங்கள் கணினி அளவிலான தோல்விகளுக்கு வழிவகுக்கும் பிழைகளின் அபாயத்தை அதிகரிக்கின்றன;
  • செயல்திறன் சிக்கல்கள்: வணிக தர்க்கம் அதன் தரவுகளுடன் குறுகிய மற்றும் மெதுவான இடைமுகம் மூலம் செயல்படுகிறது:
    • தரவு மீண்டும் மார்ஷல் செய்யப்பட்டு நெட்வொர்க் ஸ்டேக் மூலம் உந்தப்படும்;
    • சேவையின் வெளிப்புற ஏபிஐ மட்டத்தில் போதுமான வினவல் அளவுரு திறன்கள் இல்லாததால், டொமைன் சேவையானது செயலாக்கத்திற்குத் தேவைப்படும் வணிக தர்க்கத்தை விட அதிகமான தரவை வழங்கும்;
    • பல சுயாதீனமான வணிக தர்க்கங்கள் அதே தரவை செயலாக்கத்திற்கு மீண்டும் மீண்டும் கோரலாம் (தரவை கேச் செய்யும் அமர்வு பீன்ஸ் சேர்ப்பதன் மூலம் இந்த சிக்கலை நீங்கள் குறைக்கலாம், ஆனால் இது கட்டமைப்பை மேலும் சிக்கலாக்குகிறது மற்றும் தரவு புத்துணர்ச்சி மற்றும் கேச் செல்லாத பிரச்சனைகளை உருவாக்குகிறது);
  • பரிவர்த்தனை சிக்கல்கள்:
    • இயங்குதள சேவையால் சேமிக்கப்பட்ட நிலையான நிலையுடன் வணிக செயல்முறைகள் டொமைன் தரவுகளுடன் முரண்படுகின்றன, மேலும் இந்த சிக்கலை தீர்க்க எளிதான வழிகள் எதுவும் இல்லை;
    • டொமைன் தரவின் பூட்டை பரிவர்த்தனைக்கு வெளியே நகர்த்துதல்: டொமைன் வணிக தர்க்கம் மாற்றங்களைச் செய்ய வேண்டுமானால், முதலில் உண்மையான தரவின் சரியான தன்மையை சரிபார்த்த பிறகு, செயலாக்கப்பட்ட தரவில் போட்டி மாற்றத்திற்கான சாத்தியத்தை விலக்குவது அவசியம். தரவை வெளிப்புறமாகத் தடுப்பது சிக்கலைத் தீர்க்க உதவும், ஆனால் அத்தகைய தீர்வு கூடுதல் அபாயங்களைக் கொண்டுள்ளது மற்றும் அமைப்பின் ஒட்டுமொத்த நம்பகத்தன்மையைக் குறைக்கிறது;
  • புதுப்பிக்கும் போது கூடுதல் சிக்கல்கள்: சில சந்தர்ப்பங்களில், நீங்கள் நிலைத்தன்மை சேவை மற்றும் வணிக தர்க்கத்தை ஒத்திசைவாக அல்லது கண்டிப்பான வரிசையில் புதுப்பிக்க வேண்டும்.

முடிவில், நான் அடிப்படைகளுக்குச் செல்ல வேண்டியிருந்தது: டொமைன் தரவு மற்றும் டொமைன் வணிக தர்க்கத்தை ஒரு மைக்ரோ சர்வீஸில் இணைக்கவும். இந்த அணுகுமுறை மைக்ரோ சர்வீஸை கணினியில் ஒரு ஒருங்கிணைந்த அங்கமாக உணருவதை எளிதாக்குகிறது மற்றும் மேலே உள்ள சிக்கல்களுக்கு வழிவகுக்காது. இதுவும் இலவசம் அல்ல:

  • வணிக தர்க்கம் (குறிப்பாக, வணிக செயல்முறைகளின் ஒரு பகுதியாக பயனர் செயல்பாடுகளை வழங்க) மற்றும் API இயங்குதள சேவைகளுடன் தொடர்பு கொள்ள API தரநிலைப்படுத்தல் தேவைப்படுகிறது; API மாற்றங்கள், முன்னோக்கி மற்றும் பின்தங்கிய இணக்கத்தன்மைக்கு மிகவும் கவனமாக கவனம் தேவை;
  • இதுபோன்ற ஒவ்வொரு மைக்ரோ சர்வீஸின் ஒரு பகுதியாக வணிக தர்க்கத்தின் செயல்பாட்டை உறுதிப்படுத்த கூடுதல் இயக்க நேர நூலகங்களைச் சேர்க்க வேண்டும், மேலும் இது அத்தகைய நூலகங்களுக்கு புதிய தேவைகளை உருவாக்குகிறது: லேசான தன்மை மற்றும் குறைந்தபட்ச இடைநிலை சார்புகள்;
  • வணிக லாஜிக் டெவலப்பர்கள் நூலக பதிப்புகளைக் கண்காணிக்க வேண்டும்: மைக்ரோ சர்வீஸ் நீண்ட காலமாக முடிக்கப்படவில்லை என்றால், அது பெரும்பாலும் நூலகங்களின் காலாவதியான பதிப்பைக் கொண்டிருக்கும். இது ஒரு புதிய அம்சத்தைச் சேர்ப்பதற்கு எதிர்பாராத தடையாக இருக்கலாம் மற்றும் பதிப்புகளுக்கு இடையில் பொருந்தாத மாற்றங்கள் இருந்தால், அத்தகைய சேவையின் பழைய வணிக தர்க்கத்தை நூலகங்களின் புதிய பதிப்புகளுக்கு மாற்ற வேண்டியிருக்கலாம்.

பிபிஎம் பாணி ஒருங்கிணைப்பு

அத்தகைய கட்டமைப்பில் இயங்குதள சேவைகளின் அடுக்கு உள்ளது, ஆனால் இந்த அடுக்கு டொமைன் வணிக தர்க்கத்தை செயல்படுத்துவதற்கான கொள்கலனை உருவாக்காது, ஆனால் அதன் சூழல் மட்டுமே துணை "தளம்" செயல்பாடுகளை வழங்குகிறது. டொமைன் மைக்ரோ சர்வீஸின் லேசான தன்மையை பராமரிக்க மட்டுமல்லாமல், நிர்வாகத்தை மையப்படுத்தவும் இத்தகைய அடுக்கு தேவைப்படுகிறது.

எடுத்துக்காட்டாக, வணிக செயல்முறைகளில் பயனர் செயல்பாடுகள் பணிகளை உருவாக்குகின்றன. இருப்பினும், பணிகளுடன் பணிபுரியும் போது, ​​பயனர் பொதுவான பட்டியலில் உள்ள அனைத்து டொமைன்களிலிருந்தும் பணிகளைப் பார்க்க வேண்டும், அதாவது டொமைன் வணிக தர்க்கத்திலிருந்து நீக்கப்பட்ட பொருத்தமான பணி பதிவு தள சேவை இருக்க வேண்டும். இந்த சூழலில் வணிக தர்க்கத்தை இணைப்பது மிகவும் சிக்கலானது, மேலும் இது இந்த கட்டிடக்கலையின் மற்றொரு சமரசமாகும்.

பயன்பாட்டு உருவாக்குநரின் பார்வையில் வணிக செயல்முறைகளை ஒருங்கிணைத்தல்

ஏற்கனவே மேலே குறிப்பிட்டுள்ளபடி, நல்ல வளர்ச்சி உற்பத்தித்திறனை நம்புவதற்கு, பல பயன்பாடுகளின் தொடர்புகளை செயல்படுத்துவதற்கான தொழில்நுட்ப மற்றும் பொறியியல் அம்சங்களிலிருந்து பயன்பாட்டு டெவலப்பர் சுருக்கப்பட வேண்டும்.

கட்டுரைக்காக சிறப்பாகக் கண்டுபிடிக்கப்பட்ட ஒரு கடினமான ஒருங்கிணைப்பு சிக்கலைத் தீர்க்க முயற்சிப்போம். இது மூன்று பயன்பாடுகளை உள்ளடக்கிய "விளையாட்டு" பணியாக இருக்கும், அவை ஒவ்வொன்றும் சில டொமைன் பெயரை வரையறுக்கின்றன: "app1", "app2", "app3".

ஒவ்வொரு பயன்பாட்டிற்குள்ளும், ஒருங்கிணைப்பு பஸ் மூலம் "பந்து விளையாட" தொடங்கும் வணிக செயல்முறைகள் தொடங்கப்படுகின்றன. "பால்" என்று பெயரிடப்பட்ட செய்திகள் பந்தாக செயல்படும்.

விளையாட்டு விதிகள்:

  • முதல் வீரர் துவக்குபவர். அவர் மற்ற வீரர்களை விளையாட்டிற்கு அழைக்கிறார், விளையாட்டைத் தொடங்குகிறார் மற்றும் எந்த நேரத்திலும் அதை முடிக்கலாம்;
  • மற்ற வீரர்கள் விளையாட்டில் தங்கள் பங்கேற்பை அறிவிக்கிறார்கள், ஒருவருக்கொருவர் மற்றும் முதல் வீரருடன் "அறிமுகப்படுத்துங்கள்";
  • பந்தைப் பெற்ற பிறகு, வீரர் மற்றொரு பங்கேற்கும் வீரரைத் தேர்ந்தெடுத்து பந்தை அவருக்கு அனுப்புகிறார். மொத்த பாஸ்களின் எண்ணிக்கை கணக்கிடப்படுகிறது;
  • ஒவ்வொரு வீரருக்கும் "ஆற்றல்" உள்ளது, அது அந்த வீரரின் ஒவ்வொரு பந்தையும் கடந்து செல்லும். ஆற்றல் தீர்ந்துவிட்டால், வீரர் விளையாட்டிலிருந்து வெளியேற்றப்படுகிறார், அவர் தனது ஓய்வை அறிவிக்கிறார்;
  • வீரர் தனியாக இருந்தால், அவர் உடனடியாக வெளியேறுவதாக அறிவிக்கிறார்;
  • அனைத்து வீரர்களும் வெளியேற்றப்பட்டால், முதல் வீரர் ஆட்டத்தின் முடிவை அறிவிக்கிறார். அவர் விளையாட்டை முன்பே விட்டுவிட்டால், அதை முடிக்க விளையாட்டைப் பின்பற்ற வேண்டும்.

இந்தச் சிக்கலைத் தீர்க்க, வணிகச் செயல்முறைகளுக்கு எங்கள் DSL ஐப் பயன்படுத்துவேன், இது குறைந்தபட்சம் கொதிகலன்களைக் கொண்டு கோட்லினில் உள்ள தர்க்கத்தை சுருக்கமாக விவரிக்க உங்களை அனுமதிக்கிறது.

app1 பயன்பாட்டில், முதல் வீரரின் வணிகச் செயல்முறை (அவர் விளையாட்டின் தொடக்கக்காரரும் கூட) செயல்படும்:

வகுப்பு ஆரம்ப ஆட்டக்காரர்

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

வணிக தர்க்கத்தை செயல்படுத்துவதற்கு கூடுதலாக, மேலே உள்ள குறியீடு வணிக செயல்முறையின் பொருள் மாதிரியை உருவாக்க முடியும், அதை வரைபடமாக காட்சிப்படுத்தலாம். நாங்கள் இன்னும் காட்சிப்படுத்தலைச் செயல்படுத்தவில்லை, எனவே நாங்கள் சிறிது நேரம் வரைவதற்குச் செலவிட வேண்டியிருந்தது (மேலே உள்ள குறியீட்டைக் கொண்டு வரைபடத்தின் நிலைத்தன்மையை மேம்படுத்துவதற்கு வாயில்களைப் பயன்படுத்துவது தொடர்பான BPMN குறியீட்டை இங்கே சிறிது எளிமைப்படுத்தினேன்):

பிபிஎம் பாணி ஒருங்கிணைப்பு

app2 மற்றொரு வீரரின் வணிக செயல்முறையை உள்ளடக்கும்:

வகுப்பு ரேண்டம் பிளேயர்

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

வரைபடம்:

பிபிஎம் பாணி ஒருங்கிணைப்பு

app3 பயன்பாட்டில், பிளேயரை சற்று வித்தியாசமான நடத்தையுடன் உருவாக்குவோம்: தோராயமாக அடுத்த வீரரைத் தேர்ந்தெடுப்பதற்குப் பதிலாக, அவர் ரவுண்ட்-ராபின் அல்காரிதம் படி செயல்படுவார்:

வகுப்பு 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}")
}

இல்லையெனில், வீரரின் நடத்தை முந்தையதை விட வேறுபடாது, எனவே வரைபடம் மாறாது.

இப்போது அனைத்தையும் இயக்க ஒரு சோதனை தேவை. ஒரு கொதிகலன் மூலம் கட்டுரையை ஒழுங்கீனம் செய்யாமல் இருக்க, சோதனையின் குறியீட்டை மட்டுமே தருகிறேன் (உண்மையில், பிற வணிக செயல்முறைகளின் ஒருங்கிணைப்பை சோதிக்க முன்பு உருவாக்கப்பட்ட சோதனை சூழலைப் பயன்படுத்தினேன்):

டெஸ்ட் கேம்()

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

சோதனையை இயக்கவும், பதிவைப் பார்க்கவும்:

கன்சோல் வெளியீடு

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

இவை அனைத்திலிருந்தும் பல முக்கியமான முடிவுகளை எடுக்கலாம்:

  • தேவையான கருவிகள் இருந்தால், பயன்பாட்டு டெவலப்பர்கள் வணிக தர்க்கத்திலிருந்து விலகாமல் பயன்பாடுகளுக்கு இடையே ஒருங்கிணைப்பு தொடர்புகளை உருவாக்கலாம்;
  • பொறியியல் திறன்கள் தேவைப்படும் ஒரு ஒருங்கிணைப்பு பணியின் சிக்கலானது (சிக்கலானது) கட்டமைப்பின் கட்டமைப்பில் ஆரம்பத்தில் அமைக்கப்பட்டிருந்தால், கட்டமைப்பிற்குள் மறைக்கப்படலாம். பணியின் சிரமத்தை (கடினத்தன்மை) மறைக்க முடியாது, எனவே குறியீட்டில் கடினமான பணிக்கான தீர்வு அதற்கேற்ப இருக்கும்;
  • ஒருங்கிணைப்பு தர்க்கத்தை உருவாக்கும் போது, ​​இறுதியில் நிலைத்தன்மை மற்றும் அனைத்து ஒருங்கிணைப்பு பங்கேற்பாளர்களின் நிலை மாற்றத்தின் நேர்கோட்டுத்தன்மையின் பற்றாக்குறையை கணக்கில் எடுத்துக்கொள்வது அவசியம். வெளிப்புற நிகழ்வுகள் நிகழும் வரிசைக்கு உணர்ச்சியற்றதாக மாற்றுவதற்காக தர்க்கத்தை சிக்கலாக்க இது நம்மைத் தூண்டுகிறது. எங்கள் எடுத்துக்காட்டில், அவர் விளையாட்டிலிருந்து வெளியேறுவதாக அறிவித்த பிறகு, விளையாட்டில் பங்கேற்க வேண்டிய கட்டாயத்தில் உள்ளார்: அவர் வெளியேறுவது பற்றிய தகவல் வந்து அனைத்து பங்கேற்பாளர்களாலும் செயலாக்கப்படும் வரை மற்ற வீரர்கள் பந்தை அவருக்கு அனுப்புவார்கள். இந்த தர்க்கம் விளையாட்டின் விதிகளில் இருந்து பின்பற்றப்படவில்லை மற்றும் தேர்ந்தெடுக்கப்பட்ட கட்டிடக்கலை கட்டமைப்பிற்குள் ஒரு சமரச தீர்வு ஆகும்.

அடுத்து, எங்கள் தீர்வு, சமரசங்கள் மற்றும் பிற புள்ளிகளின் பல்வேறு நுணுக்கங்களைப் பற்றி பேசலாம்.

அனைத்து செய்திகளும் ஒரே வரிசையில்

அனைத்து ஒருங்கிணைந்த பயன்பாடுகளும் ஒரு ஒருங்கிணைப்பு பேருந்தில் வேலை செய்கின்றன, இது வெளிப்புற தரகர், செய்திகளுக்கான ஒரு BPMQueue மற்றும் சமிக்ஞைகளுக்கான ஒரு BPMTopic தலைப்பு (நிகழ்வுகள்) என வழங்கப்படுகிறது. ஒரே வரிசையில் அனைத்து செய்திகளையும் அனுப்புவது ஒரு சமரசம். வணிக தர்க்க மட்டத்தில், கணினி கட்டமைப்பில் மாற்றங்களைச் செய்யாமல் நீங்கள் இப்போது எத்தனை புதிய வகையான செய்திகளை வேண்டுமானாலும் அறிமுகப்படுத்தலாம். இது ஒரு குறிப்பிடத்தக்க எளிமைப்படுத்தல், ஆனால் இது சில அபாயங்களைக் கொண்டுள்ளது, இது எங்கள் வழக்கமான பணிகளின் சூழலில், எங்களுக்கு அவ்வளவு முக்கியத்துவம் வாய்ந்ததாகத் தெரியவில்லை.

பிபிஎம் பாணி ஒருங்கிணைப்பு

இருப்பினும், இங்கே ஒரு நுணுக்கம் உள்ளது: ஒவ்வொரு பயன்பாடும் நுழைவாயிலில் உள்ள வரிசையில் இருந்து "அதன்" செய்திகளை அதன் டொமைனின் பெயரால் வடிகட்டுகிறது. மேலும், சிக்னலின் "நோக்கத்தை" ஒரே பயன்பாட்டிற்கு மட்டுப்படுத்த வேண்டும் என்றால், சிக்னல்களில் டொமைனைக் குறிப்பிடலாம். இது பேருந்தின் அலைவரிசையை அதிகரிக்க வேண்டும், ஆனால் வணிக தர்க்கம் இப்போது டொமைன் பெயர்களுடன் செயல்பட வேண்டும்: செய்திகளை முகவரியிடுவதற்கு கட்டாயம், சிக்னல்களுக்கு விரும்பத்தக்கது.

ஒருங்கிணைப்பு பேருந்தின் நம்பகத்தன்மையை உறுதி செய்தல்

நம்பகத்தன்மை பல விஷயங்களால் ஆனது:

  • தேர்ந்தெடுக்கப்பட்ட செய்தி தரகர் கட்டிடக்கலையின் ஒரு முக்கிய அங்கம் மற்றும் தோல்வியின் ஒரு புள்ளி: அது போதுமான அளவு தவறுகளை பொறுத்துக்கொள்ள வேண்டும். நல்ல ஆதரவுடனும் பெரிய சமூகத்துடனும் நேர-சோதனை செய்யப்பட்ட செயலாக்கங்களை மட்டுமே நீங்கள் பயன்படுத்த வேண்டும்;
  • செய்தி தரகரின் அதிக இருப்பை உறுதி செய்வது அவசியம், அதற்காக அது ஒருங்கிணைந்த பயன்பாடுகளிலிருந்து உடல் ரீதியாக பிரிக்கப்பட வேண்டும் (பயன்படுத்தப்பட்ட வணிக தர்க்கத்துடன் கூடிய பயன்பாடுகளின் அதிக இருப்பு வழங்குவது மிகவும் கடினம் மற்றும் விலை உயர்ந்தது);
  • தரகர் "குறைந்தபட்சம் ஒரு முறை" டெலிவரி உத்தரவாதத்தை வழங்க கடமைப்பட்டுள்ளார். ஒருங்கிணைப்பு பேருந்தின் நம்பகமான செயல்பாட்டிற்கு இது ஒரு கட்டாயத் தேவை. "சரியாக ஒருமுறை" நிலை உத்தரவாதங்கள் தேவையில்லை: வணிக செயல்முறைகள் பொதுவாக செய்திகள் அல்லது நிகழ்வுகளின் தொடர்ச்சியான வருகைக்கு உணர்திறன் இல்லை, மேலும் இது முக்கியமான சிறப்புப் பணிகளில், தொடர்ந்து பயன்படுத்துவதை விட வணிக தர்க்கத்தில் கூடுதல் சரிபார்ப்புகளைச் சேர்ப்பது எளிது. மாறாக "விலையுயர்ந்த" "உத்தரவாதங்கள்;
  • செய்திகள் மற்றும் சிக்னல்களை அனுப்புவது வணிக செயல்முறைகள் மற்றும் டொமைன் தரவுகளின் நிலை மாற்றத்துடன் ஒரு பொதுவான பரிவர்த்தனையில் ஈடுபட வேண்டும். விருப்பமான விருப்பம் வடிவத்தைப் பயன்படுத்துவதாகும் பரிவர்த்தனை அவுட்பாக்ஸ், ஆனால் அதற்கு தரவுத்தளத்தில் கூடுதல் அட்டவணை மற்றும் ரிலே தேவைப்படும். JEE பயன்பாடுகளில், உள்ளூர் JTA மேலாளரைப் பயன்படுத்தி இதை எளிதாக்கலாம், ஆனால் தேர்ந்தெடுக்கப்பட்ட தரகரின் இணைப்பு பயன்முறையில் வேலை செய்ய வேண்டும். XA;
  • உள்வரும் செய்திகள் மற்றும் நிகழ்வுகளின் கையாளுபவர்கள் வணிக செயல்முறையின் நிலையை மாற்றும் பரிவர்த்தனையுடன் செயல்பட வேண்டும்: அத்தகைய பரிவர்த்தனை திரும்பப் பெறப்பட்டால், செய்தியின் ரசீதும் ரத்து செய்யப்பட வேண்டும்;
  • பிழைகள் காரணமாக வழங்க முடியாத செய்திகள் ஒரு தனி கடையில் சேமிக்கப்பட வேண்டும் டி.எல்.க்யூ. (டெட் லெட்டர் வரிசை). இதைச் செய்ய, ஒரு தனி பிளாட்ஃபார்ம் மைக்ரோ சர்வீஸை அதன் சேமிப்பகத்தில் சேமித்து, பண்புக்கூறுகள் (விரைவான குழுவாக்கம் மற்றும் தேடுதலுக்காக) அவற்றை அட்டவணைப்படுத்தி, பார்க்க, இலக்கு முகவரிக்கு மீண்டும் அனுப்புதல் மற்றும் செய்திகளை நீக்குவதற்கு API ஐ வெளிப்படுத்துகிறோம். கணினி நிர்வாகிகள் தங்கள் இணைய இடைமுகம் மூலம் இந்த சேவையுடன் வேலை செய்யலாம்;
  • தரகர் அமைப்புகளில், DLQ இல் செய்திகள் வருவதற்கான வாய்ப்பைக் குறைக்க டெலிவரி மறு முயற்சிகள் மற்றும் டெலிவரிகளுக்கு இடையிலான தாமதங்களின் எண்ணிக்கையை நீங்கள் சரிசெய்ய வேண்டும் (உகந்த அளவுருக்களைக் கணக்கிடுவது கிட்டத்தட்ட சாத்தியமற்றது, ஆனால் நீங்கள் அனுபவபூர்வமாகச் செயல்பட்டு அவற்றைச் சரிசெய்யலாம். செயல்பாடு);
  • DLQ ஸ்டோர் தொடர்ந்து கண்காணிக்கப்பட வேண்டும், மேலும் கண்காணிப்பு அமைப்பு கணினி நிர்வாகிகளுக்குத் தெரிவிக்க வேண்டும், இதனால் அவர்கள் வழங்கப்படாத செய்திகள் தோன்றும் போது விரைவாக பதிலளிக்க முடியும். இது தோல்வி அல்லது வணிக தர்க்கப் பிழையின் "சேத மண்டலத்தை" குறைக்கும்;
  • ஒருங்கிணைப்பு பஸ் தற்காலிகமாக பயன்பாடுகள் இல்லாததால் உணர்ச்சியற்றதாக இருக்க வேண்டும்: தலைப்பு சந்தாக்கள் நீடித்ததாக இருக்க வேண்டும், மேலும் பயன்பாட்டின் டொமைன் பெயர் தனித்துவமாக இருக்க வேண்டும், இதனால் விண்ணப்பம் இல்லாத நேரத்தில் வரிசையில் இருந்து அதன் செய்தியை வேறு யாரோ செயல்படுத்த முயற்சிக்க மாட்டார்கள்.

வணிக தர்க்கத்தின் நூல் பாதுகாப்பை உறுதி செய்தல்

வணிகச் செயல்முறையின் அதே நிகழ்வு ஒரே நேரத்தில் பல செய்திகளையும் நிகழ்வுகளையும் பெறலாம், அதன் செயலாக்கம் இணையாகத் தொடங்கும். அதே நேரத்தில், ஒரு அப்ளிகேஷன் டெவலப்பருக்கு, எல்லாமே எளிமையாகவும், நூல்-பாதுகாப்பாகவும் இருக்க வேண்டும்.

செயல்முறை வணிக தர்க்கம் இந்த வணிக செயல்முறையை தனித்தனியாக பாதிக்கும் ஒவ்வொரு வெளிப்புற நிகழ்வையும் செயலாக்குகிறது. இந்த நிகழ்வுகள் இருக்கலாம்:

  • ஒரு வணிக செயல்முறை நிகழ்வைத் தொடங்குதல்;
  • வணிகச் செயல்பாட்டில் உள்ள செயல்பாடு தொடர்பான பயனர் நடவடிக்கை;
  • ஒரு வணிக செயல்முறை நிகழ்வு சந்தா செலுத்தப்பட்ட ஒரு செய்தி அல்லது சமிக்ஞையின் ரசீது;
  • வணிக செயல்முறை நிகழ்வால் அமைக்கப்பட்ட டைமரின் காலாவதி;
  • API வழியாக கட்டுப்பாட்டு நடவடிக்கை (எ.கா. செயல்முறை நிறுத்தம்).

அத்தகைய ஒவ்வொரு நிகழ்வும் ஒரு வணிக செயல்முறை நிகழ்வின் நிலையை மாற்றலாம்: சில நடவடிக்கைகள் முடிவடையும் மற்றும் மற்றவை தொடங்கலாம், நிலையான பண்புகளின் மதிப்புகள் மாறலாம். எந்தச் செயலையும் மூடுவதால், பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட செயல்பாடுகளைச் செயல்படுத்தலாம். அவர்கள் மற்ற நிகழ்வுகளுக்காக காத்திருப்பதை நிறுத்தலாம் அல்லது கூடுதல் தரவு எதுவும் தேவையில்லை என்றால், அவர்கள் அதே பரிவர்த்தனையை முடிக்கலாம். பரிவர்த்தனையை மூடுவதற்கு முன், வணிக செயல்முறையின் புதிய நிலை தரவுத்தளத்தில் சேமிக்கப்படுகிறது, அங்கு அது அடுத்த வெளிப்புற நிகழ்வுக்காக காத்திருக்கும்.

புதுப்பித்தலுக்கான தேர்வைப் பயன்படுத்தும் போது தொடர்புடைய தரவுத்தளத்தில் சேமிக்கப்பட்ட நிலையான வணிக செயல்முறை தரவு மிகவும் வசதியான செயலாக்க ஒத்திசைவு புள்ளியாகும். ஒரு பரிவர்த்தனை வணிக செயல்முறையின் நிலையை அடிப்படையிலிருந்து மாற்ற முடிந்தால், அதற்கு இணையாக வேறு எந்த பரிவர்த்தனையும் மற்றொரு மாற்றத்திற்கு அதே நிலையைப் பெற முடியாது, மேலும் முதல் பரிவர்த்தனை முடிந்த பிறகு, இரண்டாவது ஏற்கனவே மாற்றப்பட்ட நிலையைப் பெறுவதற்கு உத்தரவாதம்.

DBMS பக்கத்தில் அவநம்பிக்கையான பூட்டுகளைப் பயன்படுத்தி, தேவையான அனைத்து தேவைகளையும் நாங்கள் பூர்த்தி செய்கிறோம் ACID, மற்றும் இயங்கும் நிகழ்வுகளின் எண்ணிக்கையை அதிகரிப்பதன் மூலம் வணிக தர்க்கத்துடன் பயன்பாட்டை அளவிடும் திறனையும் தக்க வைத்துக் கொள்ளுங்கள்.

இருப்பினும், அவநம்பிக்கையான பூட்டுகள் முட்டுக்கட்டைகளால் நம்மை அச்சுறுத்துகின்றன, அதாவது வணிக தர்க்கத்தில் சில மோசமான நிகழ்வுகளில் முட்டுக்கட்டைகள் ஏற்பட்டால், புதுப்பித்தலுக்கான தேர்வு இன்னும் சில நியாயமான காலக்கெடுவிற்கு வரம்பிடப்பட வேண்டும்.

மற்றொரு சிக்கல் வணிக செயல்முறையின் தொடக்கத்தின் ஒத்திசைவு ஆகும். வணிக செயல்முறை நிகழ்வுகள் எதுவும் இல்லை என்றாலும், தரவுத்தளத்திலும் எந்த நிலையும் இல்லை, எனவே விவரிக்கப்பட்ட முறை வேலை செய்யாது. ஒரு குறிப்பிட்ட நோக்கத்தில் வணிகச் செயல்முறை நிகழ்வின் தனித்துவத்தை உறுதிப்படுத்த விரும்பினால், செயல்முறை வகுப்பு மற்றும் தொடர்புடைய நோக்கத்துடன் தொடர்புடைய சில வகையான ஒத்திசைவு பொருள் உங்களுக்குத் தேவைப்படும். இந்தச் சிக்கலைத் தீர்க்க, நாங்கள் வேறு பூட்டுதல் பொறிமுறையைப் பயன்படுத்துகிறோம், இது வெளிப்புறச் சேவையின் மூலம் URI வடிவத்தில் ஒரு விசையால் குறிப்பிடப்பட்ட தன்னிச்சையான ஆதாரத்தை பூட்ட அனுமதிக்கிறது.

எங்கள் எடுத்துக்காட்டுகளில், InitialPlayer வணிகச் செயல்முறை ஒரு அறிவிப்பைக் கொண்டுள்ளது

uniqueConstraint = UniqueConstraints.singleton

எனவே, பதிவில் தொடர்புடைய விசையின் பூட்டை எடுத்து வெளியிடுவது பற்றிய செய்திகள் உள்ளன. பிற வணிக செயல்முறைகளுக்கு இது போன்ற செய்திகள் எதுவும் இல்லை: தனித்துவமான கட்டுப்பாடு அமைக்கப்படவில்லை.

நிலையான நிலையில் வணிக செயல்முறை சிக்கல்கள்

சில நேரங்களில் ஒரு நிலையான நிலை உதவுவது மட்டுமல்லாமல், உண்மையில் வளர்ச்சியைத் தடுக்கிறது.
வணிக தர்க்கம் மற்றும் / அல்லது வணிக செயல்முறை மாதிரியில் நீங்கள் மாற்றங்களைச் செய்ய வேண்டியிருக்கும் போது சிக்கல்கள் தொடங்குகின்றன. வணிக செயல்முறைகளின் பழைய நிலைக்கு இது போன்ற எந்த மாற்றமும் பொருந்தவில்லை. தரவுத்தளத்தில் பல "நேரடி" நிகழ்வுகள் இருந்தால், பொருந்தாத மாற்றங்களைச் செய்வது நிறைய சிக்கல்களை ஏற்படுத்தும், இது jBPM ஐப் பயன்படுத்தும் போது நாம் அடிக்கடி சந்தித்தோம்.

மாற்றத்தின் ஆழத்தைப் பொறுத்து, நீங்கள் இரண்டு வழிகளில் செயல்படலாம்:

  1. ஒரு புதிய வணிக செயல்முறை வகையை உருவாக்கவும், அதனால் பழையவற்றுடன் பொருந்தாத மாற்றங்களைச் செய்யக்கூடாது, மேலும் புதிய நிகழ்வுகளைத் தொடங்கும்போது பழையதற்குப் பதிலாக அதைப் பயன்படுத்தவும். பழைய நிகழ்வுகள் "பழைய வழியில்" தொடர்ந்து செயல்படும்;
  2. வணிக தர்க்கத்தைப் புதுப்பிக்கும்போது வணிக செயல்முறைகளின் நிலையான நிலையை மாற்றவும்.

முதல் வழி எளிமையானது, ஆனால் அதன் வரம்புகள் மற்றும் தீமைகள் உள்ளன, எடுத்துக்காட்டாக:

  • பல வணிக செயல்முறை மாதிரிகளில் வணிக தர்க்கத்தின் நகல், வணிக தர்க்கத்தின் அளவு அதிகரிப்பு;
  • பெரும்பாலும் ஒரு புதிய வணிக தர்க்கத்திற்கு உடனடி மாற்றம் தேவைப்படுகிறது (கிட்டத்தட்ட எப்போதும் ஒருங்கிணைப்பு பணிகளின் அடிப்படையில்);
  • காலாவதியான மாதிரிகளை எந்த நேரத்தில் நீக்குவது என்பது டெவலப்பருக்குத் தெரியாது.

நடைமுறையில், நாங்கள் இரண்டு அணுகுமுறைகளையும் பயன்படுத்துகிறோம், ஆனால் எங்கள் வாழ்க்கையை எளிதாக்குவதற்கு பல முடிவுகளை எடுத்துள்ளோம்:

  • தரவுத்தளத்தில், வணிகச் செயல்பாட்டின் நிலையான நிலை எளிதில் படிக்கக்கூடிய மற்றும் எளிதில் செயலாக்கப்பட்ட வடிவத்தில் சேமிக்கப்படுகிறது: JSON வடிவ சரத்தில். பயன்பாட்டிற்கு உள்ளேயும் வெளியேயும் இடம்பெயர்வுகளைச் செய்ய இது உங்களை அனுமதிக்கிறது. தீவிர நிகழ்வுகளில், நீங்கள் அதை கைப்பிடிகள் மூலம் மாற்றலாம் (குறிப்பாக பிழைத்திருத்தத்தின் போது வளர்ச்சியில் பயனுள்ளதாக இருக்கும்);
  • ஒருங்கிணைப்பு வணிக தர்க்கம் வணிக செயல்முறைகளின் பெயர்களைப் பயன்படுத்துவதில்லை, இதனால் எந்த நேரத்திலும் பங்கேற்கும் செயல்முறைகளில் ஒன்றை புதிய பெயருடன் மாற்றலாம் (எடுத்துக்காட்டாக, "InitialPlayerV2"). செய்திகள் மற்றும் சமிக்ஞைகளின் பெயர்கள் மூலம் பிணைப்பு ஏற்படுகிறது;
  • செயல்முறை மாதிரியில் ஒரு பதிப்பு எண் உள்ளது, இந்த மாதிரியில் இணங்காத மாற்றங்களைச் செய்தால் அதை அதிகரிக்கிறோம், மேலும் இந்த எண் செயல்முறை நிகழ்வின் நிலையுடன் சேமிக்கப்படும்;
  • செயல்பாட்டின் நிலையான நிலை, மாதிரியின் பதிப்பு எண் மாறியிருந்தால், இடம்பெயர்வு செயல்முறை வேலை செய்யக்கூடிய வசதியான பொருள் மாதிரியில் முதலில் அடிப்படையிலிருந்து படிக்கப்படுகிறது;
  • இடம்பெயர்வு செயல்முறை வணிக தர்க்கத்திற்கு அடுத்ததாக வைக்கப்படுகிறது மற்றும் தரவுத்தளத்தில் இருந்து அதை மீட்டெடுக்கும் நேரத்தில் வணிக செயல்முறையின் ஒவ்வொரு நிகழ்வுக்கும் "சோம்பேறி" என்று அழைக்கப்படுகிறது;
  • நீங்கள் அனைத்து செயல்முறை நிகழ்வுகளின் நிலையை விரைவாகவும் ஒத்திசைவாகவும் மாற்ற வேண்டும் என்றால், மிகவும் உன்னதமான தரவுத்தள இடம்பெயர்வு தீர்வுகள் பயன்படுத்தப்படுகின்றன, ஆனால் நீங்கள் JSON உடன் வேலை செய்ய வேண்டும்.

வணிக செயல்முறைகளுக்கு எனக்கு மற்றொரு கட்டமைப்பு தேவையா?

கட்டுரையில் விவரிக்கப்பட்டுள்ள தீர்வுகள், எங்கள் வாழ்க்கையை கணிசமாக எளிதாக்கவும், பயன்பாட்டு மேம்பாட்டு மட்டத்தில் தீர்க்கப்பட்ட சிக்கல்களின் வரம்பை விரிவுபடுத்தவும், வணிக தர்க்கத்தை மைக்ரோ சர்வீஸ்களாக பிரிக்கும் யோசனையை மிகவும் கவர்ச்சிகரமானதாகவும் மாற்ற அனுமதித்தது. இதற்காக, நிறைய வேலைகள் செய்யப்பட்டுள்ளன, வணிக செயல்முறைகளுக்கான மிகவும் "இலகுரக" கட்டமைப்பு உருவாக்கப்பட்டது, அத்துடன் பரந்த அளவிலான பயன்பாட்டு பணிகளின் சூழலில் அடையாளம் காணப்பட்ட சிக்கல்களைத் தீர்ப்பதற்கான சேவை கூறுகள். பொதுவான கூறுகளின் வளர்ச்சியை இலவச உரிமத்தின் கீழ் திறந்த அணுகலுக்குக் கொண்டு வர, இந்த முடிவுகளைப் பகிர்ந்து கொள்ள நாங்கள் விரும்புகிறோம். இதற்கு சில முயற்சியும் நேரமும் தேவைப்படும். அத்தகைய தீர்வுகளுக்கான தேவையைப் புரிந்துகொள்வது எங்களுக்கு கூடுதல் ஊக்கமாக இருக்கும். முன்மொழியப்பட்ட கட்டுரையில், கட்டமைப்பின் திறன்களுக்கு மிகக் குறைந்த கவனம் செலுத்தப்படுகிறது, ஆனால் அவற்றில் சில வழங்கப்பட்ட எடுத்துக்காட்டுகளிலிருந்து தெரியும். ஆயினும்கூட, நாங்கள் எங்கள் கட்டமைப்பை வெளியிட்டால், ஒரு தனி கட்டுரை அதற்கு அர்ப்பணிக்கப்படும். இதற்கிடையில், கேள்விக்கு பதிலளிப்பதன் மூலம் நீங்கள் ஒரு சிறிய பின்னூட்டத்தை இட்டால் நாங்கள் நன்றியுள்ளவர்களாக இருப்போம்:

பதிவு செய்த பயனர்கள் மட்டுமே கணக்கெடுப்பில் பங்கேற்க முடியும். உள்நுழையவும், தயவு செய்து.

வணிக செயல்முறைகளுக்கு எனக்கு மற்றொரு கட்டமைப்பு தேவையா?

  • 18,8%ஆம், நான் நீண்ட காலமாக இப்படி ஒன்றைத் தேடிக்கொண்டிருக்கிறேன்.

  • 12,5%உங்கள் செயலாக்கத்தைப் பற்றி மேலும் அறிந்து கொள்வது சுவாரஸ்யமாக உள்ளது, இது பயனுள்ளதாக இருக்கும்2

  • 6,2%ஏற்கனவே உள்ள கட்டமைப்பில் ஒன்றைப் பயன்படுத்துகிறோம், ஆனால் அதை மாற்றுவது பற்றி யோசித்து வருகிறோம்1

  • 18,8%நாங்கள் ஏற்கனவே உள்ள கட்டமைப்புகளில் ஒன்றைப் பயன்படுத்துகிறோம், எல்லாமே பொருந்துகிறது3

  • 18,8%கட்டமைப்பின்றி சமாளித்தல்3

  • 25,0%சொந்தமாக எழுதுங்கள்4

16 பயனர்கள் வாக்களித்தனர். 7 பயனர்கள் வாக்களிக்கவில்லை.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்