
تُستخدم قوائم انتظار الرسائل لتنفيذ: العمليات المعلقة ، وتفاعل الخدمات فيما بينها ، "معالجة الدُفعات" ، إلخ. توجد حلول متخصصة لتنظيم قوائم الانتظار هذه ، مثل: RabbitMQ و ActiveMQ و ZeroMQ ، وما إلى ذلك ، ولكن غالبًا ما يحدث أنها ليست في أمس الحاجة إليها ، وأن تركيبها ودعمها سوف يتسببان في المزيد من الألم والمعاناة أكثر مما يجلب فوائد. لنفترض أن لديك خدمة عند التسجيل الذي يتم فيه إرسال بريد إلكتروني إلى المستخدم للتأكيد ، وإذا كنت تستخدم Postgres ، فأنت محظوظ - في Postgres ، خارج الصندوق تقريبًا ، هناك امتداد PgQ الذي سيقوم بجميع الأعمال القذرة نيابة عنك.
في هذه المقالة ، سأتحدث عن قائمة انتظار الرسائل (المهام) في PostgreSQL باستخدام ملحق PgQ. ستكون هذه المقالة مفيدة إذا لم تستخدم PgQ أو تستخدم قوائم انتظار مكتوبة ذاتيًا أعلى Postgres.
لماذا تحتاج إلى PgQ على الإطلاق ، إذا كان يمكنك فقط إنشاء جهاز لوحي وكتابة المهام هناك؟ قد يبدو ذلك ممكنًا ، لكن سيتعين عليك مراعاة الوصول المتوازي إلى المهام ، والأخطاء المحتملة (ماذا سيحدث إذا سقطت عملية معالجة المهمة؟) ، بالإضافة إلى الأداء (PgQ سريع للغاية ، والحلول المكتوبة ذاتياً ليست كذلك ، خاصةً إذا كانت المعاملة قيد التنفيذ) لا تغلق قاعدة البيانات أثناء التنفيذ الكامل للمهمة) ، ولكن السبب الأكثر أهمية في رأيي أنه من الضروري استخدام PgQ هو أن PgQ مكتوب بالفعل ويعمل وأن الحل المكتوب ذاتيًا لا يزال بحاجة إلى كتابته (UPD: حول سبب عدم جدوى استخدام قوائم الانتظار المكتوبة ذاتيًا ، يمكنك أن تقرأ ، على سبيل المثال ،
هنا ).
(UPD: نظرًا لأن PgQ يعمل على أعلى مستويات Postgres ، يمكن استخدام كل فرحة المعاملات فيه أيضًا)
لكن PgQ لديه ناقص واحد ضخم - عدم وجود وثائق ، وأنا أحاول التعويض عن هذا القصور مع هذه المقالة.
جهاز
يتكون PgQ من أجزاء (على الأقل 2): 1 - ملحق pgq لل postgres ، 2 - البرنامج الخفي pgqd (حول تثبيتهما لاحقًا).
ويتم كل التفاعل مع قائمة الانتظار باستخدام وظائف داخل بوستجرس.
على سبيل المثال ، لإنشاء قائمة انتظار ، يجب تشغيل
select * from pgq.create_queue({ } text);
بعد إنشاء قائمة الانتظار ، يمكنك إضافة رسائل إليها.
select * from pgq.insert_event({ } text, { } text, { } text);
نحن الآن بحاجة لمعرفة كيفية تلقي الرسائل المسجلة. لهذا ، هناك كيان مثل "المستهلك" (سأكتب مستهلك) ، والذي لا يستقبل الرسائل (الأحداث) ، ولكن "الدُفعات" (الدُفعة). Bach عبارة عن مجموعة من الرسائل المتتالية ، يتم إنشاء bach باستخدام pgqd. بشكل دوري (المعلمة "ticker_period" في ملف التكوين) تأخذ pgqd جميع الرسائل المتراكمة وتكتب إلى ملف تعريف جديد.
من المهم إذا لم يعمل pgqd ، فلن يتم إنشاء bach جديدة ، مما يعني أن المستهلكين ليس لديهم ما يقرؤونه ، وأيضًا إذا لم يعمل pgqd لفترة طويلة وبعد ذلك قيد التشغيل ، فسوف يخلق bach كبيرة واحدة من الرسائل المتراكمة خلال هذا الوقت ، وبالتالي لا ينبغي أن يكون pgqd فقط قم بإيقاف تشغيله.
تسجيل مستهلك (
مهم! سيتلقى المستهلك أحداثًا مسجلة فقط
بعد تسجيله ، لذلك يجب عليك أولاً إنشاء مستهلك ، وعندها فقط كتابة الأحداث):
select * from pgq.register_consumer({ } text, { } text);
(على غرار pgq.unregister_consumer)سيتلقى كل مستهلك
كل الأحداث التي حدثت بعد إنشائه (حتى يتم معالجتها من قبل مستهلك آخر) ، مما يعني أنك على الأرجح تحتاج إلى مستهلك واحد فقط لمرة واحدة. بعد ذلك ، سأخبرك عن كيفية تقسيم الحمل على عدة خوادم.
للحصول على bach ، تحتاج أولاً إلى معرفة معرّفها:
select * from pgq.next_batch({ } text, { } text);
يمكن أن تقوم الدالة بإرجاع NULL إذا قام المستهلك بمعالجة جميع bachs. في هذه الحالة ، عليك فقط الانتظار حتى تقوم pgqd بإنشاء ملف تعريف جديد.
في هذه الحالة ، على الرغم من عدم معالجة bach ، فإن هذه الوظيفة تُرجع نفس القيمة.
يمكنك الحصول على جميع الأحداث في المجموعة باستخدام:
select * from pgq.get_batch_events({id } bigint);
(قد يكون الصندوق فارغًا.)
إذا حدث خطأ أثناء معالجة أحدهم ، يمكنك محاولة معالجة هذا الحدث لاحقًا:
select * from pgq.event_retry({id } bigint, {id } bigint, { } integer);
للإبلاغ عن نهاية باخ وإتاحة الفرصة لبدء واحدة جديدة ، يتم استخدامه
select * from pgq.finish_batch({id } bigint);
بالطبع ، هذه ليست جميع الوظائف في الملحق ، أوصي بقراءة
pgq.imtqy.com/extension/pgq/files/external-sql.html و
github.com/pgq/pgq/tree/master/functions (يحتوي كل ملف على تعريف ووصف وظيفة المقابلة).
تقاسم الحمل
من أجل التعامل مع الأحداث في وقت واحد من قبل العديد من معالجات ، هناك امتداد pgq_coop ، الذي يعمل مثل pgq ويضيف كيان جديد يسمى "المستهلك الفرعي" ، والتي سوف تتلقى جميع الأحداث من لحظة تسجيل المستهلك الأم ، بطبيعة الحال ، باستثناء تلك التي تمت معالجتها بالفعل.
select * from pgq_coop.register_subconsumer({ } text, { } text, { } text);
select * from pgq_coop.next_batch({ } text, { } text, { } text);
select * from pgq_coop.next_batch({ } text, { } text, { } text, { , } interval);
select * from pgq_coop.finish_batch({id } bigint);
اقرأ عن جميع الميزات
هنا .
تركيب
يتم تضمين امتداد pgq و daque pgqd في مستودعات PGDG ويتم تثبيتهما ببساطة شديدة في معظم التوزيعات ، على سبيل المثال ، في دبيان:
sudo apt install postgresql-XX-pgq3 pgqd
(XX هو رقم الإصدار).
pgqd هو برنامج صغير يمكن العثور عليه حول استخدام
pgqd --help
، ولا تنسَ إضافته إلى التشغيل التلقائي (
sudo systemctl enable pgqd.service
،
sudo systemctl enable pgqd.service
الافتراضية هي
/etc/pgqd.ini
).
لبدء استخدام PgQ ، في قاعدة البيانات تحتاج فقط إلى الاتصال بالملحق:
create extension if not exists pgq;
مع pgq_coop ، كل شيء أكثر تعقيدًا قليلاً ، ليس في المستودع ، لكن ليس من الصعب تجميعه من المصادر (مثال لديبيان):
sudo apt install postgresql-server-dev-XX git clone https://github.com/pgq/pgq-coop.git cd pgq-coop sudo make install
وربط التمديد باستخدام
create extension if not exists pgq_coop;
روابط مفيدة
وثائق Pgqوظائف Pgqوظائف Pgq_coopشفرة المصدر Pgqdحساب جيثب مع جميع المشاريع ذات الصلةويكي بوستجرس