RabbitMQ - خادم SQL

قبل أسبوع أو أسبوعين ، رأيت رسالة في منتدى مستخدمي RabbitMQ حول كيفية إعداد إرسال الرسائل من SQL Server إلى RabbitMQ. نظرًا لأننا نعمل بشكل وثيق مع Derivco ، تركت بعض الاقتراحات هناك ، وقلت أيضًا أنني أكتب مدونة حول كيفية القيام بذلك. جزء من رسالتي لم يكن صحيحًا تمامًا - على الأقل حتى تلك اللحظة (آسف ، يا صديقي ، كان مشغولًا جدًا).

شيء رائع ، هذا هو خادم SQL الخاص بك. من السهل جدًا وضع المعلومات في قاعدة بيانات. استرجاع البيانات من قاعدة بيانات باستخدام استعلام بنفس السهولة. ولكن الحصول على البيانات التي تم تحديثها أو لصقها للتو أصبح أصعب قليلاً. فكر في الأحداث في الوقت الفعلي ؛ يتم إجراء عملية شراء - يحتاج شخص ما إلى إخطار بشأن هذا في نفس اللحظة بمجرد حدوث ذلك. ربما سيقول أحدهم أن هذه البيانات لا يجب أن تنبثق من قاعدة البيانات ، ولكن من مكان آخر. بالطبع ، هذا هو الحال ، ولكن في كثير من الأحيان ليس لدينا خيار.

كانت لدينا مهمة: إرسال الأحداث من قاعدة البيانات إلى الخارج لمزيد من المعالجة ، وكان السؤال - كيف نفعل ذلك؟

SQL Server والاتصالات الخارجية


أثناء وجود SQL Server ، كانت هناك عدة محاولات لتنظيم الاتصالات خارج قاعدة البيانات ؛ خدمات إعلام خادم SQL (NS) ، التي ظهرت في SQL Server 2000 ، وفي وقت لاحق ، في SQL Server 2005 ، ظهر وسيط خدمة خادم SQL (SSB). لقد وصفتهم في كتابي A First Look at SQL Server 2005 for Developers ، جنبًا إلى جنب مع Bob Boshemen و Dan Sullivan. ظهرت NS في SQL Server 2000 ، كما قلت ، وتمت إعادة تصميمها في الإصدار التجريبي من SQL Server 2005. ومع ذلك ، تم استبعاد NS تمامًا من إصدار SQL Server 2005 الجاهز للبيع (RTM).
ملاحظة: إذا قرأت الكتاب ، ستجد هناك عددًا من الميزات التي لم تكن موجودة في إصدار RTM.
نجا SSB ، وقدمت Microsoft المنشط الخارجي لوسيط الخدمة (EA) في حزمة ميزات SQL Server 2008. يجعل من الممكن من خلال SSB التفاعل خارج قاعدة البيانات المحلية. من الناحية النظرية ، يبدو الأمر جيدًا ، ولكن من الناحية العملية - إنه مرهق ومربك. قمنا ببعض الاختبارات وأدركنا بسرعة أنها لا تفعل ما نحتاجه. بالإضافة إلى ذلك ، لم تعطينا SSB الأداء المطلوب ، لذا كان علينا اختراع شيء آخر.

SQLCLR


ونتيجة لذلك ، اعتمدنا على تقنية SQLCLR. SQLCLR عبارة عن منصة .NET مضمنة في قلب SQL Server ويمكن استخدامها لتنفيذ تعليمات برمجية .NET داخل النواة. نظرًا لأننا ننفذ كود .NET ، فنحن قادرون على القيام بكل شيء تقريبًا كما هو الحال في تطبيق .NET عادي.
ملاحظة: لقد كتبت "تقريبًا" أعلاه ، لأن هناك بالفعل بعض القيود. في هذا السياق ، ليس لهذه القيود أي تأثير تقريبًا على ما سنفعله.
مبدأ تشغيل SQLCLR هو كما يلي: يتم تجميع التعليمات البرمجية في مكتبة dll ، ثم يتم تسجيل هذه المكتبة باستخدام أدوات SQL Server:

بناء التجميع

CREATE ASSEMBLY [RabbitMQ.SqlServer] AUTHORIZATION rmq FROM 'F:\some_path\RabbitMQSqlClr4.dll' WITH PERMISSION_SET = UNSAFE; GO 

مقتطف الشفرة 1: إنشاء تجميع على مسار مطلق

