ملخص
عندما كنت أجري مقابلة في Netease ، سألني القائم بإجراء المقابلة سؤالًا وقال
بعد تقديم طلب ، إذا لم يدفع المستخدم ويحتاج إلى إلغاء الطلب ، فما الذي يمكنني فعله؟
كان إجابتي في ذلك الوقت هو استخدام مهمة محددة في توقيت لمسح جدول DB. لم يكن المقابلة راضيا للغاية وسأل:
هل هناك أي طريقة أخرى لاستخدام المهام الموقوتة لتحقيق إشعارات دقيقة في الوقت الفعلي؟
كان إجابتي في ذلك الوقت:
يمكنك استخدام قائمة انتظار. بعد وضع الطلب ، يتم إرسال رسالة إلى قائمة الانتظار ويتم تحديد وقت انتهاء الصلاحية. بمجرد وصول الوقت ، يتم تنفيذ واجهة رد الاتصال.
بعد أن استمع القائم بإجراء المقابلة ، توقف عن السؤال. في الواقع ، كانت فكرتي صحيحة في ذلك الوقت ، لكنني لم أكن محترفًا للغاية. القول المهني هو استخدام الرسائل المتأخرة.
في الواقع ، هناك بالفعل بعض المشكلات في استخدام المهام الموقوتة. يأمل نظام الأعمال الأصلي في أنه إذا لم يتم دفع الطلب في 10 دقائق ، فسيتم إلغاء الطلب على الفور وسيتم إصدار مخزون المنتج. ومع ذلك ، بمجرد أن يكون حجم البيانات كبيرًا ، سيتم تمديد وقت الحصول على بيانات الطلب غير المدفوعة. سيتم إلغاء بعض الطلبات بعد 10 دقائق ، والتي قد تكون 15 دقيقة ، 20 دقيقة ، وما إلى ذلك. وبهذه الطريقة ، لن يتم إصدار المخزون في الوقت المناسب وسيؤثر أيضًا على الرقم الفردي. باستخدام رسائل التأخير ، يمكن تنفيذ عملية إلغاء الطلب نظريًا وفقًا لوقت المحدد.
حاليًا ، فإن معظم المقالات على الإنترنت حول استخدام RabbitMQ لتنفيذ الرسائل المتأخرة تدور حول كيفية استخدام قائمة انتظار الحروف الميتة الخاصة بـ RabbitMQ. يبدو حل التنفيذ معقدًا للغاية ويتم تنفيذه باستخدام واجهة برمجة تطبيقات RabbitMQ Client الأصلية ، والتي هي أكثر مطوّلة.
قام SPRING BOOT بلف واجهة برمجة تطبيقات Client Client RabbitMQ ، وهو أمر أبسط بكثير. فيما يلي مقدمة مفصلة حول كيفية استخدام المكون الإضافي RabbitMQ_Delayed_Message_Exchange لتنفيذ الرسائل المتأخرة.
تحضير البرمجيات
إرلانج
النسخة المستخدمة في هذه المقالة هي: Erlang 20.3
الأرنب
تستخدم هذه المقالة إصدار نافذة RabbitMQ ، رقم الإصدار هو: 3.7.4
rabbitmq_delayed_message_exchange البرنامج المساعد
عنوان تنزيل البرنامج المساعد: http://www.ribbitmq.com/community-plugins.html
بعد فتح عنوان URL ، Ctrl + F والبحث في RabbitMQ_Delayed_Message_Exchange.
تذكر أنه يجب عليك اختيار رقم الإصدار. نظرًا لأنني أستخدم RabbitMQ 3.7.4 ، يجب أيضًا اختيار RabbitMQ_Delayed_Message_Exchange المكون الإضافي 3.7.x.
إذا لم تقم بتحديد الإصدار الصحيح ، فسوف تواجه العديد من المشكلات الغريبة عند استخدام الرسائل المتأخرة ، ولا يوجد حل على الإنترنت. لقد ناضلت طوال الليل بسبب هذه المشكلة. يرجى تذكر تحديد إصدار المكون الإضافي الصحيح.
بعد تنزيل المكون الإضافي ، ضعه في دليل الإضافات ضمن دليل تثبيت RabbitMQ ، وابدأ البرنامج المساعد باستخدام الأمر التالي:
rabbitmq-plugins تمكين rabbitmq_delayed_message_exchange
إذا نجحت بدء التشغيل ، فستظهر الرسالة التالية:
تم تمكين المكونات الإضافية التالية: rabbitmq_delayed_message_exchange
بعد إطلاق المكون الإضافي بنجاح ، تذكر إعادة تشغيل RabbitMQ لجعله مفعولًا.
RabbitMQ متكامل
هذا بسيط للغاية ، فقط أضفه في ملف pom.xml لمشروع Maven
<Rependency> <roupiD> org.springframework.boot </rougiD> <StifactId> Spring-Boot-Starter-AMQP </stifactid> </sependency>
أنا أستخدم 2.0.1.release لإقلاع الربيع.
بعد ذلك ، أضف تكوين redis في ملف Application.Properties:
Spring.RabbitMq.host = 127.0.0.1Spring.RabbitMq.Port = 5672Spring.RabbitMq.Username = GuestSpring.RabbitMQ.Password = Guest
تحديد ConnectionFactory و Rabbittemplate
كما أنه بسيط للغاية ، فإن الكود كما يلي:
package com.mq.ribbitmq ؛ استيراد org.springframework.amqp.ribbit.connection.cachingConnectionFactory ؛ استيراد org.springframework.amqp.ribbit.connection.connectionfactory ؛ import org.springframework.amqp. org.springframework.boot.context.properties.ConfigurationProperties ؛ استيراد org.springframework.context.antation.bean يستضيف؛ منفذ الباحث الخاص ؛ اسم المستخدم الخاص بالسلسلة الخاصة ؛ كلمة مرور السلسلة الخاصة ؛ Bean Public ConnectionFactory ConnectionFactory () {CachingConnectionFactory CachingConnectionFactory = جديد CachingConnectionFactory (مضيف ، منفذ) ؛ CachingConnectionFactory.setUserName (اسم المستخدم) ؛ CachingConnectionFactory.setPassword (كلمة المرور) ؛ CachingConnectionFactory.setVirtualhost ("/") ؛ CachingConnectionFactory.setPublisherConfirms (صواب) ؛ إرجاع CachingConnectionFactory ؛ } bean public rabbittemplate rabbittemplate () {rabbittemplate rabbittemplate = new rabbittemplate (connectionFactory ()) ؛ إرجاع rabbittemplate ؛ } السلسلة العامة gethost () {return host ؛ } public void sethost (سلسلة مضيف) {this.host = host ؛ } public int getPort () {return port ؛ } public void setport (int port) {this.port = port ؛ } السلسلة العامة getUserName () {return username ؛ } public void setusername (string username) {this.userName = username ؛ } السلسلة العامة getPassword () {return password ؛ } public void setPassword (سلسلة كلمة مرور) {this.password = password ؛ }}تكوين التبادل وقائمة الانتظار
حزمة com.mq.RabbitMq ؛ استيراد org.springframework.amqp.core.*؛ استيراد org.springframework.context.antation.bean ؛ import org.springframework.context.annotation.configuration ؛ import java.util.hashmap ؛ QueUeConfig {bean public customexchange delayexchange () {map <string ، object> args = new hashmap <> () ؛ args.put ("x-delayed-type" ، "direct") ؛ إرجاع customexchange الجديد ("test_exchange" ، "x delayed-message" ، صحيح ، خطأ ، args) ؛ } Queue public Queue () {قائمة الانتظار قائمة قائمة الانتظار = قائمة انتظار جديدة ("test_queue_1" ، true) ؛ قائمة الانتظار ؛ } Bean Public Binding Binding () {return bindingbuilder.bind (queue ()). to (delayExchange ()). with ("test_queue_1"). noargs () ؛ }}تجدر الإشارة هنا إلى استخدام Customexchange ، وليس DirectExchange ، ويجب أن يكون نوع customexchange x delayed-message.
تنفيذ إرسال الرسالة
package com.mq.ribbitmq ؛ استيراد org.springframework.amqp.amqpexception ؛ استيراد org.springframework.amqp.core.message ؛ import org.springframework.amqp.core.messagepostprocessor ؛ org.springframework.beans.factory.annotation. public void sendmsg (string queuename ، string msg) {simpledateformat sdf = new SimplEdateFormat ("Yyyy-MM-DD HH: mm: ss") ؛ System.out.println ("Message Send Time:"+sdf.format (New Date ())) ؛ rabbittemplate.convertandsend ("test_exchange" ، QueuEname ، MSG ، New MessagePostProcessor () {Override Public Message PostProcessMessage (رسالة رسالة) يلقي AmqPexception {message.getMessageProperties (). setheader ("x-delay" ، 3000) ؛ }}لاحظ أنه عند الإرسال ، يجب إضافة رأس
x delay
وقت التأخير الذي حددته هنا هو 3 ثوان.
مستهلكي الرسائل
package com.mq.ribbitmq ؛ استيراد org.springframework.amqp.rabbit.annotation.Rabbithandler ؛ استيراد org.springframework.amqp.ribbit.annotation.RabbitListener ؛ استيراد org.springframework.stereophoTeope.component ؛ java.util.date ؛ componentpublic class messagereceiver {rabbitListener (queues = "test_queue_1") استلام الفراغ العام (سلسلة msg) {simpledateformat sdf = new SimpledateFormat ("Yyyyy-mm-dd hh: mm: ss") ؛ System.out.println ("وقت استقبال الرسائل:"+sdf.format (date ())) ؛ System.out.println ("رسالة مستلمة:"+msg) ؛ }}قم بتشغيل برنامج التمهيد الربيعي وأرسل الرسائل
قم بتشغيل برنامج SPRING BOOT مباشرةً في الطريقة الرئيسية ، وسيقوم SPRING BOOT تلقائيًا بتحليل فئة Messagereceiver.
بعد ذلك ، ما عليك سوى استخدام Junit لتشغيل الواجهة التي ترسل الرسالة.
package com.mq.ribbitmq ؛ استيراد org.junit.test ؛ استيراد org.junit.runner.runwith ؛ استيراد org.springframework.beans.factory.annotation.autowired org.springframework.test.context.junit4 test public void send () {messageservice.sendmsg ("test_queue_1" ، "hello i am reghing msg") ؛ }} بعد الجري ، يمكنك رؤية المعلومات التالية:
رسالة إرسال الرسالة: 2018-05-03 12:44:53
بعد 3 ثوان ، ستخرج وحدة تحذية الربيع:
وقت استقبال الرسائل: 2018-05-03 12:44:56
رسالة مستلمة: مرحبًا أنا أؤخر MSG
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.