پيادهسازی يك ESB قابل سفارشي سازی با جاوا
يكپارچهسازی برنامههای نامتجانس با استفاده از
Enterprise Service Bus
نويسنده:Balwinder
Sodhi
مترجم: مريم پويانپور
خلاصه
يكپارچه ساختن سرويسها و كامپوننتهاي مختلف موجود در يك سازمان، بدون توجه به پروتكل پيغامگذاري و يا فرمت پيغامي كه آنها استفاده ميكنند به يك backbone نياز دارد تا بتواند اين سرويسها و كامپوننتها را مرتبط سازد. يك گذرگاه سرويس سازماني (ESB)، زيرساخت- Service Messaging است كه اين backbone را فراهم ميسازد. اين مقاله چگونگي پيادهسازي يك ESB مبتني بر جاواي ساده، اما قابل سفارشي ساختن را كه رايجترين ملزومات كاربردي يك زيرساخت توزيع پيغام ESB را برآورده سازد، توضيح ميدهد. يكي از مزاياي اين پيادهسازي اين است كه كاملا بر پايه استانداردهاي Java/J2EE بوده و هيچ ويژگي J2EE خاص فروشنده را براي فراهم نمودن كارآيي ESB مورد استفاده قرار نميدهد. اين پيادهسازي ميتواند روي هر كانتينر J2EE سازگار انجام شود. يك سازمان را در نظر بگيريد كه در آنجا برنامههاي نامتجانس داريد (احتمالا توسط گروههاي مختلف توزيع شدهاند) كه به تعامل با يكديگر نياز دارند، اما از محدوديتهايي برخوردارند. اين محدوديتها عبارتند از:
برنامهها لزوما با استفاده از تكنولوژي مشابه ساخته نشدهاند، بنابراين ممكن است با استفاده از مكانيزم invocation محلي خود با هم ارتباط برقرار نكنند، به عنوان مثال يك برنامه J2EE و برنامه .Net
ترجيحا هر برنامه نبايد در خواستهايش را به فرمتي كه برنامه مورد نظر آن را ميشناسد، تغيير دهد، به علاوه سازمان برنامههاي زيادي دارد كه برنامه مورد نظر را مورد استفاده قرار ميدهند.
كامپوننتهاي سرويس بايد يك مكانيزم درخواست يا invocation را استفاده كنند كه براي آنها طبيعي ميباشد. به عنوان مثال برنامه J2EE موجود ميتواند درخواستها را فقط از طريق (Java Message Service) JMS بگيرد.
سازمان به سمت معماري حركت ميكند كه در آنجا يك برنامه خودش را با آنچه كه ميشناسد و آنچه بايد در هنگام به دست آوردن سرويسهاي ديگر در داخل سازمان به عنوان پارامتر پاس كند، مرتبط ميسازد.
محدوديتهاي ديگر ممكن است شما را به داشتن يك زيرساخت كه برنامههاي نامتجانس را بدون تغيير طرح آنها قادر به يكپارچه سازي مينمايد، ملزم سازند. ESB يكي از روشهاي شناخت چنين معماري يكپارچهسازي است.
گرچه هر سازمان احتمالا ESB خود را به روش منحصر به فرد خود ايجاد ميكند، اما در نظر گرفتن انعطافپذيري در تعريف يك ESB از اهميت خاصي برخوردار است. هيچ روش ثابتي براي ساختن يك ESB وجود ندارد. ايده واقعي، داشتن يك لايه ارتباطي است كه تعاملات بين فراهمكنندگان سرويس و مصرف كنندگان سرويس را بهبود بخشد و بتواند به بافت سازگار با سرويس، پيام يا رويداد پاسخ دهد.
در اينجا روشي براي ساختن يك ESB مبتنيبر جاواي قابل گسترش كه از رايجترين ملزومات كاربردي ESB پشتيباني ميكند، ارائه شده است.
ملزومات رايج ESB
ملزومات رايج ESB پر استفادهترين ويژگيهاي آن نيز ميباشد.
1. ESB: Routing بايد يك مكانيزم Routing انعطافپذير و كارآمد فراهم كند.
2. Transformation (تغيير): يك كامپوننت سرويس نبايد به دانستن معرفت درخواست سرويسي كه ممكن است استفاده نمايد، نياز داشته باشد. براساس درخواست كننده و هدف، ESB بايد بتواند تغيير مناسب را در مورد درخواست اعمال كند تا هدف بتواند آن را درك نمايد.
3. يك پيادهسازي ESB كه فقط JMS يا سرويسهاي وب را پشتيباني كند، ارزش چنداني ندارد، بلكه بايد بتواند آنقدر قابل گسترش باشد كه چند پروتكل پيام را بسته به نيازهاي سازمان پشتيباني نمايد.
4. امنيت: در صورت لزوم، ESB بايد احراز هويت و مجوز را براي دستيابي به كامپوننتهاي سرويس مختلف اعمال كند.