يقوم الكود بتنفيذ الإجراءات التالية:

  • CREATE ASSEMBLY - إنشاء تجميع بالاسم المحدد (بغض النظر عما ينبغي أن يكون).
  • AUTHORIZATION - يشير إلى مالك التجميع. في هذه الحالة ، rmq هو دور SQL Server محدد مسبقًا.
  • FROM - تحديد مكان وجود التجميع الأصلي. في FROM ، يمكنك أيضًا تحديد المسار بتنسيقات ثنائية أو UNC. تستخدم ملفات التثبيت لهذا المشروع تمثيلًا ثنائيًا.
  • WITH PERMISSION_SET - تعيين الأذونات. UNSAFE هو الأقل صرامة ومطلوب في هذه الحالة.

ملاحظة: بغض النظر عن الدور أو تسجيل الدخول المستخدم في بند "المصادقة" ، يجب إنشاء فئة appdomain بنفس الاسم عند تحميل التجميع في المجال. يوصى بفصل التجميعات بأسماء مختلفة من فئات appdomain بحيث عندما يفشل تجميع واحد ، لا يقع الباقي. ومع ذلك ، إذا كانت التجمعات تعتمد على بعضها البعض ، فلا يمكن تقسيمها إلى فئات مختلفة.
عندما يتم إنشاء التجميع ، نقوم بعمل أغلفة طرق .NET فيه:

 CREATE PROCEDURE rmq.pr_clr_PostRabbitMsg @EndpointID int, @Message nvarchar(max) AS EXTERNAL NAME [RabbitMQ.SqlServer].[RabbitMQSqlClr.RabbitMQSqlServer].[pr_clr_PostRabbitMsg]; GO 

مقتطف الشفرة 2: برنامج .NET Method Wrapper

يقوم الكود بتنفيذ الإجراءات التالية:

  • إنشاء إجراء مخزن لـ T-SQL باسم rmq.pr_clr_PostRabbitMsg يأخذ معلمتين ؛ @EndpointID و @Message .
  • بدلاً من نص الإجراء ، يتم استخدام مصدر خارجي يتكون من:
    • تجميع يسمى RabbitMQ.SqlServer ، أي التجميع الذي RabbitMQ.SqlServer أعلاه في مقتطف الشفرة 1 .
    • النوع الكامل (مساحة الاسم RabbitMQSqlClr.RabbitMQSqlServer ): RabbitMQSqlClr.RabbitMQSqlServer
    • الطريقة من مساحة الاسم pr_clr_PostRabbitMsg أعلاه هي: pr_clr_PostRabbitMsg .

عند rmq.pr_clr_PostRabbitMsg pr_clr_PostRabbitMsg سيتم استدعاء الأسلوب pr_clr_PostRabbitMsg .
ملاحظة: عند إنشاء إجراء ، لا يكون اسم التجميع حساسًا لحالة الأحرف ، على عكس الاسم الكامل للنوع والطريقة. ليس من الضروري أن يتطابق اسم الإجراء الذي يتم إنشاؤه مع اسم الطريقة. ومع ذلك ، يجب أن تتطابق أنواع البيانات النهائية للمعلمات.
كما قلت سابقًا ، نحتاج في Derivco إلى إرسال البيانات خارج SQL Server ، لذلك نستخدم SQLCLR و RabbitMQ (RMQ).

Rabbitmq


RMQ هو وسيط رسائل مفتوح المصدر يقوم بتنفيذ بروتوكول وضع الرسائل في قائمة انتظار متقدمة (AMQP) وهو مكتوب في Erlang.

نظرًا لأن RMQ هو وسيط رسائل ، فإن مكتبات عملاء AMQP مطلوبة للاتصال بها. يشير التطبيق إلى مكتبات العملاء ، وبمساعدتهم ، يفتح الاتصال ويرسل الرسائل - على سبيل المثال ، هناك مكالمة من خلال ADO.NET إلى SQL Server. ولكن على عكس ADO.NET ، حيث ، على الأرجح ، يفتح الاتصال في كل مرة تدخل فيها إلى قاعدة البيانات ، هنا يبقى الاتصال مفتوحًا طوال فترة التطبيق.

