سرویس بروکر Service Broker چیست؟

7 دقیقه زمان مطالعه
1401/12/14
0 نظر
شرکت مایکروسافت (Microsoft) برای اولین‌ بار در Sql Server 2005، ویژگی Service Broker را ارائه کرد که به اختصار SSSB  هم خوانده  می‌شود. با کمک Service Broker می‌توانیم ارسال و دریافت پیام به صورت غیرهمزمان و تضمین شده را در یک یا چند دیتابیس متفاوت (حتی در سرور جداگانه) داشته باشیم. در این مقاله قصد داریم به ویژگی‌های اصلی Service Broker بپردازیم. هدف اصلی Service Broker ایجاد قابلیت ارسال غیر همزمان پیام‌ها (Asynchronous Message Queue) است که این تبادل پیام یا Message به صورت امن (Secure)، مطمئن (Reliable) و مقیاس‌پذیر (Scalable) صورت می‌پذیرد.

کاربرد Service Broker

برای درک بهتر این که Service Broker چیست؟ و چه کاربردی دارد، در ادامه با هم یک مثال ساده را بررسی می‌کنیم. یک سیستم ثبت سفارش را تصور کنید. وقتی کاربر اقدام به ثبت سفارش می‌کند، چندین فرآیند باید پشت سر هم انجام شود تا آن سفارش به صورت کامل ثبت شود. این فرایند‌ها شامل درج سفارش، درج سند حسابداری، درج لاگ سفارش، ارسال ایمیل و پیامک جهت تایید سفارش و… است. انجام تمامی این فرایند در یک تراکنش به صورت همزمان می‌تواند باعث طولانی شدن فرایند ثبت سفارش شود در صورتی که می‌توان یکسری از این فرایندها را به صورت غیرهمزمان انجام داد. این کار باعث کارکرد و عملکرد بهتر در زمان ثبت سفارش می‌شود. در مثال ما ثبت سفارش و ثبت سند حسابداری باید به صورت همزمان اتفاق بیفتد ولی فرایند‌های ثبت لاگ، ارسال پیامک و ایمیل می‌توانند طی یک فرایند جداگانه و به صورت غیرهمزمان انجام شود. در این جا  می‌توان از Service Broker استفاده کرد.

اجزای مهم Service Broker

Service Broker از ۴ جزء مهم تشکیل شده است که سعی می‌کنیم هر کدام را به صورت جداگانه توضیح دهیم:
  • Message types
  • Contracts
  • Queues
  • Service program

نصب و کانفیگ Service Broker:

برای فعال سازی Service Broker از کوئری زیر استفاده کنید:
USE master

ALTER  DATABASE  HelloWorldServiceBroker SET ENABLE_BROKER;

GO
نکته ای که لازم است به آن توجه کنید، این است که فعال سازی Service Broker به ازای دیتابیس انجام می‌شود. برای دیدن فهرست دیتابیس‌هایی که Service Broker  برای آن‌ها فعال است، می‌توانید از دستور زیر استفاده کنید:
USE master

select name,is_broker_enabled from sys.databases

GO

Message Types

ماهیت Service Broker، ارسال پیام بین سرویس‌هایی است که با هم صحبت می‌کنند. این پیام‌ها همان رکورد‌های ما و در واقع Message Type  ها هستند. پیام دارای یک بدنه اصلی دارد که به صورت پیش فرض Var Binary است. در زمان ایجاد پیام، باید نام و قالب دیتا (DataType) را مشخص کنیم. در حال حاضر Service Broker  از ۴ قالب داده پشتیبانی می‌کند. برای ارسال پیام، می‌توانیم از هر کدام از آن‌ها استفاده کنیم که عبارتند از: Well-formed XML XML validated against a registered XML schema collection No validation (e.g. for binary data) Empty (the message body must be empty) در مثال زیر، برای ارسال و دریافت پیام‌ها  دو Message Type  از نوع xml  درست کردیم. Message  type با نام [Request Message] و نوع xml برای ارسال پیام‌ها و Message Type دیگری با نام [Response Message] برای دریافت پیام‌ها که همانند نوع پیام قبلی از  xml  استفاده کردیم.
Use HelloWorldServiceBroker

GO

CREATE MESSAGE TYPE

[RequestMessage]

VALIDATION = WELL_FORMED_XML

GO

CREATE MESSAGE TYPE

[ResponseMessage]

