اسان جي ڪمپني ERP-ڪلاس سافٽ ويئر حلن جي ترقي ۾ ماهر آهي، جنهن جو وڏو حصو ٽرانزيڪشنل سسٽم تي قبضو ڪيو ويو آهي وڏي مقدار ۾ ڪاروباري منطق ۽ دستاويز جي وهڪري سان لا EDMS. اسان جي پروڊڪٽس جا موجوده ورجن جاوا اي اي ٽيڪنالاجيز تي ٻڌل آهن، پر اسان پڻ فعال طور تي مائڪرو سروسز سان تجربا ڪري رهيا آهيون. اهڙن حلن جي سڀ کان وڌيڪ مشڪلاتي علائقن مان هڪ آهي ڀرپاسي ڊومينز سان تعلق رکندڙ مختلف سب سسٽم جو انضمام. انضمام جي مسئلن هميشه اسان کي هڪ وڏو سر درد ڏنو آهي، بغير ڪنهن تعميراتي انداز، ٽيڪنالاجي اسٽيڪ ۽ فريم ورڪ جيڪي اسان استعمال ڪندا آهيون، پر تازو ئي اهڙن مسئلن کي حل ڪرڻ ۾ ترقي ڪئي وئي آهي.
آرٽيڪل ۾ آئون توهان جي توجه ڏيان ٿو، مان ان تجربي ۽ تعميراتي تحقيق بابت ڳالهائيندس جيڪو اين پي او ڪرسٽا جي نامزد ٿيل علائقي ۾ آهي. اسان هڪ ايپليڪيشن ڊولپر جي نقطي نظر کان انضمام جي مسئلي جي سادي حل جو هڪ مثال پڻ ڏسنداسين ۽ اهو معلوم ڪنداسين ته هن سادگي جي پويان ڇا لڪيل آهي.
رد ڪرڻ
آرٽيڪل ۾ بيان ڪيل تعميراتي ۽ ٽيڪنيڪل حل مون طرفان تجويز ڪيل آهن ذاتي تجربن جي بنياد تي مخصوص ڪمن جي حوالي سان. اهي حل آفاقي هجڻ جي دعويٰ نٿا ڪن ۽ استعمال جي ٻين حالتن ۾ بهتر نه هجن.
BPM جو ان سان ڇا تعلق آهي؟
هن سوال جو جواب ڏيڻ لاء، اسان کي اسان جي حل جي لاڳو ٿيل مسئلن جي وضاحتن ۾ ٿورو وڌيڪ ڌيان ڏيڻ جي ضرورت آهي. اسان جي عام ٽرانزيڪشن سسٽم ۾ ڪاروباري منطق جو بنيادي حصو صارف انٽرفيس ذريعي ڊيٽابيس ۾ ڊيٽا داخل ڪري رهيو آهي، هن ڊيٽا جي دستياب ۽ خودڪار تصديق، ان کي ڪجهه ڪم فلو ذريعي کڻڻ، ان کي ڪنهن ٻئي سسٽم ۾ شايع ڪرڻ / تجزياتي ڊيٽابيس / آرڪائيو، رپورٽون ٺاهڻ. . اهڙيء طرح، گراهڪن لاء سسٽم جو اهم ڪم انهن جي اندروني ڪاروباري عملن جي خودڪار آهي.
سهولت لاءِ، اسان ڪميونيڪيشن ۾ اصطلاح ”دستاويز“ استعمال ڪندا آهيون جيئن ڊيٽا جي هڪ سيٽ جي ڪجهه تجريد جي طور تي هڪ گڏيل ڪنجي سان گڏيل آهي جنهن سان هڪ خاص ورڪ فلو ”ڳنڍ“ ٿي سگهي ٿو.
پر انضمام جي منطق بابت ڇا؟ سڀ کان پوء، انضمام جو ڪم سسٽم جي فن تعمير جي ذريعي پيدا ڪيو ويو آهي، جيڪو "ڪٽ" حصن ۾ نه آهي ڪسٽمر جي درخواست تي، پر مڪمل طور تي مختلف عنصر جي اثر هيٺ:
Conway جي قانون جي تابع؛
ٻين پراڊڪٽس لاءِ اڳ ۾ ٺاهيل سبسسٽم کي ٻيهر استعمال ڪرڻ جي نتيجي ۾؛
معمار جي صوابديد تي، غير فعال گهرجن جي بنياد تي.
مکيه ڪم فلو جي ڪاروباري منطق کان انضمام جي منطق کي الڳ ڪرڻ لاء هڪ وڏو آزمائش آهي، انهي ڪري ته ڪاروباري منطق کي انضمام جي نموني سان آلوده نه ڪيو وڃي ۽ ايپليڪيشن ڊولپر کي سسٽم جي تعميراتي نظارن جي خاصيتن کي ڳولڻ جي ضرورت کان بچايو وڃي. ھن طريقي سان ڪيترائي فائدا آھن، پر عملي طور تي ان جي غير موثريت ڏيکاري ٿو:
انضمام جي مسئلن کي حل ڪرڻ عام طور تي آسان اختيارن ڏانهن واپس اچي ٿو هم وقت ساز ڪالن جي صورت ۾ مکيه ڪم فلو جي عمل ۾ محدود توسيع پوائنٽن جي ڪري (هم وقت سازي جي انضمام جي نقصانن تي بحث ڪيو ويو آهي)؛
انضمام جا نمونا اڃا تائين بنيادي ڪاروباري منطق ۾ داخل ٿين ٿا جڏهن ٻئي سب سسٽم کان موٽ گهربل هجي؛
ايپليڪيشن ڊولپر انضمام کي نظر انداز ڪري ٿو ۽ آساني سان ان کي ٽوڙي سگھي ٿو ڪم فلو کي تبديل ڪندي؛
صارف جي نقطي نظر کان سسٽم هڪ مڪمل ٿيڻ بند ڪري ٿو، سب سسٽم جي وچ ۾ "سيمس" قابل ذڪر ٿي ويندا آهن، ۽ غير ضروري صارف آپريشن ظاهر ٿيندا آهن، ڊيٽا جي منتقلي جي شروعات هڪ سب سسٽم کان ٻئي ڏانهن.
هڪ ٻيو طريقو اهو آهي ته انضمام جي ڳالهين کي بنيادي ڪاروباري منطق ۽ ڪم جي فلو جو هڪ لازمي حصو سمجهيو وڃي. ايپليڪيشن ڊولپر جي قابليت کي تيز ٿيڻ کان روڪڻ لاءِ، نئين انٽيگريشن رابطي کي ٺاهڻ آسان ۽ آسان هجڻ گهرجي، حل چونڊڻ لاءِ گهٽ ۾ گهٽ اختيارن سان. اهو ڪم ڪرڻ کان وڌيڪ ڏکيو آهي اهو لڳي ٿو: اوزار ڪافي طاقتور هجڻ گهرجي ته صارف کي ان جي استعمال لاء گهربل مختلف قسم جي اختيارن سان مهيا ڪري، هن کي اجازت ڏيڻ جي بغير "پاڻ کي پيرن ۾ گولي." اهڙا ڪيترائي سوال آهن جن جو جواب هڪ انجنيئر کي انضمام جي ڪمن جي حوالي سان لازمي آهي، پر جيڪو هڪ ايپليڪيشن ڊولپر کي پنهنجي روزاني ڪم ۾ نه سوچڻ گهرجي: ٽرانزيڪشن جون حدون، استحڪام، ايٽمي، سيڪيورٽي، اسڪيلنگ، لوڊ ۽ وسيلن جي ورڇ، روٽنگ، مارشلنگ، تقسيم ۽ مٽائڻ جي حوالي سان، وغيره. اهو ضروري آهي ته ايپليڪيشن ڊولپرز کي پيش ڪرڻ لاء ڪافي سادو حل ٽيمپليٽس جن ۾ اهڙن سڀني سوالن جا جواب اڳ ۾ ئي لڪيل آهن. اهي ٽيمپليٽس لازمي طور تي محفوظ هجڻ گهرجن: ڪاروباري منطق گهڻو ڪري تبديل ٿينديون آهن، جيڪي غلطيون متعارف ڪرائڻ جو خطرو وڌائينديون آهن، غلطين جي قيمت تمام گهٽ سطح تي رهڻ گهرجي.
پر BPM کي ان سان ڇا ڪرڻو آهي؟ ڪم جي فلو کي لاڳو ڪرڻ لاء ڪيترائي اختيار آهن ...
درحقيقت، ڪاروباري عملن جو هڪ ٻيو عمل اسان جي حلن ۾ تمام گهڻو مشهور آهي - هڪ رياستي منتقلي ڊراگرام جي بياناتي تعريف ۽ ٽرانزيڪشن لاءِ ڪاروباري منطق سان هينڊلر جي ڪنيڪشن ذريعي. انهي صورت ۾، رياست جيڪو ڪاروبار جي عمل ۾ "دستاويز" جي موجوده پوزيشن کي طئي ڪري ٿو، اهو خود "دستاويز" جي هڪ خاصيت آهي.
اھو اھو آھي جيڪو عمل ھڪڙي منصوبي جي شروعات ۾ ڏسڻ ۾ اچي ٿو
هن عمل درآمد جي مقبوليت جي سبب آهي نسبتا سادگي ۽ سڌر ڪاروباري عمل ٺاهڻ جي رفتار. بهرحال، جيئن سافٽ ويئر سسٽم مسلسل وڌيڪ پيچيده ٿي ويندا آهن، ڪاروباري عمل جو خودڪار حصو وڌندو آهي ۽ وڌيڪ پيچيده ٿي ويندو آهي. ضرورت آهي ته ڊمپوزيشن، پروسيس جي حصن کي ٻيهر استعمال ڪرڻ، انهي سان گڏ برانچنگ جي عملن جي ته جيئن هر شاخ کي متوازي طور تي عمل ڪيو وڃي. اهڙين حالتن ۾، اوزار مشڪل ٿي ويندو آهي، ۽ رياست جي منتقلي ڊراگرام پنهنجي معلوماتي مواد کي وڃائي ڇڏيندو آهي (انضمام جي وچ ۾ لاڳاپا مڪمل طور تي ڊراگرام ۾ ظاهر نه ٿيندا آهن).
اهو اهو آهي جيڪو عمل جي ضرورتن جي وضاحت جي ڪيترن ئي ورهاڱي کان پوء ڏسڻ ۾ اچي ٿو.
هن صورتحال مان نڪرڻ جو طريقو انجڻ جي انضمام هو جي بي پي ايم ڪجھ پراڊڪٽس ۾ سڀ کان وڌيڪ پيچيده ڪاروباري عملن سان. مختصر مدت ۾، هن حل ۾ ڪجهه ڪاميابي هئي: اهو ممڪن ٿيو ته پيچيده ڪاروباري عملن کي لاڳو ڪرڻ، جڏهن ته نوٽيفڪيشن ۾ ڪافي معلوماتي ۽ لاڳاپيل آريگرام برقرار رکندي. بي پي ايم اين 2.
ھڪڙي پيچيده ڪاروباري عمل جو ھڪڙو ننڍڙو حصو
ڊگھي مدت ۾، حل اميدن تي پورو نه ٿيو: بصري اوزار جي ذريعي ڪاروباري عملن کي ٺاهڻ جي اعلي محنت جي شدت قابل قبول پيداوار جي اشارن کي حاصل ڪرڻ جي اجازت نه ڏني، ۽ اوزار پاڻ ڊولپرز جي وچ ۾ سڀ کان وڌيڪ ناپسنديده بڻجي ويو. انجڻ جي اندروني ڍانچي جي باري ۾ به شڪايتون آهن، جنهن جي ڪيترن ئي "پيچ" ۽ "crutches" جي ظهور جو سبب بڻيا.
jBPM استعمال ڪرڻ جو بنيادي مثبت پاسو ڪاروبار عمل جي مثال جي پنهنجي مستقل حالت جي فائدن ۽ نقصانن جي آگاهي هئي. اسان مختلف ايپليڪيشنن جي وچ ۾ پيچيدگي انضمام پروٽوڪول کي لاڳو ڪرڻ لاء پروسيس جي طريقيڪار کي استعمال ڪرڻ جو امڪان پڻ ڏٺو آهي سگنلن ۽ پيغامن ذريعي غير مطابقت واري رابطي کي استعمال ڪندي. مستقل رياست جي موجودگي ان ۾ اهم ڪردار ادا ڪري ٿي.
مٿين بنيادن تي، اسان نتيجو ڪري سگھون ٿا: BPM انداز ۾ عمل جو طريقو اسان کي ڪمن جي وسيع رينج کي حل ڪرڻ جي اجازت ڏئي ٿو وڌندڙ پيچيده ڪاروباري عملن کي خودڪار ڪرڻ لاءِ، انهن عملن ۾ هم آهنگيءَ سان انضمام جي سرگرمين کي ترتيب ڏيڻ ۽ قابليت کي برقرار رکڻ جي قابليت کي برقرار رکڻ لاءِ لاڳو ٿيل عمل کي مناسب نوٽيشن ۾ ڏسڻ ۾.
انضمام جي نموني جي طور تي هم وقت سازي ڪالن جا نقصان
هم وقت سازي انضمام آسان ترين بلاڪنگ ڪال ڏانهن اشارو ڪري ٿو. ھڪڙو سب سسٽم ڪم ڪري ٿو سرور جي پاسي ۽ API کي گهربل طريقي سان بي نقاب ڪري ٿو. ٻيو سب سسٽم ڪلائنٽ سائڊ طور ڪم ڪري ٿو ۽ صحيح وقت تي ڪال ڪري ٿو ۽ نتيجو جو انتظار ڪري ٿو. سسٽم جي فن تعمير تي مدار رکندي، ڪلائنٽ ۽ سرور جا پاسا يا ته ساڳي ايپليڪيشن ۽ پروسيس ۾، يا مختلف ۾ واقع ٿي سگهن ٿا. ٻي صورت ۾، توهان کي ڪجهه RPC لاڳو ڪرڻ جي ضرورت آهي ۽ پيٽرولن جي مارشلنگ ۽ ڪال جو نتيجو مهيا ڪرڻ جي ضرورت آهي.
هن انضمام جي نموني ۾ ڪافي نقصانن جو هڪ وڏو سيٽ آهي، پر ان جي سادگي جي ڪري عملي طور تي استعمال ڪيو ويندو آهي. عمل درآمد جي رفتار موهيندڙ ٿي ۽ مجبور ڪري ٿي ته توهان ان کي بار بار استعمال ڪرڻ جي لاءِ آخري حدن کي دٻائڻ جي صورت ۾، حل کي ٽيڪنيڪل قرض طور رڪارڊ ڪيو. پر اهو پڻ ٿئي ٿو ته اڻڄاتل ڊولپرز ان کي غير شعوري طور تي استعمال ڪن ٿا، صرف منفي نتيجن کي محسوس نه ڪن.
سبسسٽم رابطي ۾ سڀ کان وڌيڪ واضح اضافو کان علاوه، "وڌندڙ" ۽ "وڌيڪ" ٽرانزيڪشن سان پڻ گهٽ واضح مسئلا آهن. درحقيقت، جيڪڏهن ڪاروباري منطق ڪجهه تبديليون آڻيندي، پوء ٽرانزيڪشن کان بچي نه ٿو سگهجي، ۽ ٽرانزيڪشن، موڙ ۾، انهن تبديلين کان متاثر ٿيل ڪجهه ايپليڪيشن وسيلن کي بلاڪ ڪري ٿو. اهو آهي، جيستائين هڪ سب سسٽم ٻئي کان جواب جو انتظار ڪري، اهو ٽرانزيڪشن کي مڪمل ڪرڻ ۽ تالا کي هٽائڻ جي قابل نه هوندو. اهو خاص طور تي مختلف اثرات جي خطري کي وڌائي ٿو:
سسٽم جي ردعمل گم ٿي وئي آهي، صارفين سوالن جي جوابن لاء هڪ ڊگهو وقت انتظار ڪندا آهن؛
سرور عام طور تي صارف جي درخواستن جو جواب ڏيڻ بند ڪري ٿو ھڪڙي گھڻائي واري ٿريڊ پول جي ڪري: ٿريڊز جي اڪثريت ھڪڙي ٽرانزيڪشن تي قبضو ڪيل وسيلن تي بند ٿيل آھن؛
Deadlocks ظاهر ٿيڻ شروع ٿي ويا آهن: انهن جي واقعن جو امڪان گهڻو ڪري ٽرانزيڪشن جي مدت تي منحصر آهي، ڪاروباري منطق جي مقدار ۽ ٽرانزيڪشن ۾ شامل تالا؛
ٽرانزيڪشن جي وقت ختم ٿيڻ واريون غلطيون ظاهر ٿين ٿيون؛
سرور OutOfMemory سان ”ناڪام“ ٿي وڃي ٿو جيڪڏهن ڪم کي پروسيسنگ ۽ ڊيٽا جي وڏي مقدار کي تبديل ڪرڻ جي ضرورت آهي، ۽ هم وقت سازي انضمام جي موجودگي پروسيسنگ کي ”لائيٽ“ ٽرانزيڪشن ۾ ورهائڻ تمام ڏکيو بڻائي ٿي.
تعميراتي نقطي نظر کان، انضمام دوران بلاڪنگ ڪالن جو استعمال انفرادي سب سسٽم جي معيار تي ڪنٽرول جي نقصان جي ڪري ٿي: اهو ناممڪن آهي ته هڪ سب سسٽم جي ٽارگيٽ معيار جي اشارن کي ٻئي سب سسٽم جي معيار جي اشارن کان الڳ ڪرڻ ۾. جيڪڏهن سب سسٽم مختلف ٽيمن پاران ترقي ڪئي وئي آهي، اهو هڪ وڏو مسئلو آهي.
شيون اڃا به وڌيڪ دلچسپ ٿي وڃن ٿيون جيڪڏهن سب سسٽم ضم ٿي رهيا آهن مختلف ايپليڪيشنن ۾ ۽ توهان کي ٻنهي پاسن تي هم وقت سازي تبديليون ڪرڻ جي ضرورت آهي. انهن تبديلين جي ٽرانزيڪشن کي ڪيئن يقيني بڻايو وڃي؟
جيڪڏهن تبديليون الڳ الڳ ٽرانزيڪشن ۾ ڪيون وينديون آهن، ته پوء توهان کي قابل اعتماد استثنا فراهم ڪرڻ جي ضرورت پوندي ۽ معاوضو، ۽ اهو مڪمل طور تي هم وقت سازي انضمام جي بنيادي فائدي کي ختم ڪري ٿو - سادگي.
ورهايل ٽرانزيڪشن پڻ ذهن ۾ اچن ٿا، پر اسان انهن کي اسان جي حل ۾ استعمال نه ڪندا آهيون: اهو اعتماد کي يقيني بڻائڻ ڏکيو آهي.
"ساگا" ٽرانزيڪشن جي مسئلي جي حل جي طور تي
microservices جي وڌندڙ مقبوليت سان، جي طلب ساگا نموني.
اهو نمونو مڪمل طور تي ڊگهي ٽرانزيڪشن جي مٿين مسئلن کي حل ڪري ٿو، ۽ ڪاروباري منطق جي پاسي کان سسٽم جي حالت کي منظم ڪرڻ جي صلاحيتن کي پڻ وڌائي ٿو: هڪ ناڪام ٽرانزيڪشن کان پوء معاوضو شايد سسٽم کي ان جي اصل حالت ڏانهن واپس نه آڻي، پر مهيا ڪري ٿو. هڪ متبادل ڊيٽا پروسيسنگ رستو. اهو توهان کي ڪاميابي سان مڪمل ٿيل ڊيٽا پروسيسنگ مرحلن کي ورجائڻ کان پاسو ڪرڻ جي اجازت ڏئي ٿو جڏهن پروسيس کي ”سٺو“ پڄاڻي تي آڻڻ جي ڪوشش ڪئي وڃي.
دلچسپ ڳالهه اها آهي ته، monolithic سسٽم ۾ اهو نمونو ان وقت به لاڳاپيل هوندو آهي جڏهن اهو ٿلهي سان ملندڙ سب سسٽم جي انضمام تي اچي ٿو ۽ ڊگھي عرصي تائين هلندڙ ٽرانزيڪشن ۽ لاڳاپيل وسيلن جي تالان جي ڪري ناڪاري اثرن جو مشاهدو ڪيو وڃي ٿو.
BPM انداز ۾ اسان جي ڪاروباري عملن جي حوالي سان، ”ساگاس“ کي لاڳو ڪرڻ بلڪل آسان ثابت ٿيو آهي: ”ساگا“ جا انفرادي قدم ڪاروباري عمل جي اندر سرگرمين جي طور تي بيان ڪري سگھجن ٿا، ۽ ڪاروباري عمل جي مسلسل حالت پڻ. "ساگا" جي اندروني حالت کي طئي ڪري ٿو. اهو آهي، اسان کي ڪنهن به اضافي ڪوآرڊينيشن ميڪانيزم جي ضرورت ناهي. توهان کي صرف هڪ پيغام بروکر جي ضرورت آهي جيڪا "گهٽ ۾ گهٽ هڪ ڀيرو" ٽرانسپورٽ جي ضمانت جي حمايت ڪري ٿي.
پر اهو حل پڻ پنهنجي "قيمت" آهي:
ڪاروباري منطق وڌيڪ پيچيده ٿي ويندي آهي: معاوضي تي ڪم ڪرڻ جي ضرورت آهي؛
اهو ضروري آهي ته مڪمل استحڪام کي ڇڏي ڏيو، جيڪو خاص طور تي monolithic سسٽم لاء حساس ٿي سگهي ٿو؛
فن تعمير ٿورو وڌيڪ پيچيده ٿي ويندو آهي، ۽ هڪ پيغام بروکر جي اضافي ضرورت ظاهر ٿئي ٿي؛
اضافي نگراني ۽ انتظامي اوزارن جي ضرورت پوندي (جيتوڻيڪ عام طور تي اھو سٺو آھي: سسٽم سروس جو معيار وڌندو).
monolithic نظام لاء، "Sag" استعمال ڪرڻ جو جواز ايترو واضح نه آهي. مائڪرو سروسز ۽ ٻين SOA لاءِ، جتي گهڻو ڪري اڳ ۾ ئي هڪ بروکر موجود آهي، ۽ پروجيڪٽ جي شروعات ۾ مڪمل استحڪام قربان ڪيو ويندو آهي، هن نموني کي استعمال ڪرڻ جا فائدا وڏي پئماني تي نقصانن کان وڌي سگهن ٿا، خاص طور تي جيڪڏهن ڪاروباري منطق تي هڪ آسان API آهي. سطح
مائڪرو سروسز ۾ ڪاروباري منطق کي گڏ ڪرڻ
جڏهن اسان microservices سان تجربا ڪرڻ شروع ڪيو، هڪ معقول سوال پيدا ٿيو: ڊومين جي ڪاروباري منطق کي ڪٿي رکڻو آهي خدمت جي سلسلي ۾ جيڪو ڊومين ڊيٽا جي تسلسل کي يقيني بڻائي ٿو؟
جڏهن مختلف BPMSs جي فن تعمير کي ڏسندي، اهو مناسب لڳي سگھي ٿو ته ڪاروباري منطق کي استقامت کان الڳ ڪرڻ: پليٽ فارم ۽ ڊومين-آزاد مائڪرو سروسز جو هڪ پرت ٺاهيو جيڪو هڪ ماحول ۽ ڪنٽينر ٺاهي ٿو ڊومين ڪاروباري منطق تي عمل ڪرڻ لاءِ، ۽ ڊومين ڊيٽا جي تسلسل کي ترتيب ڏيو جيئن تمام سادو ۽ هلڪو وزن مائڪرو سروسز جو هڪ الڳ پرت. هن معاملي ۾ ڪاروباري عمل مسلسل پرت جي خدمتن جي آرڪيسٽريشن کي انجام ڏئي ٿو.
هن طريقي سان هڪ تمام وڏو فائدو آهي: توهان پليٽ فارم جي ڪارڪردگي کي وڌائي سگهو ٿا جيترو توهان چاهيو، ۽ صرف پليٽ فارم مائڪرو سروسز جي لاڳاپيل پرت هن مان "ٿلهي" ٿي ويندي. ڪنهن به ڊومين مان ڪاروباري عمل فوري طور تي پليٽ فارم جي نئين ڪارڪردگي کي استعمال ڪرڻ جي قابل هوندا آهن جيئن ئي اپڊيٽ ڪيو ويندو آهي.
هڪ وڌيڪ تفصيلي اڀياس هن طريقي جي اهم نقصانات کي ظاهر ڪيو:
هڪ پليٽ فارم سروس جيڪا ڪيترن ئي ڊومينز جي ڪاروباري منطق کي هڪ ئي وقت تي عمل ڪري ٿي ناڪامي جي هڪ واحد نقطي جي طور تي وڏو خطرو کڻندي آهي. ڪاروباري منطق ۾ بار بار تبديليون غلطين جو خطرو وڌائين ٿيون جيڪي سسٽم جي وڏين ناڪامين جي ڪري.
ڪارڪردگي جا مسئلا: ڪاروباري منطق ان جي ڊيٽا سان گڏ هڪ تنگ ۽ سست انٽرفيس ذريعي ڪم ڪري ٿو:
هڪ ڊومين سروس اڪثر ڪري وڌيڪ ڊيٽا فراهم ڪندي جنهن جي عمل لاءِ ڪاروباري منطق لاءِ گهربل آهي ڇاڪاڻ ته خدمت جي خارجي API جي سطح تي درخواستن کي پيرا ميٽرائيز ڪرڻ لاءِ ناکافي صلاحيتون؛
ڪاروباري منطق جا ڪيترائي آزاد ٽڪرا بار بار ساڳئي ڊيٽا کي پروسيسنگ لاءِ ٻيهر گذارش ڪري سگھن ٿا (اهو مسئلو سيشن اجزاء شامل ڪري گھٽائي سگهجي ٿو جيڪي ڊيٽا کي ڪيش ڪن ٿا، پر اهو آرڪيٽيڪچر کي وڌيڪ پيچيده ڪري ٿو ۽ ڊيٽا جي مطابقت ۽ ڪيش جي غلطيءَ جا مسئلا پيدا ڪري ٿو)؛
واپار جا مسئلا:
مسلسل رياست سان ڪاروباري عمل، جيڪو هڪ پليٽ فارم سروس طرفان محفوظ ڪيو ويو آهي، ڊومين ڊيٽا سان متضاد آهن، ۽ هن مسئلي کي حل ڪرڻ لاء ڪي آسان طريقا نه آهن؛
ڊومين ڊيٽا کي ٽرانزيڪشن کان ٻاهر بلاڪ ڪرڻ: جيڪڏهن ڊومين ڪاروبار منطق کي تبديل ڪرڻ جي ضرورت آهي پهرين موجوده ڊيٽا جي صحيحيت جي جانچ ڪرڻ کان پوء، اهو ضروري آهي ته پروسيس ٿيل ڊيٽا ۾ مقابلي واري تبديلي جي امڪان کي خارج ڪرڻ لاء. خارجي ڊيٽا کي بلاڪ ڪرڻ مسئلو حل ڪرڻ ۾ مدد ڪري سگهي ٿو، پر اهو حل اضافي خطرن کي کڻندو آهي ۽ سسٽم جي مجموعي اعتبار کي گھٽائي ٿو؛
تازه ڪاري ڪرڻ وقت اضافي مشڪلاتون: ڪجهه حالتن ۾، مسلسل خدمت ۽ ڪاروباري منطق کي هم وقت سازي يا سخت ترتيب ۾ اپڊيٽ ڪرڻ جي ضرورت آهي.
بالآخر، اسان کي واپس وڃڻو پوندو بنياديات: ڊومين ڊيٽا ۽ ڊومين ڪاروباري منطق کي هڪ مائڪرو سروس ۾ شامل ڪريو. اهو طريقو هڪ microservice جي تصور کي سسٽم جي هڪ لازمي جزو جي طور تي آسان بڻائي ٿو ۽ مٿين مسئلن کي جنم نٿو ڏئي. اهو پڻ مفت ۾ نه ڏنو ويو آهي:
ڪاروباري منطق سان رابطي لاءِ API معيار جي ضرورت آهي (خاص طور تي، صارف جي سرگرمين کي ڪاروباري عملن جي حصي طور مهيا ڪرڻ) ۽ API پليٽ فارم سروسز؛ API تبديلين تي وڌيڪ ڌيان ڏيڻ جي ضرورت آهي، اڳتي ۽ پوئتي مطابقت؛
اهو ضروري آهي ته اضافي رن ٽائم لائبريريون شامل ڪيون وڃن ته جيئن ڪاروباري منطق جي ڪارڪردگي کي يقيني بڻائي سگهجي ته جيئن هر هڪ مائڪرو سروس جي حصي جي طور تي، ۽ اهو اهڙن لائبريرين لاء نئين گهرجن کي جنم ڏئي ٿو: روشني ۽ گهٽ ۾ گهٽ منتقلي انحصار؛
ڪاروباري منطق ڊولپرز کي لائبريري ورزن جي نگراني ڪرڻ جي ضرورت آهي: جيڪڏهن هڪ microservice ڊگهي عرصي تائين حتمي نه ڪئي وئي آهي، ته پوء گهڻو ڪري ان ۾ لائبريرين جو هڪ پراڻو نسخو هوندو. اهو هڪ نئين خصوصيت شامل ڪرڻ ۾ اڻڄاتل رڪاوٽ ٿي سگهي ٿو ۽ ٿي سگهي ٿو اهڙي خدمت جي پراڻي ڪاروباري منطق کي لڏڻ جي ضرورت هجي لائبريرين جي نئين نسخن ڏانهن جيڪڏهن نسخن جي وچ ۾ غير مطابقت رکندڙ تبديليون هجن.
پليٽ فارم سروسز جو هڪ پرت پڻ اهڙي فن تعمير ۾ موجود آهي، پر هي پرت هاڻي ڊومين ڪاروباري منطق کي هلائڻ لاءِ ڪنٽينر نه ٺاهيندي آهي، پر صرف ان جو ماحول، معاون ”پليٽفارم“ افعال مهيا ڪندي آهي. اهڙي پرت جي ضرورت آهي نه رڳو ڊومين مائڪرو سروسز جي هلڪي وزن واري طبيعت کي برقرار رکڻ لاءِ، پر انتظاميا کي مرڪزي ڪرڻ لاءِ.
مثال طور، ڪاروباري عملن ۾ صارف سرگرميون ڪم پيدا ڪن ٿيون. جڏهن ته، ڪمن سان ڪم ڪرڻ وقت، صارف کي عام فهرست ۾ سڀني ڊومينز مان ڪم ڏسڻ گهرجي، جنهن جو مطلب آهي ته اتي هڪ لاڳاپيل پليٽ فارم ٽاسڪ رجسٽريشن سروس هجڻ گهرجي، ڊومين ڪاروباري منطق کان صاف. اهڙي حوالي سان ڪاروباري منطق جي انڪشاف کي برقرار رکڻ ڪافي مشڪل آهي، ۽ اهو هن فن تعمير جو هڪ ٻيو سمجھوتو آهي.
ايپليڪيشن ڊولپر جي اکين ذريعي ڪاروباري عملن جو انضمام
جيئن مٿي ذڪر ڪيو ويو آهي، هڪ ايپليڪيشن ڊولپر کي لازمي طور تي ڪيترن ئي ايپليڪيشنن جي رابطي کي لاڳو ڪرڻ جي ٽيڪنيڪل ۽ انجنيئرنگ خاصيتن کان هٽايو وڃي ته جيئن هڪ سٺي ترقي جي پيداوار تي شمار ڪري سگهي.
اچو ته هڪ بلڪه ڏکيو انضمام جي مسئلي کي حل ڪرڻ جي ڪوشش ڪريون، خاص طور تي آرٽيڪل لاء ٺاهيل. هي هڪ "راند" جو ڪم هوندو جنهن ۾ ٽي ايپليڪيشنون شامل آهن، جتي انهن مان هر هڪ مخصوص ڊومين جو نالو بيان ڪري ٿو: "app1"، "app2"، "app3".
هر ايپليڪيشن جي اندر، ڪاروباري عمل شروع ڪيا ويا آهن جيڪي شروع ڪن ٿا "بال کي راند" انٽيگريشن بس ذريعي. "بال" نالي سان پيغام هڪ بال طور ڪم ڪندو.
راندين جا ضابطا:
پهريون پليئر شروعات ڪندڙ آهي. هو ٻين رانديگرن کي راند ۾ دعوت ڏئي ٿو، راند کي شروع ڪري ٿو ۽ ڪنهن به وقت ختم ڪري سگهي ٿو؛
بال حاصل ڪرڻ کان پوء، پليئر هڪ ٻيو حصو وٺندڙ رانديگر کي چونڊيندو آهي ۽ هن کي بال پاس ڪري ٿو. ٽرانسميشن جو ڪل تعداد شمار ڪيو ويو آهي؛
هر پليئر وٽ ”توانائي“ هوندي آهي جيڪا ان رانديگر طرفان بال جي هر پاس سان گهٽجي ويندي آهي. جڏهن توانائي ختم ٿئي ٿي، پليئر راند کي ڇڏي، پنهنجي استعيفي جو اعلان ڪندي؛
جيڪڏهن پليئر اڪيلو ڇڏي ويو آهي، هو فوري طور تي پنهنجي روانگي جو اعلان ڪري ٿو؛
جڏهن سڀئي رانديگر ختم ٿي ويا آهن، پهريون رانديگر راند ختم ٿيڻ جو اعلان ڪري ٿو. جيڪڏهن هو راند کي جلدي ڇڏي ٿو، هو ان کي مڪمل ڪرڻ لاء راند جي پيروي ڪرڻ لاء رهي ٿو.
هن مسئلي کي حل ڪرڻ لاء، مان اسان جي ڊي ايس ايل کي ڪاروباري عملن لاء استعمال ڪندس، جيڪو اسان کي اجازت ڏئي ٿو ڪوٽلن ۾ منطق کي بيان ڪرڻ لاء، گهٽ ۾ گهٽ بوائلر پليٽ سان.
پهرين پليئر جو ڪاروباري عمل (اڪا راند جو شروعات ڪندڙ) ايپ 1 ايپليڪيشن ۾ ڪم ڪندو:
ڪلاس شروعاتي پليئر
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}")
}
ڪاروباري منطق تي عمل ڪرڻ کان علاوه، مٿي ڏنل ڪوڊ ڪاروباري عمل جو هڪ اعتراض ماڊل پيدا ڪري سگهي ٿو، جنهن کي ڊاگرام جي صورت ۾ ڏسي سگهجي ٿو. اسان اڃان تائين visualizer تي عمل نه ڪيو آهي، ان ڪري اسان کي ان کي ڊرائنگ ڪرڻ ۾ ٿورو وقت گذارڻو پيو (هتي مون BPMN نوٽشن کي ٿورو آسان ڪيو آهي گيٽس جي استعمال جي حوالي سان ڏنل ڪوڊ سان ڊاگرام جي تسلسل کي بهتر ڪرڻ لاءِ):
app2 ۾ شامل ٿيندو ٻئي پليئر جي ڪاروباري عمل:
ڪلاس 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}")
}
خاڪو:
ايپ 3 ايپليڪيشن ۾ اسان هڪ رانديگر کي ٿورڙي مختلف رويي سان ٺاهينداسين: بي ترتيب طور تي ايندڙ رانديگر کي چونڊڻ جي بدران، هو گول رابن الگورتھم مطابق عمل ڪندو:
ڪلاس 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;
}
ضروري اوزارن سان، ايپليڪيشن ڊولپرز ٺاهي سگھن ٿا ايپليڪيشنن جي وچ ۾ انٽيگريشن لاڳاپا بغير ڪاروباري منطق جي مداخلت جي؛
انضمام جي ڪم جي پيچيدگي جيڪا انجنيئرنگ جي صلاحيتن جي ضرورت هوندي آهي، فريم ورڪ جي اندر لڪائي سگهجي ٿي جيڪڏهن اهو شروعاتي طور تي فريم ورڪ جي فن تعمير ۾ شامل آهي. مسئلي جي ڏکيائي کي لڪائي نه ٿو سگهجي، تنهنڪري ڪوڊ ۾ هڪ مشڪل مسئلي جو حل ان وانگر نظر ايندو؛
جڏهن انضمام جي منطق کي ترقي ڪندي، اهو ضروري آهي ته اڪائونٽ ۾ حتمي استحڪام ۽ سڀني انضمام شرڪت ڪندڙن جي حالت ۾ تبديلين جي لڪيرائيزيشن جي کوٽ کي. اهو اسان کي مجبور ڪري ٿو ته منطق کي پيچيده ڪرڻ لاءِ ان کي ترتيب سان غير حساس بڻائڻ لاءِ جنهن ۾ ٻاهرين واقعا ٿين ٿا. اسان جي مثال ۾، رانديگر کي راند ۾ حصو وٺڻ تي مجبور ڪيو ويندو آهي جڏهن هو راند مان نڪرڻ جو اعلان ڪري ٿو: ٻيا رانديگر ان کي بال پاس ڪندا رهندا جيستائين سندس نڪرڻ جي معلومات پهچي وڃي ۽ سڀني شرڪت ڪندڙن طرفان عمل ڪيو وڃي. هي منطق راند جي ضابطن جي پيروي نٿو ڪري ۽ چونڊيل فن تعمير جي فريم ورڪ ۾ هڪ سمجھوتي حل آهي.
اڳيون، اسان اسان جي حل جي مختلف پيچيدگين، سمجھوتن ۽ ٻين نقطن بابت ڳالهائينداسين.
سڀئي پيغام هڪ قطار ۾ آهن
سڀئي مربوط ايپليڪيشنون هڪ انٽيگريشن بس سان ڪم ڪن ٿيون، جيڪو هڪ خارجي بروکر جي صورت ۾ پيش ڪيو ويو آهي، پيغامن لاءِ هڪ BPMQueue ۽ سگنلز (واقعات) لاءِ هڪ BPMTopic موضوع. سڀني پيغامن کي هڪ قطار ذريعي رکڻ خود هڪ سمجھوتو آهي. ڪاروباري منطق جي سطح تي، توھان ھاڻي متعارف ڪرائي سگھو ٿا گھڻا نوان پيغام جا قسم جيڪي توھان چاھيو بغير سسٽم جي جوڙجڪ ۾ تبديليون ڪرڻ جي. اها هڪ اهم سادگي آهي، پر ان ۾ ڪجهه خطرا آهن، جيڪي اسان جي عام ڪمن جي حوالي سان اسان لاءِ ايترا اهم نه ٿا لڳي.
بهرحال، هتي هڪ ذيلي ذخيري آهي: هر ايپليڪيشن پنهنجي ڊومين جي نالي سان، داخلا تي قطار مان "پنهنجي" پيغامن کي فلٽر ڪري ٿو. ڊومين پڻ سگنلن ۾ بيان ڪري سگھجي ٿو جيڪڏھن توھان کي محدود ڪرڻ جي ضرورت آھي ”منظر جي دائري“ کي سگنل جي ھڪڙي ايپليڪيشن تائين. انهي کي بس ذريعي وڌائڻ گهرجي، پر ڪاروباري منطق هاڻي ڊومين نالن سان هلائڻ گهرجي: پيغامن کي خطاب ڪرڻ لاء - لازمي، سگنلن لاء - گهربل.
انٽيگريشن بس جي اعتبار کي يقيني بڻائڻ
Reliability ڪيترن ئي نقطن تي مشتمل آهي:
منتخب ٿيل پيغام بروکر فن تعمير جو هڪ نازڪ حصو ۽ ناڪامي جو هڪ واحد نقطو آهي: اهو ڪافي طور تي غلطي برداشت ڪرڻ گهرجي. توهان کي صرف وقت جي آزمائشي عملن کي استعمال ڪرڻ گهرجي، سٺي مدد ۽ وڏي ڪميونٽي سان؛
اهو ضروري آهي ته پيغام بروکر جي اعلي دستيابي کي يقيني بڻائي، جنهن لاء ان کي جسماني طور تي الڳ ٿيل ايپليڪيشنن کان الڳ ڪيو وڃي (اپلائيڊ ڪاروباري منطق سان ايپليڪيشنن جي اعلي دستيابي کي يقيني بڻائڻ تمام گهڻو ڏکيو ۽ قيمتي آهي)؛
بروکر "گهٽ ۾ گهٽ هڪ ڀيرو" پهچائڻ جي ضمانت فراهم ڪرڻ جو پابند آهي. انضمام بس جي قابل اعتماد آپريشن لاء هڪ لازمي گهربل آهي. "بلڪل هڪ ڀيرو" سطح جي ضمانت جي ڪا ضرورت ناهي: ڪاروباري عمل، ضابطي جي طور تي، پيغامن يا واقعن جي بار بار اچڻ لاءِ حساس نه هوندا آهن، ۽ خاص ڪمن ۾ جتي اهو ضروري آهي، ڪاروبار ۾ اضافي چيڪ شامل ڪرڻ آسان آهي. منطق مسلسل استعمال ڪرڻ جي ڀيٽ ۾ ڪافي "مهانگي" " ضمانتون؛
پيغام ۽ سگنل موڪلڻ لازمي طور تي ڪاروباري عملن ۽ ڊومين ڊيٽا جي حالت ۾ تبديلين سان گڏ مجموعي ٽرانزيڪشن ۾ شامل ٿيڻ گهرجي. ترجيحي اختيار ھڪڙو نمونو استعمال ڪرڻ آھي ٽرانزيڪشنل آئوٽ باڪس، پر ان کي ڊيٽابيس ۾ اضافي ٽيبل ۽ ريپٽر جي ضرورت پوندي. JEE ايپليڪيشنن ۾، هن کي مقامي JTA مينيجر استعمال ڪندي آسان بڻائي سگهجي ٿو، پر چونڊيل بروکر سان ڪنيڪشن ڪم ڪرڻ جي قابل هوندو. XA;
ايندڙ پيغامن ۽ واقعن کي سنڀاليندڙن کي پڻ هڪ ٽرانزيڪشن سان ڪم ڪرڻ گهرجي جيڪو ڪاروباري عمل جي حالت کي تبديل ڪري ٿو: جيڪڏهن اهڙي ٽرانزيڪشن کي واپس ڪيو وڃي، پوء پيغام جي وصولي کي منسوخ ڪيو وڃي.
نياپا جيڪي نقصن جي ڪري ڊليور نه ٿي سگھيا آھن تن کي الڳ اسٽوريج ۾ رکڻ گھرجي ڊي ايل ق (ميل خط جي قطار). هن مقصد لاءِ، اسان هڪ الڳ پليٽ فارم microservice ٺاهيو آهي جيڪو اهڙن پيغامن کي پنهنجي اسٽوريج ۾ محفوظ ڪري ٿو، انهن کي خاصيتن جي حساب سان ترتيب ڏئي ٿو (جلدي گروپ بندي ۽ ڳولا لاءِ)، ۽ هڪ API کي ظاهر ڪري ٿو ڏسڻ لاءِ، منزل جي پتي تي ٻيهر موڪلڻ، ۽ پيغامن کي حذف ڪرڻ. سسٽم منتظم پنهنجي ويب انٽرفيس ذريعي هن خدمت سان ڪم ڪري سگهن ٿا؛
بروکر سيٽنگن ۾، توهان کي پهچائڻ جي ڪوششن جي تعداد کي ترتيب ڏيڻ جي ضرورت آهي ۽ ترسيل جي وچ ۾ دير جي وچ ۾ پيغامن جي DLQ ۾ اچڻ جي امڪان کي گھٽائڻ لاء (اهو سڀ کان بهتر پيٽرولر کي ڳڻڻ تقريبا ناممڪن آهي، پر توهان تجرباتي طور تي عمل ڪري سگهو ٿا ۽ آپريشن دوران انهن کي ترتيب ڏئي سگهو ٿا. ؛
DLQ اسٽور کي مسلسل مانيٽر ڪيو وڃي، ۽ مانيٽرنگ سسٽم کي لازمي طور تي سسٽم ايڊمنسٽريٽرن کي خبردار ڪرڻ گهرجي ته جيئن جڏهن اڻپورا پيغام اچي وڃن، اهي جلدي ممڪن طور تي جواب ڏئي سگهن. اهو گھٽائي ڇڏيندو "متاثر ٿيل علائقو" جي ناڪامي يا ڪاروباري منطق جي غلطي؛
انضمام بس ايپليڪيشنن جي عارضي غير موجودگيءَ لاءِ حساس نه هجڻ گهرجي: هڪ موضوع جي رڪنيت پائيدار هجڻ گهرجي، ۽ ايپليڪيشن جو ڊومين نالو منفرد هجڻ گهرجي، انهي ڪري جڏهن ايپليڪيشن غير حاضر آهي، ڪو ٻيو ماڻهو ان جي پيغامن تي عمل ڪرڻ جي ڪوشش نه ڪندو. قطار.
ڪاروباري منطق جي سلسلي جي حفاظت کي يقيني بڻائڻ
ڪاروباري عمل جو ساڳيو مثال هڪ ئي وقت ۾ ڪيترائي پيغام ۽ واقعا حاصل ڪري سگھن ٿا، جن جي پروسيسنگ متوازي شروع ٿيندي. ساڳئي وقت، هڪ ايپليڪيشن ڊولپر لاء، هر شيء سادو ۽ موضوع کان محفوظ هجڻ گهرجي.
عمل جي ڪاروباري منطق هر خارجي واقعي تي عمل ڪري ٿي جيڪا انفرادي طور تي ڪاروباري عمل کي متاثر ڪري ٿي. اهڙا واقعا ٿي سگهن ٿا:
ڪاروباري عمل جو مثال شروع ڪرڻ؛
ڪاروباري عمل جي اندر سرگرمي سان لاڳاپيل صارف عمل؛
هڪ پيغام يا سگنل جي وصولي جنهن ۾ ڪاروباري عمل جو مثال سبسڪرائب ڪيو ويو آهي؛
ڪاروباري عمل جي مثال سان ٽائمر مقرر ڪرڻ؛
API ذريعي عمل کي ڪنٽرول ڪريو (مثال طور، عمل ۾ مداخلت).
هر اهڙو واقعو ڪاروباري عمل جي حالت کي تبديل ڪري سگهي ٿو مثال طور: ڪجهه سرگرميون ختم ٿي سگهن ٿيون ۽ ٻيون شروع ٿي سگهن ٿيون، ۽ مسلسل ملڪيت جا قدر تبديل ٿي سگهن ٿا. ڪنهن به سرگرمي کي بند ڪرڻ جي نتيجي ۾ ٿي سگهي ٿو هڪ يا وڌيڪ هيٺين سرگرمين کي چالو ڪرڻ. اهي، موڙ ۾، ٻين واقعن جي انتظار ۾ روڪي سگهن ٿا، يا، جيڪڏهن انهن کي ڪنهن به اضافي ڊيٽا جي ضرورت ناهي، ساڳئي ٽرانزيڪشن ۾ مڪمل ڪري سگهن ٿا. ٽرانزيڪشن کي بند ڪرڻ کان اڳ، ڪاروباري عمل جي نئين حالت ڊيٽابيس ۾ محفوظ ڪئي وئي آهي، جتي اهو ايندڙ خارجي واقعي جو انتظار ڪندو.
مسلسل ڪاروباري پروسيسنگ ڊيٽا هڪ تعلقي ڊيٽابيس ۾ ذخيرو ٿيل آهي پروسيسنگ کي هم وقت سازي ڪرڻ لاءِ هڪ تمام آسان نقطو آهي جيڪڏهن توهان استعمال ڪريو SELECT FOR UPDATE. جيڪڏهن هڪ ٽرانزيڪشن ان کي تبديل ڪرڻ لاءِ بنياد کان ڪاروباري عمل جي حالت حاصل ڪرڻ ۾ ڪامياب ٿي وئي، ته پوءِ متوازي طور تي ٻيو ڪو به ٽرانزيڪشن ٻي تبديلي لاءِ ساڳي حالت حاصل ڪرڻ جي قابل نه هوندو، ۽ پهرين ٽرانزيڪشن جي مڪمل ٿيڻ کان پوءِ، ٻيو آهي. اڳ ۾ ئي تبديل ٿيل حالت حاصل ڪرڻ جي ضمانت.
ڊي بي ايم ايس پاسي تي مايوسي لاڪ استعمال ڪندي، اسان سڀني ضروري گهرجن کي پورو ڪريون ٿا امل، ۽ پڻ ايپليڪيشن کي ماپڻ جي صلاحيت برقرار رکون ٿا ڪاروباري منطق سان هلندڙ مثالن جو تعداد وڌائيندي.
تنهن هوندي، مايوسي لاڪ اسان کي ڊيڊ لاڪ سان خطرو ڪري ٿو، جنهن جو مطلب آهي ته SELECT FOR UPDATE اڃا تائين محدود هجڻ گهرجي ڪجهه مناسب وقت ختم ٿيڻ جي صورت ۾ جيڪڏهن ڊيڊ لاڪ ڪاروبار منطق ۾ ڪجهه سخت ڪيسن تي واقع ٿين.
ٻيو مسئلو هڪ ڪاروباري عمل جي شروعات جي هم وقت سازي آهي. جڏهن ته ڪاروباري عمل جو ڪو مثال نه آهي، ڊيٽابيس ۾ ڪا به رياست ناهي، تنهنڪري بيان ڪيل طريقو ڪم نه ڪندو. جيڪڏهن توهان کي هڪ مخصوص دائري ۾ ڪاروباري عمل جي مثال جي انفراديت کي يقيني بڻائڻ جي ضرورت آهي، ته پوء توهان کي پروسيس ڪلاس ۽ لاڳاپيل دائري سان لاڳاپيل ڪجهه قسم جي هم وقت سازي اعتراض جي ضرورت پوندي. ھن مسئلي کي حل ڪرڻ لاءِ، اسان ھڪ مختلف لاڪنگ ميکانيزم استعمال ڪريون ٿا جيڪو اسان کي اجازت ڏئي ٿو ھڪ لاڪ کڻڻ لاءِ ھڪ غير ارادي وسيلن تي جيڪو بيان ڪيل ڪيئي طرفان URI فارميٽ ۾ ھڪ خارجي خدمت ذريعي.
اسان جي مثالن ۾، InitialPlayer ڪاروباري عمل ۾ هڪ اعلان شامل آهي
uniqueConstraint = UniqueConstraints.singleton
تنهن ڪري، لاگ ان ۾ لاڳاپيل ڪي جي تالا کڻڻ ۽ ڇڏڻ بابت پيغام شامل آهن. ٻين ڪاروباري عملن لاءِ اهڙا نياپا نه آهن: uniqueConstraint مقرر نه آهي.
مسلسل رياست سان ڪاروباري عملن جا مسئلا
ڪڏهن ڪڏهن هڪ مستقل رياست هجڻ نه رڳو مدد ڪري ٿي، پر حقيقت ۾ ترقي ۾ رڪاوٽ پڻ.
مسئلا تڏهن شروع ٿين ٿا جڏهن ڪاروباري منطق ۽/يا ڪاروباري عمل جي ماڊل ۾ تبديليون ڪرڻ گهرجن. هر اهڙي تبديلي ڪاروباري عمل جي پراڻي حالت سان مطابقت ناهي. جيڪڏهن ڊيٽابيس ۾ ڪيترائي زنده مثالون آهن، ته پوءِ غير مطابقت واريون تبديليون ڪرڻ تمام گهڻيون مشڪلاتون پيدا ڪري سگهن ٿيون، جن جو اسان اڪثر سامنا ڪندا آهيون جڏهن jBPM استعمال ڪندا آهيون.
تبديلين جي کوٽائي تي مدار رکندي، توھان ٻن طريقن سان ڪم ڪري سگھو ٿا:
نئين ڪاروباري عمل جو قسم ٺاهيو ته جيئن پراڻي ۾ غير مطابقت رکندڙ تبديليون نه ڪيون وڃن، ۽ نوان مثال شروع ڪرڻ وقت پراڻي بدران ان کي استعمال ڪريو. پراڻيون ڪاپيون ”اڳي وانگر“ ڪم ڪنديون رهنديون.
ڪاروباري منطق کي اپڊيٽ ڪرڻ دوران ڪاروباري عملن جي مستقل حالت کي منتقل ڪريو.
پهريون طريقو آسان آهي، پر ان جون حدون ۽ نقصان آهن، مثال طور:
ڪيترن ئي ڪاروباري عمل جي ماڊل ۾ ڪاروباري منطق جي نقل، ڪاروباري منطق جي مقدار کي وڌائڻ؛
اڪثر ڪري نئين ڪاروباري منطق ڏانهن فوري منتقلي جي ضرورت هوندي آهي (انضمام جي ڪمن جي لحاظ کان - تقريبن هميشه)؛
ڊولپر کي خبر ناهي ته ڪهڙي نقطي تي پراڻي ماڊلز کي ختم ڪري سگهجي ٿو.
عملي طور تي اسان ٻنهي طريقن کي استعمال ڪندا آهيون، پر اسان جي زندگين کي آسان بڻائڻ لاء ڪيترائي فيصلا ڪيا آهن:
ڊيٽابيس ۾، ڪاروباري عمل جي مسلسل حالت هڪ آساني سان پڙهڻ جي قابل ۽ آساني سان پروسيس ٿيل فارم ۾ ذخيرو ٿيل آهي: هڪ JSON فارميٽ اسٽرنگ ۾. هي لڏپلاڻ کي ايپليڪيشن جي اندر ۽ ٻاهران ٻنهي کي انجام ڏيڻ جي اجازت ڏئي ٿو. آخري حل جي طور تي، توهان ان کي دستي طور تي درست ڪري سگهو ٿا (خاص طور تي ڊيبگنگ دوران ترقي ۾ مفيد)؛
انضمام ڪاروباري منطق ڪاروباري عملن جا نالا استعمال نه ڪندو آهي، انهي ڪري ته ڪنهن به وقت ممڪن آهي ته ڪنهن به وقت ۾ حصو وٺندڙ عملن مان هڪ تي عمل درآمد کي نئين نالي سان تبديل ڪيو وڃي (مثال طور، "InitialPlayerV2"). پابند پيغام ۽ سگنل جي نالن ذريعي ٿئي ٿي؛
پروسيس ماڊل وٽ هڪ نسخو نمبر آهي، جنهن کي اسين وڌايون ٿا جيڪڏهن اسان هن ماڊل ۾ غير مطابقت رکندڙ تبديليون ڪيون، ۽ اهو نمبر پروسيس مثال جي حالت سان گڏ محفوظ ڪيو وڃي.
پروسيس جي مسلسل حالت کي ڊيٽابيس مان پهريون ڀيرو هڪ آسان اعتراض ماڊل ۾ پڙهيو ويندو آهي، جيڪو لڏپلاڻ وارو طريقو ڪم ڪري سگهي ٿو جيڪڏهن ماڊل ورزن نمبر تبديل ٿي ويو آهي؛
لڏپلاڻ وارو عمل ڪاروباري منطق جي اڳيان رکيل آهي ۽ "سست" سڏيو ويندو آهي ڪاروباري عمل جي هر مثال لاءِ ڊيٽابيس مان بحالي جي وقت؛
جيڪڏهن توهان سڀني عملن جي حالت کي جلدي ۽ هم وقت سازي سان منتقل ڪرڻ جي ضرورت آهي، وڌيڪ کلاسک ڊيٽابيس لڏپلاڻ حل استعمال ڪيا ويندا آهن، پر توهان کي JSON سان ڪم ڪرڻو پوندو.
ڇا توهان کي ڪاروباري عملن لاءِ ٻئي فريم ورڪ جي ضرورت آهي؟
مضمون ۾ بيان ڪيل حل اسان کي اسان جي زندگي کي خاص طور تي آسان ڪرڻ جي اجازت ڏني، ايپليڪيشن ڊولپمينٽ جي سطح تي حل ٿيل مسئلن جي حد کي وڌايو، ۽ ڪاروباري منطق کي مائڪرو سروسز ۾ الڳ ڪرڻ جي خيال کي وڌيڪ پرڪشش بڻايو. هن کي حاصل ڪرڻ لاء، تمام گهڻو ڪم ڪيو ويو، ڪاروباري عملن لاء هڪ تمام "هلڪو وزن" فريم ورڪ ٺاهي وئي، انهي سان گڏ خدمت جي اجزاء جي سڃاڻپ مسئلن کي حل ڪرڻ لاء ايپليڪيشن مسئلن جي وسيع رينج جي حوالي سان. اسان کي انهن نتيجن کي حصيداري ڪرڻ جي خواهش آهي ۽ عام اجزاء جي ترقي کي مفت لائسنس تحت کليل رسائي فراهم ڪرڻ آهي. اهو ڪجهه ڪوشش ۽ وقت جي ضرورت پوندي. اهڙن حلن جي طلب کي سمجهڻ اسان لاءِ هڪ اضافي حوصلا افزائي ٿي سگهي ٿي. تجويز ڪيل مضمون ۾، تمام ٿورو ڌيان پاڻ فريم ورڪ جي صلاحيتن کي ادا ڪيو ويو آهي، پر انهن مان ڪجهه پيش ڪيل مثالن مان نظر اچن ٿا. جيڪڏهن اسان پنهنجو فريم ورڪ شايع ڪريون ٿا، هڪ الڳ مضمون ان لاءِ وقف ڪيو ويندو. ساڳئي وقت ۾، اسان شڪرگذار ٿينداسين جيڪڏهن توهان سوال جو جواب ڏيندي ٿورو موٽ ڏيو:
صرف رجسٽرڊ استعمال ڪندڙ سروي ۾ حصو وٺي سگهن ٿا. سائن ان ڪريو، توهان جي مهرباني.
ڇا توهان کي ڪاروباري عملن لاءِ ٻئي فريم ورڪ جي ضرورت آهي؟