وبالتالي ، من أجل أن نكون قادرين على التفاعل من قاعدة البيانات مع RabbitMQ ، نحتاج إلى التطبيق ومكتبة عميل .NET لـ RabbitMQ.
ملاحظة: في الجزء التالي من هذه المقالة ، سيتم العثور على أجزاء رمز RabbitMQ ، ولكن بدون تفسيرات تفصيلية لما يقومون به. إذا كنت جديدًا في العمل مع RabbitMQ ، فإنني أقترح إلقاء نظرة على برامج RabbitMQ التعليمية المختلفة لفهم الغرض من الشفرة. يعد البرنامج التعليمي Hello World C # بداية جيدة. أحد الاختلافات بين الكتب المدرسية وأمثلة الكود هي أنه لم يتم التصريح عن المبادلات في الأمثلة. من المفترض أن تكون محددة مسبقًا.

أرنب MQ.SqlServer


RabbitMQ.SqlServer هو تجميع يستخدم مكتبة عميل .NET لـ RabbitMQ ويوفر القدرة على إرسال الرسائل من قاعدة البيانات إلى نقطة نهاية RabbitMQ واحدة أو أكثر (VHosts والمبادلات). يمكن تنزيل / تشفير الكود من مستودعي RabbitMQ-SqlServer على GitHub. يحتوي على مصادر تجميع وملفات تثبيت (أي ليس عليك تجميعها بنفسك).
ملاحظة: هذا مجرد مثال لإظهار كيف يمكن أن يتفاعل SQL Server مع RabbitMQ. هذا ليس منتجًا نهائيًا أو حتى جزءًا منه. إذا كسر هذا الرمز عقلك - فلا تلومني ، لأن هذا مجرد مثال.

وظائف


عندما يتم تحميل التجميع ، أو عندما يتم استدعاء التهيئة بشكل صريح ، أو عندما يتم استدعاؤه بشكل غير مباشر ، في الوقت الذي يتم فيه استدعاء الإجراء المجمع ، يقوم التجميع بتحميل سلسلة الاتصال في قاعدة البيانات المحلية التي تم تثبيتها فيها ، بالإضافة إلى نقاط نهاية RabbitMQ التي يتصل بها:

اتصال

 internal bool InternalConnect() { try { connFactory = new ConnectionFactory(); connFactory.Uri = connString; connFactory.AutomaticRecoveryEnabled = true; connFactory.TopologyRecoveryEnabled = true; RabbitConn = connFactory.CreateConnection(); for (int x = 0; x < channels; x++) { var ch = RabbitConn.CreateModel(); rabbitChannels.Push(ch); } return true; } catch(Exception ex) { return false; } } 

مقتطف الشفرة 3: الاتصال بنقطة النهاية

في نفس الوقت ، يقوم جزء من الاتصال بنقطة النهاية أيضًا بإنشاء IModels على الاتصال ، ويتم استخدامها عند إرسال رسائل (إضافة إلى قائمة الانتظار):

إرسال رسالة

 internal bool Post(string exchange, byte[] msg, string topic) { IModel value = null; int channelTryCount = 0; try { while ((!rabbitChannels.TryPop(out value)) && channelTryCount < 100) { channelTryCount += 1; Thread.Sleep(50); } if (channelTryCount == 100) { var errMsg = $"Channel pool blocked when trying to post message to Exchange: {exchange}."; throw new ApplicationException(errMsg); } value.BasicPublish(exchange, topic, false, null, msg); rabbitChannels.Push(value); return true; } catch (Exception ex) { if (value != null) { _rabbitChannels.Push(value); } throw; } } 

يتم استدعاء طريقة pr_clr_PostRabbitMsg(int endPointId, string msgToPost) طريقة pr_clr_PostRabbitMsg(int endPointId, string msgToPost) ، والتي تم تقديمها كإجراء باستخدام عبارة CREATE PROCEDURE في جزء التعليمات البرمجية 2:

طريقة الاتصال اللاحق

 public static void pr_clr_PostRabbitMsg(int endPointId, string msgToPost) { try { if(endPointId == 0) { throw new ApplicationException("EndpointId cannot be 0"); } if (!isInitialised) { pr_clr_InitialiseRabbitMq(); } var msg = Encoding.UTF8.GetBytes(msgToPost); if (endPointId == -1) { foreach (var rep in remoteEndpoints) { var exch = rep.Value.Exchange; var topic = rep.Value.RoutingKey; foreach (var pub in rabbitPublishers.Values) { pub.Post(exch, msg, topic); } } } else { RabbitPublisher pub; if (rabbitPublishers.TryGetValue(endPointId, out pub)) { pub.Post(remoteEndpoints[endPointId].Exchange, msg, remoteEndpoints[endPointId].RoutingKey); } else { throw new ApplicationException($"EndpointId: {endPointId}, does not exist"); } } } catch { throw; } } 