VALIDATION = WELL_FORMED_XML

قرارداد‌ها (Contracts)

service broker برای ارسال پیام‌ها از منطق صف یا Queue استفاده می‌کند که برای تحقق این امر نیاز به یک قرارداد دارد. در این قرارداد مشخص می‌شود که آغازگر (Initiator) و دریافت‌کننده پیام (Target) کدام سرویس است. تعریف Contract بخش‌های مختلفی دارد که شامل موارد زیر است:
  • Send By Initiator
  • Send By Target
  • Send By ANY
در مثال زیر، یک قرارداد  با نام [HelloWorldContract] ایجاد کردیم که در آن (Request Message) ارسال‌کننده و (Response Message) دریافت‌کننده پیام خواهند بود. ارسال‌کننده را با Send By Initiator  و دریافت‌کننده پیام را با Send By Target  مشخص کردیم.
CREATE CONTRACT [HelloWorldContract]

(
[RequestMessage] SENT BY Initiator,

[ResponseMessage] SENT BY TARGET
)

صف‌ها (Queues)

صف محل ذخیره پیام‌ها در Service Broker است، شما می‌توانید مانند جداول معمولی روی صف، کوئری select را اجرا کنید و از وضعیت صف با خبر شوید.
SELECT *  FROM InitiatorQueue
در مثال زیر، براساس Initiator و Target دو صف ایجاد کرده‌ایم که در آن پیام‌ها توسط سرویس که در ادامه مقاله به آن اشاره خواهیم کرد، به صف هدایت می‌شوند.
CREATE QUEUE InitiatorQueue

WITH STATUS = ON

GO

CREATE QUEUE TargetQueue

WITH STATUS = ON

سرویس (Service)

اگر بخواهیم یک تعریف کلی و ساده از Service داشته باشیم، می‌توان گفت وظیفه service هدایت پیام‌ها به صف مورد نظر است. در واقع سرویس و صف به هم وابستگی دارند .هنگامی که Initiator یا Target پیامی را ارسال یا دریافت می‌کنند، سرویس پیام‌ها را به صف‌های مناسب هدایت می‌کند به طور مثال Initiator شروع به ارسال پیام می‌کند، سرویس، پیام را  که از سمت Initiator ارسال شده است، به صف مورد نظری که در مثال ما Target Queue است، هدایت می‌کند و این فرایند تا زمان به پایان رسیدن مکالمه، ادامه خواهد یافت. در مثال زیر بر اساس هر کدام از صف‌هایی که در بالا ایجاد کردیم‌، سرویس تعریف شده است.
CREATE SERVICE Initiator Service

ON QUEUE Initiator Queue

(

[HelloWorldContract]

)

GO

CREATE SERVICE TargetService

ON QUEUE TargetQueue

(

[HelloWorldContract]

)

GO
در نهایت، پس از ایجاد زیر ساخت‌های اصلی Service Broker، آماده‌ایم که ارسال پیام‌ها را شروع کنیم. این کار توسط  BEGIN DIALOG CONVERSATION  انجام می‌شود اما قبل از این کار اجازه دهید،  یک جمع بندی سریع داشته باشیم از کارهایی که تا الان انجام داده‌ایم. در ابتدا، در سطح دیتابیس Service Broker را فعال کردیم. بعد از فعال کردن سرویس، message type با نوع xml را برای ارسال و دریافت پیام‌ها تعریف کردیم. یک قرار داد که مشخص‌کننده  Initiator یا  Target است را ایجاد کردیم . در مرحله بعد، دو صف بر اساس  Initiator  یا Target برای ذخیره پیام‌ها تعریف کردیم . در انتها، دو سرویس برای هدایت پیام‌ها به صف‌های  مورد نظر ایجاد کردیم.

مکالمات (Dialogue یا Conversations)

شروع فرایند ارسال پیام با دیالوگ انجام می‌شود. مفهوم دیالوگ بسیار ساده است. یک آغازکننده ارسال پیام، یک دریافت‌کننده پیام و در نهایت تایید دریافت پیام و پایان دیالوگ. در service broker   برای آغاز ارسال پیام، نیاز به Begin Dialog Conversation است که شامل یک سرویس آغازگر (Initiator)، سرویس مقصد (Target) و همچنین قرارداد است. در صورت تمایل، شما می‌توانید تعیین کنید که آیا از رمزگذاری استفاده شود یا خیر. در حال حاضر ما برای ساده‌سازی فرایند چیزی را رمزگذاری نمی‌کنیم. پیگیری پیام بین سرویس‌ها توسط یک UNIQUEIDENTIFIER  انجام می‌شود. در مثال زیر، یک دیالوگ ایجاد کرده‌ایم:
BEGIN TRANSACTION ;