شكل 1- كامپوننتهاي معماري اصلي يك ESB
شكل 1 كامپوننتهاي معماري اصلي يك ESB را نشان ميدهند كه داراي 3 بخش هستند:
1. Receiver (گيرنده): يك ESB براي اينكه به برنامههاي كلاينت اجازه دهد تا پيامها را به ESB بفرستند، اينترفيسهاي مختلفي را در دسترس ميگذارد. به عنوان مثال يك Servlet ميتواند درخواستهاي HTTP براي ESB را دريافت كند. در همين زمان شما ميتوانيد يك (message-driven bean)MDB داشته باشيد كه به يك مقصد JMS يعني جايي كه برنامههاي كلاينت ميتوانند پيام بفرستند، گوش دهيد.
2. Core (هسته): Core بخش اصلي پيادهسازي ESB است و روتينگ و تغيير را مديريت نموده و امنيت را برقرار ميسازد. عموما Core از يك MDB تشكيل شده كه درخواستهاي رسيده را دريافت نموده و سپس براساس بافت متن تغييرات، روتينگ و امنيت مناسب را اعمال ميكند. اطلاعات مشروح درباره روتينگ، انتقال، تغيير و امنيت در يك سند XML خاص قرار ميگيرد.
3. Dispatcher (توزيع كننده): تمام اداره كنندههاي انتقال outbound (به طرف بيرون) در اين بخش ESB قرار ميگيرند. شما ميتوانيد هر گونه اداره كننده انتقال (مثل e-mail، فكس، FTP و غيره) را به ESB متصل كنيد.
تمام اين بخشهاي ESB توسط يك سند XML كه كل مسيرهايي را كه ESB بر روي آنها عمل مينمايد را فهرست بندي ميكند، به يكديگر متصل ميشوند. اداره كنندههاي انتقالات، مبدلهاي مختلف، سياستهاي اعمال شده و اتصالات آنها به مسيرهاي مختلف از طريق اين سند XML مرتبط ميشوند.
ESBConfiguration.xml
ليست XML كه در زير آورده شده اطلاعاتي درباره عملكرد ESB به ما ميدهد. عناصر اصلي به شرح زير ميباشند:
1. Beans: اين عنصر شامل صفر عنصر Bean يا بيشتر ميباشد.
2. Bean: اين عنصر روش ايجاد و پيكربندي يك كلاس Bean را تعريف ميكند و ويژگيهاي زير را دارد:
name: نام منحصربهفردي كه براي اشاره به اين bean استفاده ميشود.
Class Name: نام كاملا مشروط كلاس bean
هر bean ميتواند صفر عنصر پراپرتي يا تعداد بيشتري از آنها را به عنوان Children داشته باشد. هر عنصر پراپرتي يك name ويژگي دارد كه آن را مشخص ميكند و نيز يك عنصر Child كه نوع Value دارد و مقدار پراپرتي را نگاه ميدارد. اين پراپرتيها واقعا اعضاي مدل Java-Beans اين كلاس هستند كه ميتوانند كلاس bean را پيكربندي كنند.
3. RetryPolices: اين عنصر حامل صفر يا تعداد بيشترRetry Policy Children ميباشد.
4. RetryPolicy: اين عنصر سياست retry براي يك مسير خاص را تعريف ميكند و داراي يك نام ويژگي است كه براي ارجاع به آن مورد استفاده قرار ميگيرد. اين عنصر دو عنصر Child به نامهاي MaxRetries وRetry Interval دارد.
5. Route: عنصر ريشه EsbConfiguration ميتواند داراي صفر يا تعداد بيشتر عنصرهاي Child از اين نوع باشد. اين عنصر مسيري را براي ESB نشان ميدهد و ويژگيهاي ذيل را دارا ميباشد:
name: يك نام منحصربهفرد كه براي ارجاع به آن مورد استفاده قرار ميگيرد.
retryPolicyRef: ارجاع به سياست retry. اين بايد با ويژگي name عنصر RetryPolicy مطابقت كند.
TransformerRef: ارجاع به يك bean كه مبدل را نشان ميدهد. اين بايد با ويژگي name عنصر Bean مطابقت نمايد.
عنصر Route ميتواند يك يا چند عنصر Child از نوع Transport HandlerRef داشته باشد.
اين Child اساسا به يك bean ( يك اداره كننده انتقال مناسب كه بايد براي اين مسير مورد استفاده قرار گيرد را نشان ميدهد) و نام متد عمومي اين bean كه براي ارسال پيغام فراخواني ميشود، اشاره ميكند. عنصر Route به شكل اختياري، ميتواند يك Child DeadletterDestination داشته باشد كه به مسير ديگري كه نشان دهنده يك مقصد dead-Letter است، اشاره ميكند.
سند XML نمونه EsbConfiguration.xml، به شكل زير ظاهر ميشود:
<?xml version="1.0"
encoding="UTF-8"?>
<EsbConfiguration xmlns="http://www.bss.org/esb/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Route name="creditService" retryPolicyRef="100-sec-retry"
transformerRef="creditServiceTransform">
<TransportHandler beanName="creditJMSTransport"/>
<DeadLetterDestination routeName="DeadLetter"/>
<AuthConstraint principals="app-1"/>
</Route>
<Route name="taxCalculationService" retryPolicyRef="500-sec-retry"
transformerRef="taxCalcServiceTransform">
<TransportHandler beanName="taxCalcWS"/>
<DeadLetterDestination routeName="DeadLetter"/>
<AuthConstraint principals="app-2"/>
</Route>
<Route name="RedeliveryRequest" retryPolicyRef="500-sec-retry">
<TransportHandler beanName="redeliveryRequestJMSTransport"/>
<DeadLetterDestination routeName="DeadLetter"/>
</Route>
<Route name="DeadLetter" retryPolicyRef="500-sec-retry">
<TransportHandler beanName="deadLetterJMSTransport"/>
</Route>
<Route name="Redelivery" retryPolicyRef="500-sec-retry">
<TransportHandler beanName="redeliveryJMSTransport"/>
<DeadLetterDestination routeName="DeadLetter"/>
</Route>
<Route name="Error" retryPolicyRef="500-sec-retry">
<TransportHandler beanName="errorJMSTransport"/>
</Route>
<Beans>
<!-- Transport handlers for the service components. -->
<Bean name="creditJMSTransport"
className="org.bss.esb.transport.jms.JmsHandler">
<Property name="ConnectionFactory" type="java.lang.String">
<Value>qcf-1</Value>
</Property>
<Property name="Destination" type="java.lang.String">
<Value>myCreditQueue</Value>
</Property>
</Bean>
<Bean name="taxCalcWS"
className="org.bss.esb.transport.webservice.WebServiceHandler">
<Property name="WsdlUrl" type="java.lang.String">
<Value>http://www.tax.com/calc</Value>
</Property>
</Bean>
<!-- Transformer beans for the service components -->
<Bean name="creditServiceTransform"
className="org.bss.esb.transform.XSLTransform">
<Property name="XslUrl" type="java.lang.String">
<Value>file:///C:/temp/esb/transform/xsl/credit.xsl</Value>
</Property>
</Bean>
<Bean name="taxCalcServiceTransform"
className="org.bss.esb.transform.CustomTransform">
<Property name="ConfigFileUrl" type="java.lang.String">
<Value>file:///C:/temp/esb/transform/custom/configManager.properties</Value>
</Property>
</Bean>
<!-- Transport handlers for the system queues -->
<Bean name="redeliveryJMSTransport"
className="org.bss.esb.transport.jms.JmsHandler">
<Property name="ConnectionFactory" type="java.lang.String">
<Value>qcf-1</Value>
</Property>
<Property name="Destination" type="java.lang.String">
<Value>Redelivery.Queue</Value>
</Property>
</Bean>
<Bean name="deadLetterJMSTransport"
className="org.bss.esb.transport.jms.JmsHandler">
<Property name="ConnectionFactory" type="java.lang.String">
<Value>qcf-1</Value>
</Property>
<Property name="Destination" type="java.lang.String">
<Value>System.DL.Queue</Value>
</Property>
</Bean>
<Bean name="errorJMSTransport"
className="org.bss.esb.transport.jms.JmsHandler">
<Property name="ConnectionFactory" type="java.lang.String">
<Value>qcf-1</Value>
</Property>
<Property name="Destination" type="java.lang.String">
<Value>System.Error.Queue</Value>
</Property>
</Bean>
<Bean name="redeliveryRequestJMSTransport"
className="org.bss.esb.transport.jms.EsbRedeliveryHandler">
<Property name="ConnectionFactory" type="java.lang.String">
<Value>qcf-1</Value>
</Property>
<Property name="Destination" type="java.lang.String">
<Value>Redelivery.Request.Topic</Value>
</Property>
</Bean>
</Beans>
<!-- Defines the retry policies that can be used by various route
definitions. -->
<RetryPolicies>
<RetryPolicy name="100-sec-retry">
<MaxRetries>10</MaxRetries>
<RetryInterval>100</RetryInterval>
</RetryPolicy>
<RetryPolicy name="500-sec-retry">
<MaxRetries>10</MaxRetries>
<RetryInterval>500</RetryInterval>
</RetryPolicy>
</RetryPolicies>
</EsbConfiguration>
رفتار ESB
سند ESBConfiguration.xml رفتار ESB ما را تعيين ميكند. EsbRouterMDB اين XML را از محلي كه در توصيفگر deployment آن مشخص شده، بارگذاري ميكند، سپس اطلاعات آن در يك ساختار داده كه در شكل 2 نشان داده شده، سازماندهي ميشود.