مقتطف الشفرة 5: تمثيل الطريقة كإجراء

عند تنفيذ الطريقة ، يُفترض أن يرسل المتصل معرفًا لنقطة النهاية التي يجب إرسال الرسالة إليها ، وفي الواقع ، الرسالة نفسها. إذا تم تمرير القيمة -1 كمعرف لنقطة النهاية ، فإننا نكرر كل النقاط ونرسل رسالة إلى كل منها. تأتي الرسالة في شكل سلسلة نحصل منها بايت باستخدام Encoding.UTF8.GetBytes . في بيئة إنتاج ، يجب استبدال استدعاء Encoding.UTF8.GetBytes بالتسلسل.

التثبيت


لتثبيت المثال وتشغيله ، تحتاج إلى جميع الملفات في المجلد src\SQL . للتثبيت ، اتبع الخطوات التالية:

  • قم بتشغيل البرنامج النصي 01.create_database_and_role.sql . سيخلق:
    • قاعدة بيانات اختبار RabbitMQTest حيث سيتم إنشاء التجميع.
    • يتم تعيين دور rmq كمالك تجميع
    • مخطط ، والذي سيطلق عليه أيضًا rmq . في هذا الرسم التخطيطي ، يتم إنشاء كائنات قاعدة بيانات مختلفة.

  • قم بتشغيل الملف 02.create_database_objects.sql . سيخلق:

    • جدول rmq.tb_RabbitSetting الذي سيخزن سلسلة الاتصال بقاعدة البيانات المحلية.
    • جدول rmq.tb_RabbitEndpoint ، حيث سيتم تخزين نقطة نهاية RabbitMQ أو أكثر.

  • في ملف 03.create_localhost_connstring.sql بتغيير قيمة المتغير @connString إلى سلسلة الاتصال الصحيحة RabbitMQTest بيانات RabbitMQTest تم إنشاؤها في الخطوة 1 وقم بتشغيل البرنامج النصي.

قبل المتابعة ، يجب أن يكون لديك نسخة جارية من وسيط RabbitMQ و VHost (بشكل افتراضي ، يتم تمثيل VHost كـ /). كقاعدة عامة ، لدينا العديد من VHost ، فقط للعزلة. يحتاج هذا المضيف أيضًا إلى مبادل ، في المثال الذي نستخدمه amq.topic . عندما يكون وسيط RabbitMQ الخاص بك جاهزًا ، قم بتحرير rmq.pr_UpsertRabbitEndpoint إجراء rmq.pr_UpsertRabbitEndpoint ، الموجودة في ملف 04.upsert_rabbit_endpoint.sql :

أرنب النهاية

 EXEC rmq.pr_UpsertRabbitEndpoint @Alias = 'rabbitEp1', @ServerName = 'RabbitServer', @Port = 5672, @VHost = 'testHost', @LoginName = 'rabbitAdmin', @LoginPassword = 'some_secret_password', @Exchange = 'amq.topic', @RoutingKey = '#', @ConnectionChannels = 5, @IsEnabled = 1 

مقتطف الشفرة 6: إنشاء نقطة نهاية في RabbitMQ

في هذه المرحلة ، حان الوقت لنشر التجميعات. هناك اختلافات في خيارات النشر لإصدارات SQL Server قبل SQL Server 2014 (2005 ، 2008 ، 2008R2 ، 2012) ، ولعام 2014 وما بعده. يكمن الاختلاف في الإصدار المدعوم من CLR. قبل SQL Server 2014 ، كان النظام الأساسي .NET يعمل في الإصدار CLR 2 ، وفي SQL Server 2014 والإصدارات الأحدث ، تم استخدام الإصدار 4.

SQL Server 2005-2012


دعنا نبدأ بإصدارات SQL Server التي تعمل على CLR 2 ، لأنها لها خصائصها الخاصة. نحن بحاجة إلى نشر التجميع الذي تم إنشاؤه ، وفي الوقت نفسه نشر مكتبة .NET عميل RabbitMQ.Client ( RabbitMQ.Client ). من جمعيتنا سنشير إلى مكتبة عميل RabbitMQ. لأن نظرًا لأننا خططنا لاستخدام CLR 2 ، RabbitMQ.Client تجميع RabbitMQ.Client و RabbitMQ.Client استنادًا إلى .NET 3.5. هناك مشاكل.