DECLARE @ch UNIQUEIDENTIFIER

DECLARE @msg NVARCHAR(MAX) ;

BEGIN DIALOG CONVERSATION @ch

FROM SERVICE [InitiatorService]

TO SERVICE 'TargetService'

ON CONTRACT [HelloWorldContract]

WITH ENCRYPTION = OFF ;

SET @msg = '<HelloWorldRequest>

Send message hello

</HelloWorldRequest>' ;

SEND ON CONVERSATION @ch

MESSAGE TYPE [RequestMessage]

(@msg) ;

COMMIT TRANSACTION

GO
قبل از این که سراغ مرحله بعد برویم، بهتر است بر روی Queue دستور select را اجرا کنیم:
select * from TargetQueue
همانطور که در خروجی مشاهده می‌کنید، یک رکورد در صف وجود دارد، این رکورد همان پیامی است که توسط دستورات بالا ایجاد و در صف قرار گرفته است. پس از ارسال پیام از سمت آغازگر، برای دریافت و پردازش پیام می‌توان از عبارت Receive  استفاده کرد. در این مرحله، از صف Target Queue پیام ارسال شده خوانده و پردازش می‌شود و سپس جواب آن به صف Initiator ارسال می‌شود.
DECLARE @ch UNIQUEIDENTIFIER

DECLARE @messagetypename NVARCHAR(256)

DECLARE @messagebody XML

DECLARE @responsemessage XML

BEGIN TRANSACTION ;

RECEIVE TOP(1)

@ch = conversation_handle,

@messagetypename = message_type_name,

@messagebody = CAST(message_body AS XML)

FROM TargetQueue

PRINT 'Conversation handle: ' + CAST(@ch AS NVARCHAR(MAX))

PRINT 'Message type: ' + @messagetypename

PRINT 'Message body: ' + CAST(@messagebody AS NVARCHAR(MAX))

IF ( @messagetypename = RequestMessage' )

BEGIN

-- Construct the response message

SET @responsemessage = '<HelloWorldResponse>Hello World, '

+ @messagebody.value('/HelloWorldRequest[1]', 'NVARCHAR(MAX)')

+ '</HelloWorldResponse>' ;

-- Send the response message back to the initiating service

SEND ON CONVERSATION @ch MESSAGE TYPE [ResponseMessage] (@responsemessage) ;

-- End the conversation on the target's side

END CONVERSATION @ch ;

END

COMMIT TRANSACTION

GO
بعد از اجرا کوئری بالا، می‌توانید دستور select * from InitiatorQueue را برای مشاهده وضعیت صف اجرا کنید.
DECLARE @ch UNIQUEIDENTIFIER

DECLARE @messagetypename NVARCHAR(256)

DECLARE @messagebody XML

BEGIN TRANSACTION ;

RECEIVE TOP (1)

@ch = conversation_handle,

@messagetypename = message_type_name,

@messagebody = CAST(message_body AS XML)

FROM InitiatorQueue

IF ( @messagetypename = ‘ResponseMessage' )

BEGIN

PRINT 'Conversation handle: ' + CAST(@ch AS NVARCHAR(MAX))

PRINT 'Message type: ' + @messagetypename

PRINT 'Message body: ' + CAST(@messagebody AS NVARCHAR(MAX))

END

IF ( @messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' )

BEGIN

-- End the conversation on the initiator's side

END CONVERSATION @ch ;

END

COMMIT TRANSACTION

GO
جمع‌بندی
در پاسخ به سوال Service Broker چیست؟ می‌توان گفت، Service Broker یک ویژگی قدرتمند و کاربردی است که در sql server 2005 معرفی شده است. این ویژگی به ما کمک می‌کند تا یک سری از فرایندها را به صورت Asynchronous (غیر همزمان ) انجام دهیم که بهترین مثال برای این موضوع  ارسال ایمیل یا پیامک است. در این مقاله ما تعریف، کاربرد و اجزای، نمونه کد و مثال Service Broker با هم بررسی کردیم.    
امتیاز شما به این مقاله:
نویسنده:

مطالب مرتبط