शुभ दोपहर, हबलूसर!
हमारे पास विभिन्न सेवाओं और मौजूदा प्रणालियों को नियंत्रित प्रक्रियाओं में जोड़ने का काम है। गति की आवश्यकता नहीं है ब्रह्मांडीय (यानी, स्टॉक कोट्स के आधार पर प्रतिक्रिया बनाने के लिए नहीं), लेकिन बहुत सारी प्रक्रियाएं और घटक (सिस्टम) हैं जिनका उपयोग करने की आवश्यकता है, वे भी लूमिंग हैं। मैं पी 2 पी बाइंडिंग नहीं करना चाहता। मैं कुछ सुंदर और प्रबंधनीय चाहता हूं।
बाजार की समीक्षा करने के बाद, अमेज़न सरल वर्कफ़्लो के आधार पर एक प्रतिकृति बनाने का निर्णय लिया गया, क्योंकि हम इसे सीधे उपयोग नहीं कर सकते। फ्रेमवर्क के गुण जो हमारे अनुरूप हैं:
- कम शुरुआत दहलीज (एक अच्छा प्रोग्रामर आज महंगा है)। यहां कम दहलीज प्रोग्रामिंग की शुरुआत के संदर्भ में अधिक है क्योंकि सब कुछ उच्च स्तर पर किया जाता है - लगभग इंटरफेस के साथ बातचीत के स्तर पर। लेकिन अतुल्यकालिक रूप से प्रक्रिया को पर्याप्त रूप से नियंत्रित करने के लिए, एक को अनुभव का निर्माण करना चाहिए
- कार्य मापदंडों और निष्पादन परिणामों को सहेजते समय, हम एक विश्लेषण और प्रक्रिया कार्य निष्पादकों के प्रतिगमन परीक्षण के लिए एक आधार प्राप्त करते हैं
- कुछ स्थानों में समन्वयक में प्रक्रिया नियंत्रण तर्क की एकाग्रता। यह पहली नज़र में स्पष्ट नहीं हो सकता है, लेकिन एक संभावित विकल्प की तुलना में यह सबसे बड़ा लाभ है, जब प्रत्येक अभिनेता का अपना तर्क है - जिसे अन्य घटकों को अगला (ट्रांसफर कंट्रोल) कहा जाएगा। अक्सर सिस्टम जटिलता और घटकों के पुन: उपयोग में असमर्थता की ओर जाता है
यह न्यूनतम है जिसे मैं पसंद करूंगा, लेकिन जैसा कि अभ्यास से पता चलता है, अधिक प्लस हैं। इस कार्य को "टास्क" के नाम पर
टास्कुरेटा नाम दिया गया - एक कार्य, और फिनिश में एक गोफर, जो मायने नहीं रखता है, लेकिन दिखाई नहीं देता है। खुला स्रोत
GitHub पर उपलब्ध
है । सर्वर के बीच एक आम मेमोरी स्पेस और रनटाइम बनाने के लिए प्रोजेक्ट का क्रियान्वयन किया गया था, अमेज़ॅन से आरईएस सेवाओं और दोस्तों के तेजी से और सुविधाजनक कार्यान्वयन के लिए ड्रापवॉयर, जो पहले थे और खुद को विकसित करने के लिए एक उत्कृष्ट उत्पाद हमें प्रेरित कर रहे थे। यह प्रलेखन के साथ कठिन है, लेकिन हम इसे जल्द ही ठीक कर देंगे।
आइए सिद्धांत से आगे बढ़ते हैं कि अब वास्तविक उदाहरण क्या है।
मान लें कि हमें एक एप्लिकेशन विकसित करने की आवश्यकता है जो उपयोगकर्ता को एक स्ट्रिंग संदेश भेजता है। इनपुट में हमें यूजर आईडी और कैरेक्टर सेट मिलता है। उसकी प्रोफ़ाइल से (आईडी द्वारा) हमें वरीयता डेटा मिलता है - ईमेल या फोन नंबर से संदेश प्राप्त करने के लिए। प्रोफाइल पर फोन नंबर और ईमेल भी उपलब्ध है। अगला हम आवश्यक परिवहन के साथ संदेश भेजते हैं। यदि भेजने में विफल रहा है (गलत पते या संख्या के कारण), तो भविष्य में रिट्रीट को रोकने के लिए इसे प्रोफ़ाइल में नोट किया जाना चाहिए।
इसे एक गैर-कार्यात्मक आवश्यकता में जोड़ें जो संदेश भेजने वाली सेवाएं पहले से मौजूद हैं, अन्य सबनेट पर हैं और उनका पुन: उपयोग करने की आवश्यकता है।
पुनश्च: वर्णित उदाहरण का सभी स्रोत कोड GitHub
taskurotta \ taskurotta-getstarted पर भी उपलब्ध है
Taskurotta आपको सिस्टम घटकों (अभिनेताओं) को लागू करने की अनुमति देता है जो डेवलपर के लिए सामान्य तरीके से एक-दूसरे के साथ बातचीत करते हैं - एक-दूसरे के तरीकों को कॉल करके, लेकिन एक अतुल्यकालिक तरीके से। अभिनेताओं को दो प्रकारों में विभाजित किया जाता है - कलाकार और समन्वयक। कलाकारों को उन्हें सौंपे गए कार्यों को स्पष्ट रूप से पूरा करना चाहिए। वे सबसे स्वतंत्र मॉड्यूल हैं, और तदनुसार - सबसे पुन: प्रयोज्य। कलाकार बाहरी दुनिया (किसी भी इनपुट / आउटपुट स्ट्रीम) के साथ बातचीत कर सकते हैं, इस तरह से कार्य कर सकते हैं और जब तक आवश्यक हो। दूसरी ओर, समन्वयक बाहरी दुनिया से संबंधित कार्य नहीं करते हैं। उन्हें जल्दी से जल्दी काम करना चाहिए और डेटाबेस, नेटवर्क और अन्य संभावित अस्थिर घटकों के साथ सीधे बातचीत पर ठोकर नहीं खाना चाहिए। कलाकारों के लिए कार्य निर्धारित करना, उनके कार्यों का समन्वय करना और इस तरह प्रक्रिया का कार्यान्वयन (विवरण) सुनिश्चित करना उनका कर्तव्य है। समन्वयक पुन: प्रयोज्य उपप्रकारों के प्रतिमान को लागू करके अन्य समन्वयकों के लिए कार्य निर्धारित कर सकते हैं।
समन्वयक का कार्य वर्तमान में ज्ञात कार्यों को वितरित करना है। यानी यह परिणाम के इंतजार में अवरुद्ध नहीं होना चाहिए। उसे ज्ञात कार्यों के बीच निर्भरता का निर्माण करना चाहिए और, यदि आवश्यक हो, तो आगे के कार्यों को निर्धारित करने के लिए अतुल्यकालिक बिंदुओं का निर्माण करें।
हमारी प्रक्रिया के लिए, समन्वयक को निम्नलिखित कार्य करना चाहिए:
- उपयोगकर्ता प्रोफ़ाइल का अनुरोध करें
- प्रोफ़ाइल के लिए प्रतीक्षा करें
- उपयोगकर्ता को संदेश भेजें
- प्रेषण के परिणाम की प्रतीक्षा करें
हम राज्य मशीन, कई कलाकारों द्वारा एक संदेश को बदलने के तरीके, और अन्य सामान्य, लेकिन बोनी विधियों का उपयोग करके क्रियाओं के इस क्रम को एन्कोड नहीं करेंगे। हम इसे प्रॉमिस इकाई और हमारी प्रणाली का उपयोग करके बस और खूबसूरती से करेंगे, जो समन्वयक के कार्यों की निगरानी करता है।
Promise<Profile> profilePromise = userProfileService.get(userId); Promise<Boolean> sendResultPromise = decider.sendToTransport(profilePromise, message);
उदाहरण से पता चलता है कि सेवाओं को कॉल करने के परिणामस्वरूप, हमें एक वास्तविक वस्तु नहीं मिलती है, लेकिन एक निश्चित वादा - कार्य के परिणाम के लिए एक लिंक। हम इस वादे को अन्य सेवाओं (यानी कार्यों) के तर्क के रूप में पारित कर सकते हैं। अन्य सेवाओं के कॉल सिस्टम द्वारा इंटरसेप्ट किए जाएंगे (यानी, एक वास्तविक सिंक्रोनस कॉल नहीं होगा) और उनके बीच एक संबंध बनाया गया है। कार्य सेवाओं द्वारा तब तक निष्पादित नहीं किए जाएंगे जब तक कि उनके सभी प्रकार के वादे तैयार नहीं हो जाते, अर्थात। जब तक सभी आवश्यक प्रारंभिक कार्य पूरे नहीं हो जाते।
इस प्रकार, समन्वयक और हमारी प्रणाली द्वारा संयुक्त रूप से प्रक्रिया नियंत्रण किया जाता है। समन्वयक कार्यों के बीच निर्भरता बनाता है, और सिस्टम अन्य चीजों के बीच, प्रारंभिक कार्यों के पूरा होने की प्रतीक्षा करने का कार्य और उन पर निर्भर कार्यों के बाद के लॉन्च का कार्य करता है।
आइए अब हम बताते हैं कि आगे की क्रियाओं के निर्धारण के लिए अतुल्यकालिक बिंदु क्या हैं।
हमें यह सुनिश्चित करने की आवश्यकता है कि अधिसूचना भेजना सफल था और यदि नहीं, तो हमें उपयोगकर्ता को सूचनाएं भेजने से रोकना होगा।
इस मामले में, अधिसूचना भेजने और आगे की कार्रवाई से पहले, भेजने के परिणाम का विश्लेषण करना आवश्यक है। यानी परिणाम, ब्लॉक या नहीं के आधार पर कार्य को पूरा करने, विश्लेषण करने और। ऐसी समस्या को हल करने के लिए, समन्वयक के पास खुद के लिए एक कार्य बनाने का अवसर है - अर्थात। आगे के कार्यों को परिभाषित करने के लिए एक बिंदु जिसके लिए आवश्यक वादा हस्तांतरित किया जाना चाहिए। नीचे यह कैसा दिखता है।
public void start(String userId, String message) { Promise<Profile> profilePromise = userProfileService.get(userId); Promise<Boolean> sendResultPromise = decider.sendToTransport(profilePromise, message); decider.blockOnFail(userId, sendResultPromise); } @Asynchronous public void blockOnFail(String userId, Promise<Boolean> sendResultPromise) { logger.info(".blockOnFail(userId = [{}], sendResultPromise = [{}])", userId, sendResultPromise); if (!sendResultPromise.get()) { userProfileService.blockNotification(userId); } }
प्रारंभ () विधि प्रक्रिया की शुरुआत है। आगे तीन कार्यों का कथन है। प्रोफ़ाइल प्राप्त करने वाला पहला, दूसरा और तीसरा, समन्वयक परिणाम के बाद के विश्लेषण (sendToTransport और blockOnFail विधियों को कॉल करके) के लिए खुद को निर्धारित करता है। इस प्रकार, समन्वयक ऐसा है मानो पहले कार्य के समाधान की प्रतीक्षा कर रहा है, लेकिन अवरुद्ध किए बिना। एक बार समस्या हल हो जाने के बाद, टास्सुरेट्टा सिस्टम SendToTransport समन्वयक विधि को कॉल करता है, इसके लिए तैयार किए गए वादे ऑब्जेक्ट को पास करता है, जिससे प्राप्त () विधि का उपयोग करके वास्तविक डेटा प्राप्त किया जा सकता है। SendToTransport टास्क पूरा होने के बाद, ब्लॉकऑनफैल टास्क लॉन्च किया जाता है, जहां हम यूजरप्रोफाइल सर्विस को यूजर को मैसेज को ब्लॉक करने के लिए सेट करते हैं, अगर कोई नोटिफिकेशन भेजते समय कोई एरर आई।
आगे की कार्रवाई निर्धारित करने के लिए बिंदुओं का उपयोग करते हुए, विभिन्न प्रक्रिया व्यवहारों को लागू किया जा सकता है:
- विभिन्न शाखाओं पर समानांतरकरण
- प्रॉमिस फॉरवर्डिंग और @ नोवाइट एनोटेशन का उपयोग करके एक बिंदु पर आगे की स्वतंत्र प्रक्रिया थ्रेड्स को मर्ज करें
- अतुल्यकालिक पुनरावृत्ति
- इसी तरह के कार्यों के निष्पादन को समानांतर करना, उदाहरण के लिए, सभी फाइलों के डिजिटल हस्ताक्षर की जांच करना और एक निर्णय बिंदु पर निष्पादन के परिणामों की प्रतीक्षा करना
- आदि
पुनश्च: ब्लॉकऑनफेल कार्य को डिकोडर ऑब्जेक्ट के माध्यम से कहा जाता है। यह एक कृत्रिम वस्तु है जो कॉल को स्वीकार करती है लेकिन वास्तव में ब्लॉकऑनफेल विधि को कॉल नहीं करती है। हमें कार्य सेट करने की आवश्यकता है, और इसे समकालिक रूप से कॉल नहीं करना चाहिए।
चूंकि, परिदृश्य के अनुसार, हमारे पास पहले से ही ईमेल और एसएमएस भेजने के लिए ठेकेदार हैं, हम केवल प्रोफ़ाइल के साथ काम करने के लिए एक ठेकेदार बना सकते हैं। इस ठेकेदार के दो कार्य हैं:
- उपयोगकर्ता आईडी द्वारा प्रोफाइल लौटाएं
- किसी विशिष्ट उपयोगकर्ता के लिए संदेश भेजने की असंभवता के बारे में प्रोफ़ाइल में एक प्रोफ़ाइल बनाएं
हम इसका इंटरफ़ेस घोषित करके शुरू करते हैं। समन्वयक इस इंटरफेस के साथ काम करेगा। इसके बाद, कॉम्पैक्टनेस, टिप्पणियों और कोड के अन्य गैर-आवश्यक भागों के लिए छोड़ दिया जाता है।
@Worker public interface UserProfileService { public Profile get(String userId); public void blockNotification(String userId); }
एनोटेशन
@Worker
इस इंटरफ़ेस को ठेकेदार के रूप में परिभाषित करता है। एक एनोटेशन में वैकल्पिक विशेषताएँ होती हैं जो इसके नाम और संस्करण (अनुबंध के) को परिभाषित करती हैं। डिफ़ॉल्ट रूप से, नाम इंटरफ़ेस का पूरा नाम है, और संस्करण "1.0" है। विभिन्न संस्करणों के निष्पादन एक साथ बिना किसी टकराव के विभिन्न प्रक्रियाओं के लिए काम कर सकते हैं।
आइए इंटरफ़ेस के कार्यान्वयन के लिए आगे बढ़ें।
public class UserProfileServiceImpl implements UserProfileService { private static final Logger logger = LoggerFactory.getLogger(UserProfileServiceImpl.class); @Override public Profile get(String userId) { return ProfileUtil.createRandomProfile(userId); } @Override public void blockNotification(String userId) { logger.info(".blockNotification(userId = [{}]", userId); } }
यहां हमने प्रोफ़ाइल प्रबंधक (ProfileUtil) के आरंभ को छोड़ दिया। यह एक डेटाबेस, LDAP या अन्य रजिस्ट्री के साथ काम कर सकता है। यह उदाहरण हमें दिखाता है कि ठेकेदार कार्यों (कॉल) को प्राप्त करता है और उन्हें वास्तविक मॉड्यूल को दर्शाता है।
यह ठेकेदार के निर्माण को पूरा करता है।
हमारे सामने निर्धारित कार्य को हल करने के लिए, समन्वयक को एक उपयोगकर्ता प्रोफ़ाइल के लिए एक लिंक स्थानांतरित करना होगा जो अभी तक प्राप्त नहीं हुआ है (वादा वस्तु) आगे के कार्यों का निर्धारण करने के बिंदु पर। वहां वह परिवहन का चयन करेगा या कुछ भी नहीं भेजेगा यदि इस उपयोगकर्ता के लिए संदेश भेजना पहले से ही अवरुद्ध है।
हालाँकि, निष्पादक का इंटरफ़ेस, जैसे निष्पादक स्वयं, प्राप्त करता है और परिणाम को समान रूप से देता है, और इसलिए घोषणा में निष्पादन वस्तु के रूप में निष्पादन के परिणाम नहीं होते हैं, लेकिन एक स्वच्छ डेटा ऑब्जेक्ट देता है। यह सही है। ठेकेदार को यह जानने की आवश्यकता नहीं है कि इसका उपयोग कैसे किया जाए। उदाहरण के लिए, प्रोफ़ाइल प्राप्त करने के लिए हमारे ठेकेदार का उपयोग किया जा सकता है यदि उपयोगकर्ता पहचानकर्ता पहले से ही ज्ञात है, या यदि वह ज्ञात नहीं है और आपको किसी अन्य कार्य के लिए एक लिंक स्थानांतरित करने की आवश्यकता है जो कहीं से यह पहचानकर्ता प्राप्त करेगा। इस प्रकार, हम ठेकेदार के साथ बातचीत के इंटरफ़ेस पर आते हैं। यह इंटरफ़ेस उनकी आवश्यकताओं के लिए समन्वयक द्वारा निर्धारित किया जाता है। यानी इसे समन्वयक के पैकेज (परियोजना) में परिभाषित किया गया है। प्रोफ़ाइल के साथ काम करने के लिए ठेकेदार के साथ बातचीत का इंटरफ़ेस जोड़ें:
@WorkerClient(worker = UserProfileService.class) public interface UserProfileServiceClient { public Promise<Profile> get(String userId); public void blockNotification(String userId); }
हम
@WorkerClient
एनोटेशन के साथ चिह्नित इंटरफ़ेस देखते हैं। एनोटेशन पैरामीटर ठेकेदार के वास्तविक इंटरफ़ेस के वर्ग को संदर्भित करता है। इस तरह, मौजूदा इंटरफ़ेस और किसी विशेष समन्वयक के लिए आवश्यक इंटरफ़ेस के बीच एक लिंक स्थापित किया जाता है। हम इस इंटरफ़ेस को "ठेकेदार का ग्राहक इंटरफ़ेस" कहेंगे। इस क्लाइंट इंटरफ़ेस में समन्वयक के लिए आवश्यक सभी विधियाँ होनी चाहिए (आप अप्रयुक्त घोषित नहीं कर सकते हैं) और तर्कों के समान हस्ताक्षर के साथ। कोई भी तर्क प्रकार का हो सकता है वादा यदि आप एक तर्क के रूप में पारित करना चाहते हैं जो एक कार्य का परिणाम है जो अभी तक पूरा नहीं हुआ है।
अब चलो सबसे दिलचस्प भाग पर चलते हैं - एक समन्वयक बना रहे हैं। शुरू करने के लिए, समन्वयक इंटरफ़ेस नीचे प्रस्तुत किया गया है, जिसके उपयोग से टास्कुरोटा ग्राहक उन प्रक्रियाओं को शुरू करेंगे जिनकी उन्हें ज़रूरत है।
@Decider public interface NotificationDecider { @Execute public void start(String userId, String message); }
इस इंटरफ़ेस को
@Decider
- अर्थात के रूप में परिभाषित किया गया है एक समन्वयक के रूप में। इस एनोटेशन में
@Worker
एनोटेशन - नाम और संस्करण के समान गुण हैं। डिफ़ॉल्ट रूप से, इंटरफ़ेस का पूरा नाम नाम के रूप में लिया जाता है, और "1.0" संस्करण के रूप में।
प्रारंभ विधि को
@Execute
के रूप में चिह्नित किया
@Execute
। इसका मतलब है कि इस विधि के माध्यम से आप प्रक्रिया शुरू कर सकते हैं।
अब हम समन्वयक के कार्यान्वयन के लिए आगे बढ़ते हैं
public class NotificationDeciderImpl implements NotificationDecider { private static final Logger logger = LoggerFactory.getLogger(NotificationDeciderImpl.class); private UserProfileServiceClient userProfileService; private MailServiceClient mailService; private SMSServiceClient smsService; private NotificationDeciderImpl decider; @Override public void start(String userId, String message) { logger.info(".start(userId = [{}], message = [{}])", userId, message); Promise<Profile> profilePromise = userProfileService.get(userId); Promise<Boolean> sendResultPromise = decider.sendToTransport(profilePromise, message); decider.blockOnFail(userId, sendResultPromise); } @Asynchronous public Promise<Boolean> sendToTransport(Promise<Profile> profilePromise, String message) { logger.info(".sendToTransport(profilePromise = [{}], message = [{}])", profilePromise, message); Profile profile = profilePromise.get(); switch (profile.getDeliveryType()) { case SMS: { return smsService.send(profile.getPhone(), message); } case EMAIL: { return mailService.send(profile.getEmail(), message); } } return Promise.asPromise(Boolean.TRUE); } @Asynchronous public void blockOnFail(String userId, Promise<Boolean> sendResultPromise) { logger.info(".blockOnFail(userId = [{}], sendResultPromise = [{}])", userId, sendResultPromise); if (!sendResultPromise.get()) { userProfileService.blockNotification(userId); } } }
इस कोड में, हमने निजी वस्तुओं के आरंभ को छोड़ दिया। पूर्ण और काम कर रहे उदाहरण कोड को
टास्कॉर्टा-गेटस्टार्ट प्रोजेक्ट में पाया जा सकता है। यहां हम सिर्फ यह ध्यान देते हैं कि निजी क्षेत्रों के मूल्यों को समन्वयक के लिए प्रॉक्सी वस्तुओं के एक विशेष कारखाने के माध्यम से प्राप्त किया जाता है।
कार्यान्वयन उदाहरण में, समन्वयक द्वारा अपूर्ण कार्यों के पूरा होने के परिणामों के लिए दो प्रतीक्षा बिंदु हैं। यह SendToTransport और blockOnFail मेथड है। इन विधियों को केवल तभी कहा जाएगा जब उनके सभी प्रकार के वादे तैयार हों,
यानी इसी कार्य को पूरा किया जाता है।
MailServiceClient और SMSServiceClient प्रकार की फ़ील्ड ऑब्जेक्ट भी संबंधित ठेकेदारों के लिए क्लाइंट इंटरफ़ेस हैं। आप टास्कुरेटा-गेटस्टार्टेड प्रोजेक्ट में उनके आरंभ को भी देख सकते हैं।
फिलहाल, हम सभी ने ठेकेदार और समन्वयक को लागू किया है। हम सीधे एक्टर्स (यानी, एक्जिक्यूटर्स और कोऑर्डिनेटर) के लॉन्च के लिए आगे बढ़ते हैं।
कार्य अनुप्रयोग सर्वरों के अंदर और एक अलग जावा अनुप्रयोग के रूप में किए जा सकते हैं (यह उदाहरण टास्क्यूरेटा बूटस्ट्रैप मॉड्यूल से अलग अनुप्रयोग के एक संस्करण का उपयोग करता है)। एक अलग आवेदन क्या करता है:
- Taskurotta सर्वर पर पंजीकृत
- कार्यों को करने के लिए एन थ्रेड्स का एक पूल शुरू करता है
- Taskurotta सर्वर से कार्य प्राप्त करता है
- उनका निष्पादन शुरू करता है
- परिणाम के लिए Taskurotta सर्वर आगे
एक अलग जावा एप्लिकेशन चलाने के लिए, बूटस्ट्रैप पैकेज का उपयोग किया जाता है, और अधिक विशेष रूप से, ru.taskurotta.bootstrap.Main वर्ग। यह एक तर्क के रूप में YAML प्रारूप में कॉन्फ़िगरेशन फ़ाइल के स्थान को पारित करने की आवश्यकता है।
इसे कैसे शुरू करने की कोशिश करें? बहुत सरल है। नीचे स्रोत कोड से सर्वर, अभिनेताओं और उनके लॉन्च की चरण-दर-चरण विधानसभा है। सावधान रहें, यदि आपके पास लिनक्स नहीं है, तो मामूली बदलाव आवश्यक हैं।
मान लीजिए कि आपके पास पहले से ही है:
सर्वर Taskurotta इकट्ठा
git clone https://github.com/taskurotta/taskurotta.git cd taskurotta/
विधानसभा चलाएं। गति बढ़ाने के लिए, परीक्षणों को अक्षम करें।
mvn clean install -DskipTests
अब दो नोड्स का क्लस्टर चलाएं (हम डेमो उद्देश्यों के लिए एक मशीन का उपयोग करते हैं और इसलिए लॉन्च विकल्पों में अलग-अलग पोर्ट)। एक वास्तविक वातावरण में, आप एक ही कॉन्फ़िगरेशन के साथ आवश्यक संख्या में मशीनें चला सकते हैं।
पहला क्लस्टर नोड लॉन्च करें:
java -Xmx64m -Ddw.http.port=8081 -Ddw.http.adminPort=9081 -Ddw.logging.file.currentLogFilename="assemble/target/server1.log" -jar assemble/target/assemble-0.4.0-SNAPSHOT.jar server assemble/src/main/resources/hz.yml
हम दूसरा नोड शुरू करते हैं (हम जानबूझकर स्मृति को एक प्रारंभिक चरण में इसकी संभावित लीक की पहचान करने के लिए सीमित करते हैं। इस उदाहरण के कॉन्फ़िगरेशन में, किसी भी डेटाबेस का उपयोग नहीं किया जाता है, इसलिए, अधिक मेमोरी को अधिक दिए जाने की आवश्यकता है)।
java -Xmx64m -Ddw.http.port=8082 -Ddw.http.adminPort=9082 -Ddw.logging.file.currentLogFilename="assemble/target/server2.log" -jar assemble/target/assemble-0.4.0-SNAPSHOT.jar server assemble/src/main/resources/hz.yml
जब दोनों सर्वर एक दूसरे से जुड़ेंगे, तो लॉग इस संदेश की तरह दिखाई देगा:
Members [2] { Member [192.168.1.2]:7777 Member [192.168.1.2]:7778 this }
किसी ब्राउज़र में कंसोल खोलें।
http: // localhost: 8081 / index.html - पहला नोड या
http: // localhost: 8082 / index.html - दूसरा नोड।
कंसोल के साथ काम करने के लिए आप किसी भी नोड का उपयोग कर सकते हैं। वे मुख्य रूप से एक ही जानकारी प्रदर्शित करते हैं। वर्तमान में, सभी कंसोल फ़ंक्शंस इस कॉन्फ़िगरेशन (डेटाबेस के बिना) में काम नहीं करते हैं। सब कुछ oracle और mongodb db के साथ कॉन्फ़िगरेशन में काम करता है।
प्रलेखन में तैनाती के विकल्प देखें।
अब हम अपनी प्रक्रिया चलाते हैं। हम इसके लिए टास्क्यूरेटा-गेटस्टार्टेड रिपॉजिटरी को क्लोन करते हैं
git clone https://github.com/taskurotta/taskurotta-getstarted.git cd taskurotta-getstarted/ mvn clean install
अभिनेताओं को काम करना शुरू करने के लिए, प्रक्रियाओं को शुरू करना होगा। उदाहरण के लिए उन्हें 91 टुकड़े करें।
java -cp target/getstarted-process-1.0-SNAPSHOT.jar ru.taskurotta.example.starter.NotificationModule http://localhost:8081 91
कंसोल की जाँच करें
http: // localhost: 8081 / index.html । क्यू टैब चुनें। हम देखेंगे कि समन्वयक 91 के पास एक कार्य है, जो 91 वीं चलने वाली प्रक्रिया से मेल खाता है।