شكل 2- اطلاعات ESB در يك ساختار داده
EsbRouter از اين اطلاعات (از طريق EsbConfigManager) براي خواندن مسير درست، تغييرات اعمال شده، مجوز امنيت و غيره استفاده ميكند. نكته مهمي كه بايد به خاطر سپرد، روش مورد استفاده قرار گرفتن تكنيك Dependency Injection به همراه وراثت براي پايان دادن به ارتباط عملكردهاي مختلف ESB ميباشد. اين روش امكان قابل گسترش بودن و قابل سفارشي بودن ESB را فراهم ميسازد.
همانطور كه الگوي كلاس نشان ميدهد، 2 اينترفيس مهم در طراحي ESB وجود دارد: TransformHandler و TransportHandler. اين دو اينترفيس امكان نوشتن يك پيادهسازي انتقال و تغيير خاص براي پيامهاي راهبري شده را در اختيار شما قرار ميدهند. اين كلاسهاي پيادهسازي ميتوانند از طريق عناصر Bean در EsbConfigureration با مسيرها مرتبط شوند (Wire). به عنوان مثال در سند نمونه ESBConfiguration.xml، تعريف Bean زير اداره كننده انتقال را مشخص ميكند.
<Bean name="creditJMSTransport"
className="com.foo.esb.transport.jms.JmsHandler">
<Property name="ConnectionFactory" type="java.lang.String">
<Value>myQCF</Value>
</Property>
<Property name="Destination" type="java.lang.String">
<Value>myCreditQueue</Value>
</Property>
</Bean>
سپس ميتوان با درج يك TransportHandler Child مثل
<TransportHandler BeanName = “Credit JMST transport”/>
به اين اداره كننده انتقال در يك گره Route رجوع كرد.
نكته: روشي كه در اين مقاله شرح داده شده است از اينترفيسهاي جاوا براي تعريف اداره كنندههاي انتقال و تغيير استفاده ميكند، بنابراين هر اداره كننده جديد بايد اينترفيس مورد نياز را پيادهسازي نمايد كه بسيار آزار دهنده به نظر ميرسد. شما ميتوانيد EsbConfigManager را براي استفاده از Dependency Injection به منظور فراخواني هر متد اختياري كلاس پيادهسازي اصلاح كنيد و نياز به پيادهسازي يك اينترفيس را برطرف سازيد، اما چونEsbRouter هميشه يك مورد javax.jms.Message را عبور ميدهد (Pass)، كلاس پيادهسازي اداره كننده شما بايد به هر حال از نوع javax.jms.Message استفاده كند.
اكنون بياييد اين فرآيند را به همان شكلي كه در يك ESB اتفاق ميافتد، براساس دريافت يك پيام كه عازم يك مسير خاص (سرويس يا برنامه) است، مرحله به مرحله مرور كنيم. براي سهولت بيشتر فرض ميكنيم دو برنامه از طريق JMS تعامل دارند.
1. برطبق توصيفگر deployment اولين تعداد نمونههاي MDBهاي EsbRouter ايجاد ميشوند.
2. متد ejbcrate() از EsbRouter فراخواني شده و وظايف ذيل را كامل ميكند:
- فايل EnvConfig.xml را از آدرس (URL) تعيين شده در ورودي محيط به نام java:Comp/env/EnvconfigURL بارگذاري ميكند.
- از EnvConfig.xml، آدرس محل EsbConfiguration.xml را ميخواند و آن را به يك Xml Bean تجزيه ميكند.
- نمونه EsbConfigManager را ايجاد و آغاز مينمايد كه اين مرحله ايجاد و آغاز تمام beanهاي پيكربندي شده در EsbConfiguration.xml و سپس پركردن (Populate) ساختارهاي ديتا مشخص شده در شكل 2 را در برميگيرد.
- نمونه EsbRouterMonitorMBean را آغاز ميكند (جزئيات اين مرحله شرح داده خواهد شد. فقط بدانيد كه به ساخت ESB مجهز به (Java Management Extension) JMX كمك ميكند.
- وقتي كامپوننت سرويس به ارسال يك پيام (مثلا M) به يك كامپوننت ديگر از طريق ESB نياز پيدا ميكند، اين متد پيام JMS را در صف ورودي ESB قرار ميدهد و منجر به فراخواني متد OnMessage() از ESBRouter ميشود. مراحل ذيل از طريق OnMessage() انجام ميشوند:
1. مسيري با نام R كه در يك پراپرتي پيام رسيده M مشخص شده، خوانده ميشود. نام اين پراپرتي خاص همراه با نامهاي ديگري كه بعدا معرفي خواهند شد از طريق EnvConfig.xml قابل پيكربندي ميباشند.
2. Route Info مطابق با مسير R از نمونه ESBConfigManager جستجو ميشود.
3. درخواست كننده كنترل ميشود تا مجاز يا غيرمجاز بودن آن براي ارسال پيام به مسير انتخاب شده مشخص شود. اگر درخواست كننده مجاز نباشد پيام كنار گذاشته ميشود. شما ميتوانيد اين رفتار را به دلخواه تنظيم نماييد. به عنوان مثال ميتوانيد به عنوان مدير شبكه پيام را به يك صف يا صفحه خاص وارد كنيد.
4. اگر يك TransformHandler bean قرينه پيكربندي شود از طريق الگوي EsbConfigManager جستجو ميشود و متد TransformMessage() آن با عبور دادن پيام M به عنوان يك آرگومان فراخواني ميگردد.
5. در هر TransportHandler به دست آمده براي مسير R، EsbRouter متد TransportMessage() را فرا ميخواند و پيام M ورودي به عنوان يك پارامتر عبور داده ميشود.
6. اگر هيچ ورودي در EsbConfigManager براي مسير R پيدا نشود، TransportHandler براي مسير dead-letter سيستم جستجو ميشود، سپس پيام M به مسير dead-letter فرستاده ميگردد.
7. اگر اداره كننده مسير خاص پيدا شود، اما TransportHandler نتواند پيام را ارسال كند و يا اينكه خطاي سيستم وجود داشته باشد، پس پيام براي ارسال مجدد در صف قرار ميگيرد.
قرار گرفتن در صف براي ارسال مجدد شامل مراحل زير است:
1. سياست retry از EsbConfigManager براي مسير خاص جستجو ميشود.
2. زمان بعدي ارسال براساس وقفه retry در سياست retry محاسبه ميگردد.
3. اين زمان به عنوان پراپرتي MessageRedeliveryTime تنظيم شده و به صف ارسال مجدد فرستاده ميشود.
4. يك پيام درخواست ارسال مجدد جداگانه به موضوع درخواست ارسال مجدد فرستاده ميگردد. درخواست ارسال مجدد يك javax.jms.ObjectMessage است كه يك آبجكت Long دارد. آبجكت فوق زمان ارسال مجدد محاسبه شده بعدي را به عنوان Payload نشان ميدهد.
ارسال مجدد پيام: زمانبندي و پردازش
RedeliveryRequestorProcessorMDB براساس دريافت يك پيام، درخواست ارسال مجدد يك نمونه RedeliveryTask را ايجاد ميكند. RedeliveryTask با زمان ارسال مجدد (كه در پيام درخواست ارسال مجدد با عنوان Long مشخص شده) آغاز و از طريق RedeliveryScheduler زمانبندي ميشود.
RedeliveryScheduler يك كلاس تك است كه كار زمانبندي را به java.Util.Timer مربوط به خود تفويض ميكند. متد run() از RedeliveryTask در زمان تعيين شده فراخواني ميشود و سعي ميكند در اين زمان يك پيام از صف ارسال مجدد دريافت نمايد. گيرندهاي كه اين متد را مورد استفاده قرار ميدهد يك انتخابگر پيام دارد كه فقط پيامي را كه پراپرتي MessageRedeliveryTime آن با زمان تعيين شده مطابقت داشته باشد، انتخاب ميكند، سپس اين پيام به صف ورودي ESB فرستاده ميشود.
يك پيام مجددا ارسال شده M كه براي مسير خاص R در نظر گرفته شده بدين شكل پردازش ميشود:
1. سياست retry از EsbConfigManager براي مسير خاص جستجو ميشود.
2. يك پراپرتي كه تلاشهاي ارسال مجدد گذشته براي اين پيام را نگاه داشته از M خوانده ميشود، اگر چنين پراپرتي وجود نداشته باشد و حداكثر retry طبق سياست retry صفر باشد، پس پيام M به مسير dead-letter فرستاده ميشود و مراحل بعدي حذف خواهند شد.
3. علاوه بر آن اگر تلاشهاي ارسال مجدد براي M بيشتر از حد ماكزيمم تعيين شده توسط سياست retry باشد، پس M به مسير dead-letter مربوط به مسير R فرستاده ميشود.
4. موارد ديگر:
· حساب تلاشهاي ارسال مجدد يكييكي افزايش مييابند.
· زمان بعدي ارسال مجدد براساس وقفه retry در سياست retry محاسبه ميشود.
· حساب تلاشهاي اضافه و زمان ارسال مجدد بعدي به عنوان پراپرتيها در M تنظيم ميشوند.
· پيام M به مسير ارسال مجدد فرستاده ميشود. TransportHandler مناسب براي مسير ارسال مجدد به شكل معمول از TransportHandlerCache جستجو ميشود.
· يك پيام درخواست ارسال مجدد به مسير درخواست ارسال مجدد فرستاده ميشود. اين پيام فقط شامل زمان بعدي يعني زماني كه پيام M براي ارسال مجدد زمانبندي ميشود، است.
5. اگر هرگونه خطا منجر به تلاش براي ارسال مجدد گردد، پيام M به مسير dead-letter مربوط به مسير R فرستاده ميشود، در صورتيكه ارسال به مسير خطا نيز با موفقيت انجام نشود، تراكنش متدOnMessage() از EsbRouter به وضعيت قبل برميگردد و در نتيجه پيام M به صف ورودي ESB باز خواهد گشت.
نكته: ما از يك موضوع به جاي يك صف براي ارسال درخواستهاي ارسال مجدد استفاده ميكنيم، چون اكثر كانتينرهاي J2EE سرويس timer استاندارد را فراهم نميسازند، اما آنها احتمالا APIهاي انحصاري خود را براي كامل نمودن وظايف مشابه فراهم ميكنند. پيادهسازيESB كه در اين مقاله توضيح داده شد از نمونه java.Util.Timer پيچيده شده در يك Singlton براي اجراي زمانبندي استفاده ميكند. فرض كنيد از يك صف به جاي موضوع استفاده ميكنيم، حال درباره يك محيط كلاستر شده كه RedeliveryRequesterProcessorMDB را براي آن به كار گرفتهايد، فكر كنيد. تنها يكي از سرورهاي مديريت شده در كلاستر، پيام درخواست از صف را دريافت خواهند كرد. اگر اين سرور مديريت شده بعد از زمانبندي يك RedeliveryTask براي اجرا در آينده دچار اختلال شود ما نخواهيم توانست آن را به موقع توزيع كنيم و در نتيجه مهلت ارسال منقضي خواهد شد. در مورد يك موضوع، پيغام درخواست به تمامي نمونههاي RedeliveryRequesterProcessorMDB در كلاستر فرستاده خواهد شد، بنابراين حتي اگر سرور مديريت شده بعد از زمانبندي يك وظيفه از كار بيفتد، يكي از نمونهها آن را اجرا خواهد كرد. در به كارگيري واقعي يك ESB ما يك مصرف كننده (احتمالا MDB) يا مصرف كنندگان جداگانه يا مشترك را براي مسيرهاي dead-letter مربوط به هر يك از مسيرهاي پيكربندي شده تخصيص ميدهيم. چنين مصرف كنندگاني پيامها را از مسيرهاي dead-letter ميگيرند و آنها را به اطلاع برنامهها يا مديران شبكه علاقمند به اين پيامها ميرسانند.
نمودارهاي UML
نمودارهاي UML زير ساختار پويا و ايستاي ESB و كامپوننتهاي مختلف را نشان ميدهند: (شكلهاي 3، 4، 5، 6 و 7)
شكل 3
شكل 4
شكل 5
شكل 6
شكل 7
مديريت زمان اجرا
يك سيستم حياتي و بسيار مهم مثل ESB بايد در زمان اجرا قابل مديريت و قابل كنترل باشد. بعضي از وظايف عملياتي مثل به روزرساني يا افزودن مسيرهاي جديد و اعمال تغييرات مناسب اداره كنندههاي انتقال و سياستهاي retry بايد از طريق يك كنسول قابل اجرا باشند. براي فراهم آوردن چنين كنترلي از ESB، بعضي از كامپوننتهاي Core آن به JMX مجهز شدهاند كه عملكردها و ويژگيهاي مهم خاصي را براي انجام فقط اين نوع از وظايف نشان ميدهند.
MDBهاي RedeliveryRequestProcessor و EsbRouter مجهز به JMX هستند به عنوان مثال عملكردها براي:
- به روزرساني پوياي پيكربندي بارگذاري شده توسط EsbConfigManager
- ضبط آمار توان عملياتي
- كنترل زمانبندي ارسال مجدد
در دسترس هستند. اگر به كنترل يا مانيتور ويژگيهاي اضافه نياز داريد، ميتوانيد عمليات بيشتري اضافه كنيد.
نتيجه
هر سازمان براي يك راهكار يكپارچهسازي برنامه سازمان مثل ESB به ملزومات خاص نياز دارد و آن را به شكلي متفاوت از شركتهاي ديگر پيادهسازي ميكند. موضوع مهمي كه در موفقيت پيادهسازي يك ESB نقش اساسي دارد، طراحي انعطافپذير از نظر سفارشي سازي و گسترش ميباشد كه بر بخشهاي موجود كل سيستم تاثير نگذارد. گرچه طراحي كه در اينجا شرح داده شده از كانتينرهاي Inversion of Control استفاده نميكند، پيادهسازي اين طرح با استفاده از چارچوبهايي مثل Spring امكانپذير است.
Copyright
2005 IDG News Service.All right reserved.
Copyright 2005, PC World Iran, All rights reserved.