يتم تجميع أحدث الإصدارات من مكتبة RabbitMQ.Client من أجل بيئة CLR 4 ، لذلك لا يمكن استخدامها في RabbitMQ.Client . تم تجميع أحدث إصدار من مكتبات العميل لـ CLR 2 على .NET 3.4.3. ولكن حتى إذا حاولنا نشر هذا التجميع ، فإننا نتلقى رسالة خطأ:


الشكل 1: نظام System.ServiceModel مفقود

يشير هذا الإصدار من RabbitMQ.Client إلى تجميع ليس جزءًا من SQL Server CLR. هذا تجميع WCF ، وهو أحد القيود في SQLCLR التي ذكرتها أعلاه: هذا التجميع المحدد مخصص لأنواع المهام التي لا يُسمح بتنفيذها في SQL Server. لا تحتوي الإصدارات الأخيرة من RabbitMQ.Client على هذه التبعيات ، لذلك يمكن استخدامها دون أي مشاكل ، باستثناء المتطلبات المزعجة لـ CLR 4. ماذا أفعل؟

كما تعلم ، RabbitMQ مفتوح المصدر ، لكننا مطورين ، أليس كذلك؟ ؛) لذلك دعونا ترجمة! في الإصدار السابق لأحدث الإصدارات (أي الإصدار <3.5.0) من RabbitMQ.Client حذفت الروابط إلى System.ServiceModel RabbitMQ.Client تجميعها. اضطررت إلى تغيير سطرين من التعليمات البرمجية باستخدام وظيفة System.ServiceModel ، ولكن هذه كانت تغييرات طفيفة.

في هذا المثال ، لم أستخدم إصدار العميل 3.4.3 ، لكنني أخذت الإصدار الثابت 3.6.6 وأعيد تجميعه باستخدام .NET 3.5 (CLR 2). كادت تعمل :) ، باستثناء الإصدارات الأحدث من RabbitMQ.Client use Task 'والتي ليست في الأصل جزءًا من .NET 3.5.

لحسن الحظ ، يوجد إصدار System.Threading.dll لـ .NET 3.5 يتضمن Task . لقد قمت بتنزيله ، وقم بإعداد الروابط ، وكل شيء سار! الحيلة الرئيسية هنا هي أنه يجب تثبيت System.Threading.dll مع التجميع.
ملاحظة: مصدر RabbitMQ.Client ، الذي جمعت منه نسخة من NET 3.5 ، موجود في مستودعي على GitHub RabbitMQ Client 3.6.6 .NET 3.5 . يقع ملف dll الثنائي مع System.Threading.dll لـ .NET 3.5 أيضًا في الدليل lib\NET3.5 المستودع (RabbitMQ-SqlServer) .
لتثبيت التجميعات اللازمة ( System.Threading و RabbitMQ.Client و RabbitMQ.SqlServer ) قم بتشغيل البرامج النصية للتثبيت من دليل src\sql بالترتيب التالي:

  1. 05.51.System.Threading.sql2k5-12.sql - النظام
  2. 05.52.RabbitMQ.Client.sql2k5-12.sql - أرنب MQ.Client
  3. 05.53.RabbitMQ.SqlServer.sql2k5-12.sql - أرنب MQ.SqlServer

SQL Server 2014+


في SQL Server 2014 والإصدارات الأحدث ، يتم تجميع التجميع ضمن .NET 4.XX (المثال الخاص بي على 4.5.2) ، ويمكنك الرجوع إلى أي من أحدث إصدارات RabbitMQ.Client ، والتي يمكن الحصول عليها باستخدام NuGet . في المثال الخاص بي ، أستخدم 4.1.1. RabbitMQ.Client ، الموجود أيضًا في دليل lib\NET4 بالمستودع (RabbitMQ-SqlServer) .

للتثبيت ، قم بتشغيل البرامج النصية من دليل src\sql بالترتيب التالي:

  1. 05.141.RabbitMQ.Client.sql2k14+.sql - RabbitMQ.Client
  2. 05.142.RabbitMQ.SqlServer.sql2k14+.sql - أرنب MQ.SqlServer

مغلفة طريقة SQL


