ภาพรวม
เมื่อฉันสัมภาษณ์ที่ NetEase ผู้สัมภาษณ์ถามฉันและพูดว่า
หลังจากทำการสั่งซื้อหากผู้ใช้ไม่จ่ายเงินและต้องการยกเลิกคำสั่งซื้อฉันจะทำอะไรได้บ้าง?
คำตอบของฉันในเวลานั้นคือการใช้งานที่กำหนดเวลาเพื่อสแกนตาราง DB ผู้สัมภาษณ์ไม่พอใจมากและถาม:
มีวิธีอื่นในการใช้งานที่กำหนดเวลาเพื่อให้ได้การแจ้งเตือนแบบเรียลไทม์ที่ถูกต้องหรือไม่?
คำตอบของฉันในเวลานั้นคือ:
คุณสามารถใช้คิว หลังจากวางคำสั่งซื้อข้อความจะถูกส่งไปยังคิวและระบุเวลาหมดอายุ เมื่อเวลามาถึงอินเทอร์เฟซการโทรกลับจะถูกดำเนินการ
หลังจากผู้สัมภาษณ์ฟังเขาหยุดถาม ที่จริงแล้วความคิดของฉันถูกต้องในเวลานั้น แต่ฉันไม่ได้เป็นมืออาชีพมาก การพูดอย่างมืออาชีพคือการใช้ข้อความล่าช้า
ในความเป็นจริงมีปัญหาบางอย่างกับการใช้งานที่กำหนดเวลา ระบบธุรกิจดั้งเดิมหวังว่าหากไม่ชำระคำสั่งซื้อใน 10 นาทีคำสั่งซื้อจะถูกยกเลิกทันทีและสินค้าคงคลังผลิตภัณฑ์จะถูกปล่อยออกมา อย่างไรก็ตามเมื่อปริมาณข้อมูลมีขนาดใหญ่เวลาในการรับข้อมูลคำสั่งซื้อที่ค้างชำระจะถูกขยาย คำสั่งซื้อบางอย่างจะถูกยกเลิกหลังจาก 10 นาทีซึ่งอาจเป็น 15 นาที 20 นาที ฯลฯ ด้วยวิธีนี้สินค้าคงคลังจะไม่ถูกปล่อยออกมาในเวลาและจะส่งผลกระทบต่อจำนวนคี่ การใช้ข้อความล่าช้าการดำเนินการยกเลิกคำสั่งซื้อสามารถดำเนินการในทางทฤษฎีตามเวลาที่กำหนด
ปัจจุบันบทความส่วนใหญ่บนอินเทอร์เน็ตเกี่ยวกับการใช้ RabbitMQ เพื่อใช้ข้อความล่าช้าเกี่ยวกับวิธีการใช้คิวจดหมายตายของ RabbitMQ เพื่อนำไปใช้ โซลูชันการใช้งานดูซับซ้อนมากและนำไปใช้โดยใช้ API ไคลเอนต์ RabbitMQ ดั้งเดิมซึ่งเป็นคำอื่นที่ยิ่งใหญ่กว่า
Spring Boot ได้ห่อ API ไคลเอนต์ RabbitMQ ซึ่งใช้งานง่ายกว่ามาก นี่คือการแนะนำรายละเอียดเกี่ยวกับวิธีการใช้ RabbitMQ_Delayed_Message_Exchange ปลั๊กอินและสปริงบูตเพื่อใช้ข้อความล่าช้า
การเตรียมซอฟต์แวร์
Erlang
เวอร์ชันที่ใช้ในบทความนี้คือ: Erlang 20.3
RabbitMQ
บทความนี้ใช้เวอร์ชันหน้าต่างของ RabbitMq หมายเลขเวอร์ชันคือ: 3.7.4
rabbitmq_delayed_message_exchange ปลั๊กอิน
ปลั๊กอินดาวน์โหลดที่อยู่: http://www.rabbitmq.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
<การพึ่งพา> <roupId> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter-AMQP </artifactId>
ฉันใช้ 2.0.1 รีลีสสำหรับการบูตฤดูใบไม้ผลิ
ถัดไปเพิ่มการกำหนดค่า REDIS ในไฟล์ Application.properties:
Spring.rabbitmq.host = 127.0.0.1spring.rabbitmq.port = 5672spring.rabbitmq.username = guestspring.rabbitmq.password = แขก
กำหนด connectionfactory และ rabbittemplate
นอกจากนี้ยังง่ายมากรหัสมีดังนี้:
แพ็คเกจ com.mq.rabbitmq; นำเข้า org.springframework.amqp.rabbit.connection.cachingconnectionfactory; นำเข้า org.springframework.amqp.rabbit.connection.connectionfactory; org.springframework.boot.context.properties.configurationProperties; นำเข้า org.springframework.context.annotation.bean; นำเข้า org.springframework.context.annotation.configuration; พอร์ต int ส่วนตัว; ชื่อผู้ใช้สตริงส่วนตัว; รหัสผ่านสตริงส่วนตัว @Bean Public ConnectionFactory ConnectionFactory () {CachingConnectionFactory CachingConnectionFactory = ใหม่ CachingConnectionFactory (โฮสต์, พอร์ต); CACHINGCONNECTIONFACTORY.SETUNSERNAME (ชื่อผู้ใช้); CachingConnectionFactory.SetPassword (รหัสผ่าน); CachingConnectionFactory.SetVirtualHost ("/"); CachingConnectionFactory.SetPublisherConfirms (จริง); ส่งคืนแคชคอนเน็คชั่นแฟคตอรี; } @Bean สาธารณะ Rabbittemplate Rabbittemplate () {Rabbittemplate Rabbittemplate = ใหม่ Rabbittemplate (ConnectionFactory ()); ส่งคืน Rabbittemplate; } สตริงสาธารณะ gethost () {return host; } โมฆะสาธารณะ sethost (โฮสต์สตริง) {this.host = โฮสต์; } public int getPort () {port return; } โมฆะสาธารณะ setport (พอร์ต int) {this.port = พอร์ต; } สตริงสาธารณะ getUserName () {ส่งคืนชื่อผู้ใช้; } โมฆะสาธารณะ setUserName (ชื่อผู้ใช้สตริง) {this.userName = ชื่อผู้ใช้; } สตริงสาธารณะ getPassword () {ส่งคืนรหัสผ่าน; } โมฆะสาธารณะ setPassword (รหัสผ่านสตริง) {this.password = รหัสผ่าน; -การแลกเปลี่ยนและการกำหนดค่าคิว
แพ็คเกจ com.mq.rabbitmq; นำเข้า org.springframework.amqp.core.*; นำเข้า org.springframework.context.annotation.bean; นำเข้า org.springframework.context.annotation.configuration; queUeconfig {@Bean Public CustomexChange DelayExChange () {MAP <String, Object> args = new HashMap <> (); args.put ("X-delayed-type", "Direct"); ส่งคืน customexchange ใหม่ ("test_exchange", "x-delayed-message", true, false, args); } @Bean คิวสาธารณะสาธารณะ () {คิวคิว = คิวใหม่ ("test_queue_1", จริง); กลับคิว; } @Bean การเชื่อมโยงสาธารณะ () {return bindingBuilder.bind (queue ()). ถึง (delayExchange ()) ด้วย ("test_queue_1"). noargs (); -ควรสังเกตที่นี่ว่ามีการใช้ customexchange ไม่ใช่ DirectExchange และประเภทของ customexchange จะต้องเป็นข้อความ x-delayed
ใช้การส่งข้อความ
แพ็คเกจ com.mq.rabbitmq; นำเข้า org.springframework.amqp.amqpexception; นำเข้า org.springframework.amqp.core.message; นำเข้า org.springframework.amqp.core.messagepostprocessor; org.springframwork org.springframework.beans.factory.annotation.autowired; นำเข้า org.springframework.stereotype.service; นำเข้า java.text.simpledateFormat; นำเข้า Java.util.date; @ServicePublic โมฆะสาธารณะ sendmsg (queuename สตริง, สตริง msg) {simpledateFormat sdf = ใหม่ simpledateFormat ("yyyy-mm-dd hh: mm: ss"); System.out.println ("เวลาส่งข้อความ:"+sdf.format (วันที่ใหม่ ())); rabbittemplate.convertandsend ("test_exchange", queuename, msg, messagepostprocessor ใหม่ () {@override ข้อความสาธารณะ PostprocessMessage (ข้อความข้อความ) โยน amqpexception {message.getMessageProperties () Setheader ("X-Delay", 3000); -โปรดทราบว่าเมื่อส่งจะต้องเพิ่มส่วนหัว
X-delay
เวลาล่าช้าที่ฉันตั้งไว้ที่นี่คือ 3 วินาที
ผู้บริโภคข้อความ
แพ็คเกจ com.mq.rabbitmq; นำเข้า org.springframework.amqp.rabbit.annotation.rabbithandler; นำเข้า org.springframework.amqp.rabbit.annotation.rabbitlistener; นำเข้า org.springframework.stereotype. java.util.date; @componentpublic คลาส messagereceiver {@rabbitlistener (queues = "test_queue_1") โมฆะสาธารณะได้รับ (ผงชูรสสตริง) {simpledateFormat SDF = ใหม่ SimpleDateFormat System.out.println ("เวลารับข้อความ:"+sdf.format (วันที่ใหม่ ())); System.out.println ("ข้อความที่ได้รับ:"+msg); -รันโปรแกรม Boot Spring และส่งข้อความ
เรียกใช้โปรแกรมสปริงบูตโดยตรงในวิธีการหลักและสปริงบูตจะแยกวิเคราะห์คลาส Messagereceiver โดยอัตโนมัติ
ถัดไปใช้ Junit เพื่อเรียกใช้อินเทอร์เฟซที่ส่งข้อความ
แพ็คเกจ com.mq.rabbitmq; นำเข้า org.junit.test; นำเข้า org.junit.runner.runwith; นำเข้า org.springframework.beans.factory.annotation.autowired; นำเข้า org.springframework.test.test.context.springbootest; org.springframework.test.context.junit4.springrunner; @runwith (springrunner.class) @springboottestpublic คลาส rabbitmqapplicationtests {@autowired ข้อความส่วนตัว @Test โมฆะสาธารณะส่ง () {MessagesERVICE.SENDMSG ("TEST_QUEUE_1", "Hello I AM DELAY MSG"); - หลังจากทำงานแล้วคุณสามารถดูข้อมูลต่อไปนี้:
เวลาส่งข้อความ: 2018-05-03 12:44:53
หลังจาก 3 วินาทีคอนโซลการบูตสปริงจะส่งออก:
เวลารับข้อความ: 2018-05-03 12:44:56
ข้อความที่ได้รับ: สวัสดีฉันล่าช้าข้อความ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น