अब समन्वयक चलाएं। केवल इसे YAML कॉन्फ़िगरेशन फ़ाइल में परिभाषित किया गया है - निष्पादकों के बिना। इसलिए, लॉन्च के बाद, प्रक्रिया के सभी कार्य बाहर नहीं होंगे और हम लाइन में खड़े निष्पादकों के कार्यों को देखेंगे।
java -Xmx64m -jar target/getstarted-process-1.0-SNAPSHOT.jar -f src/main/resources/config-decider.yml
हमारे क्लस्टर के पहले नोड को कॉर्डिनेटर के लिए टास्कुरोट्टा सर्वर के रूप में कॉन्फ़िगरेशन फ़ाइल में परिभाषित किया गया है
spreader: - Spreader: class: ru.taskurotta.example.bootstrap.SimpleSpreaderConfig instance: endpoint: "http://localhost:8081" threadPoolSize: 10 readTimeout: 0 connectTimeout: 3000
आप कंसोल में कतार सूची को अपडेट कर सकते हैं और देख सकते हैं कि निष्पादन के लिए प्रतीक्षा करने वाले कार्य हैं।
अब हम निष्पादकों को चलाते हैं (समन्वयक को काम करने के लिए छोड़ दें) और उन्हें प्रदर्शित करने के लिए दूसरे क्लस्टर नोड पर निर्देशित करें। चूंकि क्लस्टर नोड्स आंतरिक मेमोरी को निष्पादित करने के लिए एक साझा मेमोरी और एक वातावरण बनाते हैं, इससे कोई फर्क नहीं पड़ता कि निष्पादनकर्ता से अनुरोध किस सर्वर से आएगा।
java -Xmx64m -jar target/getstarted-process-1.0-SNAPSHOT.jar -f src/main/resources/config-workers.yml
कलाकारों के पास बातचीत के लिए दूसरा क्लस्टर नोड है:
spreader: - Spreader: class: ru.taskurotta.example.bootstrap.SimpleSpreaderConfig instance: endpoint: "http://localhost:8082" threadPoolSize: 10 readTimeout: 0 connectTimeout: 3000
नतीजतन, सभी प्रक्रियाओं को पूरी तरह से काम करना चाहिए और यह प्रबंधन कंसोल में घुमावों में देखा जा सकता है।

अभी के लिए बस इतना ही। हम सुझावों और रचनात्मक आलोचना का स्वागत करते हैं।