Ringkasan
Ketika saya wawancara di NetEase, pewawancara mengajukan pertanyaan dan berkata
Setelah melakukan pemesanan, jika pengguna tidak membayar dan perlu membatalkan pesanan, apa yang dapat saya lakukan?
Jawaban saya pada saat itu adalah menggunakan tugas waktu untuk memindai tabel DB. Pewawancara tidak terlalu puas dan bertanya:
Apakah ada cara lain untuk menggunakan tugas waktu untuk mencapai pemberitahuan real-time yang akurat?
Jawaban saya saat itu adalah:
Anda dapat menggunakan antrian. Setelah pesanan ditempatkan, pesan dikirim ke antrian dan waktu kedaluwarsa ditentukan. Setelah waktu tiba, antarmuka callback dieksekusi.
Setelah pewawancara mendengarkan, dia berhenti bertanya. Sebenarnya, ide saya benar pada waktu itu, tetapi saya tidak terlalu profesional. Pepatah profesional adalah menggunakan pesan yang tertunda.
Faktanya, memang ada beberapa masalah dengan menggunakan tugas -tugas waktunya. Sistem bisnis asli berharap bahwa jika pesanan tidak dibayar dalam 10 menit, pesanan akan dibatalkan segera dan inventaris produk akan dirilis. Namun, setelah volume data besar, waktu untuk mendapatkan data pesanan yang belum dibayar akan diperpanjang. Beberapa pesanan akan dibatalkan setelah 10 menit, yang mungkin 15 menit, 20 menit, dll. Dengan cara ini, inventaris tidak akan dirilis tepat waktu dan juga akan mempengaruhi angka ganjil. Menggunakan pesan tunda, operasi pembatalan pesanan dapat secara teoritis dilakukan sesuai dengan waktu yang ditentukan.
Saat ini, sebagian besar artikel di internet tentang menggunakan RabbitMQ untuk mengimplementasikan pesan yang tertunda adalah tentang cara menggunakan antrian surat mati RabbitMQ untuk diimplementasikan. Solusi implementasi terlihat sangat rumit dan diimplementasikan menggunakan API klien RabbitMQ asli, yang bahkan lebih bertele -tele.
Spring Boot telah membungkus API Klien RabbitMQ, yang jauh lebih sederhana untuk digunakan. Berikut adalah pengantar terperinci tentang cara menggunakan plug-in dan boot rabbitmq_delayed_message_exchange dan spring boot untuk menerapkan pesan yang tertunda.
Persiapan Perangkat Lunak
Erlang
Versi yang digunakan dalam artikel ini adalah: Erlang 20.3
Rabbitmq
Artikel ini menggunakan versi jendela RabbitMQ, nomor versi adalah: 3.7.4
Plugin RabbitMQ_Delayed_Message_Exchange
Alamat unduhan plugin: http://www.rabbitmq.com/community-plugins.html
Setelah membuka URL, Ctrl + F dan cari RabbitMQ_Delayed_Message_Exchange.
Ingat, Anda harus memilih nomor versi. Karena saya menggunakan RabbitMQ 3.7.4, plug-in RabbitMQ_Delayed_Message_Exchange yang sesuai juga harus memilih 3.7.x.
Jika Anda tidak memilih versi yang tepat, Anda akan menghadapi berbagai masalah aneh saat menggunakan pesan yang tertunda, dan tidak ada solusi di Internet. Saya berjuang sepanjang malam karena masalah ini. Harap ingat untuk memilih versi plug-in yang tepat.
Setelah mengunduh plugin, letakkan di direktori plugin di bawah direktori instalasi RabbitMQ, dan mulai plugin menggunakan perintah berikut:
RabbitMQ-Plugins mengaktifkan rabbitmq_delayed_message_exchange
Jika startup berhasil, pesan berikut akan muncul:
Plugin berikut telah diaktifkan: Rabbitmq_Delayed_Message_exchange
Setelah plug-in berhasil diluncurkan, ingatlah untuk memulai kembali RabbitMQ agar berlaku.
RabbitMQ terintegrasi
Ini sangat sederhana, cukup tambahkan dalam file pom.xml dari proyek maven
<dependency> <GroupId> org.springframework.boot </groupId> <ArTifactId> Spring-boot-starter-AMQP </RiTtifacTID> </dependency>
Saya menggunakan 2.0.1.release untuk Spring Boot.
Selanjutnya, tambahkan konfigurasi redis di file application.properties:
spring.rabbitmq.host = 127.0.0.1spring.rabbitmq.port = 5672spring.rabbitmq.username = wamagepring.rabbitmq.password = tamu
Tentukan ConnectionFactory dan Rabbittemplate
Ini juga sangat sederhana, kodenya adalah sebagai berikut:
Paket com.mq.rabbitmq; impor org.springframework.amqp.rabbit.connection.cachingConnectionFactory; impor org.springframework.amqp.rabbit.connection.connectionFactory; impor org.springframework.ampbit.rabbit.core. org.springframework.boot.context.properties.configurationproperties; impor org.springframework.context.annotation.bean; impor org.springframework.context.annotation.configuration;@configuration@configuration@configuration rabbitpramework (prefix = "spring. port int pribadi; nama pengguna string pribadi; kata sandi string pribadi; @Bean ConnectionFactory ConnectionFactory () {CachingConnectionFactory CachingConnectionFactory = CachingConnectionFactory baru (host, port); CachingConnectionFactory.setusername (nama pengguna); CachingConnectionFactory.SetPassword (kata sandi); CachingConnectionFactory.SetVirtualHost ("/"); CachingConnectionFactory.SetPublisherConfirms (true); mengembalikan CachingConnectionFactory; } @Bean Public Rabbittemplate Rabbittemplate () {Rabbittemplate rabbittemplate = rabbittemplate baru (ConnectionFactory ()); Return Rabbittemplate; } public String getHost () {return host; } public void setHost (string host) {this.host = host; } public int getport () {port return; } public void setport (int port) {this.port = port; } public string getUserName () {return username; } public void setusername (string username) {this.username = username; } public string getPassword () {return kata sandi; } public void setPassword (kata sandi string) {this.password = kata sandi; }}Konfigurasi Pertukaran dan Antrian
Paket com.mq.rabbitmq; impor org.springframework.amqp.core.*; impor org.springframework.context.annotation.bean; impor org.springframework.context.annotation.configuration; impor java.util.HashMapap; {@Bean public customexchange delayexchange () {peta <string, object> args = new HashMap <> (); args.put ("X-Delayed-Type", "Direct"); kembalikan customexchange baru ("test_exchange", "x-delayed-message", true, false, args); } @Bean Queue Queue () {antrian antrian = antrian baru ("test_queue_1", true); Kembalikan antrian; } @Bean pengikatan pengikat publik () {return bindingBuilder.bind (queue ()). To (delayexchange ()). Dengan ("test_queue_1"). Noargs (); }}Perlu dicatat di sini bahwa CustomExchange digunakan, bukan DirectExchange, dan jenis CustomExchange harus berupa pesan X-Delayed.
Menerapkan pengiriman pesan
Paket com.mq.rabbitmq; impor org.springframework.amqp.amqpException; impor org.springframework.amqp.core.message; impor org.springframework.amqp.core.messagePostoror; impor org.spramework.amqp.core org.springframework.beans.factory.annotation.Autowired; impor org.springframework.stereotype.service; impor java.text.simpledateFormat; public void sendMSG (string queuename, string msg) {SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-mm-dd hh: mm: ss"); System.out.println ("Pesan Kirim Waktu:"+sdf.format (tanggal baru ())); rabbittemplate.convertandsend ("test_exchange", queuename, msg, messagePostProcessor () {@Override Pesan POSPROCESSMESSage (pesan pesan) melempar amqpexception {message.getMessageProPerties (). setHeader ("X-DELADER (", 3000; }}Perhatikan bahwa saat mengirim, header harus ditambahkan
X-DELAY
Waktu tunda yang saya setel di sini adalah 3 detik.
Pesan konsumen
Paket com.mq.rabbitmq; impor org.springframework.amqp.rabbit.annotation.rabbithandler; impor org.springframework.amqp.rabbit.annotation.rabbitlistener; impor org.springframework.stereotipe. java.util.date; @ComponentPublic kelas messagereceiver {@rabbitListener (queuees = "test_queue_1") void public recequ (string msg) {SimpleDateFormat sdf = new SimpledateFormat ("yyyy-mm-dd hh: mm: ss"); System.out.println ("Waktu Penerimaan Pesan:"+sdf.format (tanggal baru ())); System.out.println ("Pesan Diterima:"+MSG); }}Jalankan program boot musim semi dan kirim pesan
Jalankan program Spring Boot secara langsung dalam metode utama, dan Spring Boot akan secara otomatis menguraikan kelas Messagereceiver.
Selanjutnya, cukup gunakan JUnit untuk menjalankan antarmuka yang mengirim pesan.
Paket com.mq.rabbitmq; impor org.junit.test; impor org.junit.runner.runwith; impor org.springframework.beans.factory.annotation.Autowired; impor org.springframework.boot.test.context.springboottest; org.springframework.test.context.junit4.springrunner; @runwith (springrunner.class) @springboottestpublic kelas rabbitmqapplicationTests {@Autowired private messagesserviceImpl; @Test public void send () {messeservice.sendmsg ("test_queue_1", "halo saya tunda msg"); }} Setelah berjalan, Anda dapat melihat informasi berikut:
Pesan Pengiriman Waktu: 2018-05-03 12:44:53
Setelah 3 detik, konsol boot musim semi akan menghasilkan:
Waktu Penerimaan Pesan: 2018-05-03 12:44:56
Pesan yang Diterima: Halo, saya menunda msg
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.