لإنشاء الإجراءات التي سيتم استخدامها من التجميع (3.5 أو 4) ، قم بتشغيل البرنامج النصي 06.create_sqlclr_procedures.sql . سيقوم بإنشاء إجراءات T-SQL لثلاث طرق .NET:

  • rmq.pr_clr_InitialiseRabbitMq مكالمات pr_clr_InitialiseRabbitMq . يُستخدم لتحميل وتهيئة مجموعة RabbitMQ.SqlServer.
  • مكالمات pr_clr_ReloadRabbitEndpoints . تحميل نقاط نهاية RabbitMQ المختلفة.
  • مكالمات pr_clr_PostRabbitMsg . تستخدم لإرسال رسائل إلى RabbitMQ.

يقوم البرنامج النصي أيضًا بإنشاء إجراء T-SQL بسيط - rmq.pr_PostRabbitMsg ، والذي ينطبق على rmq.pr_clr_PostRabbitMsg . هذا إجراء مجمّع يعرف ما يجب فعله بالبيانات ، ويعالج الاستثناءات ، وما إلى ذلك. في بيئة الإنتاج ، لدينا العديد من الإجراءات المماثلة التي تعالج أنواعًا مختلفة من الرسائل. اقرأ المزيد عن هذا أدناه.

استخدم


من كل ما سبق ، من الواضح أنه لإرسال رسائل إلى RabbitMQ نسمي rmq.pr_PostRabbitMsg أو rmq.pr_clr_PostRabbitMsg ، لتمرير المعلمات معرف نقطة النهاية والرسالة نفسها كسلسلة. كل هذا ، بالطبع ، رائع ، لكني أود أن أرى كيف ستعمل في الواقع.

ما نقوم به في بيئات الإنتاج هو أنه في الإجراءات المخزنة التي تعالج البيانات التي يجب إرسالها إلى RabbitMQ ، نقوم بجمع البيانات لإرسالها وفي كتلة الاتصال نسميها إجراء مثل rmq.pr_PostRabbitMsg . فيما يلي مثال مبسط للغاية على مثل هذا الإجراء:

إجراء معالجة البيانات

 ALTER PROCEDURE dbo.pr_SomeProcessingStuff @id int AS BEGIN SET NOCOUNT ON; BEGIN TRY --     DECLARE @endPointId int; --    DECLARE @msg nvarchar(max) = '{' --        SET @msg = @msg + '"Id":' + CAST(@id AS varchar(10)) + ',' --  -  SET @msg = @msg + '"FName":"Hello",'; SET @msg = @msg + '"LName":"World"'; SET @msg = @msg + '}'; -- -  --     -,  -  SELECT @endPointId = 1; --    --     EXEC rmq.pr_PostRabbitMsg @Message = @msg, @EndpointID = @endPointId; END TRY BEGIN CATCH DECLARE @errMsg nvarchar(max); DECLARE @errLine int; SELECT @errMsg = ERROR_MESSAGE(), @errLine = ERROR_LINE(); RAISERROR('Error: %s at line: %d', 16, -1, @errMsg, @errLine); END CATCH END 

في جزء الشفرة 7 ، نرى كيف يتم التقاط البيانات اللازمة ومعالجتها في الإجراء وإرسالها بعد المعالجة. لاستخدام هذا الإجراء ، قم بتشغيل البرنامج النصي 07.create_processing_procedure.sql من دليل src\SQL .

دعنا ندير كل شيء


في هذه المرحلة ، يجب أن تكون مستعدًا لإرسال بعض الرسائل. قبل الاختبار ، تأكد من أن لديك قوائم انتظار في RabbitMQ متصلة بمبادل نقطة النهاية في rmq.tb_RabbitEndpoint .

لذا ، للبدء ، عليك القيام بما يلي:
افتح ملف 99.test_send_message.sql .
اركض

 EXEC rmq.pr_clr_InitialiseRabbitMq; 

لتهيئة التجميع وتحميل نقاط نهاية RabbitMQ. هذه ليست خطوة مطلوبة ، ولكن يوصى بتحميل التجميع مسبقًا بعد إنشائه أو تعديله.

اركض

 EXEC dbo.pr_SomeProcessingStuff @id = 101 

(يمكنك استخدام أي معرف آخر تريده).

إذا كان كل شيء يعمل بدون أخطاء ، فيجب أن تظهر رسالة في قائمة انتظار RabbitMQ! لذا استخدمت SQLCLR لإرسال رسالة إلى RabbitMQ.

مبروك!

Source: https://habr.com/ru/post/ar419457/


All Articles