RabbitMQ ialah sejenis perisian tengah mesej yang melaksanakan AMQP (Advanced Message Qeuing Protocol pada asalnya daripada sistem kewangan dan digunakan untuk menyimpan dan memajukan mesej dalam sistem yang diedarkan). Ia berprestasi baik dari segi kebolehgunaan, kebolehskalaan dan ketersediaan yang tinggi. RabbitMQ dilaksanakan terutamanya untuk mencapai penyahgandingan dua hala antara sistem. Apabila pengeluar menjana sejumlah besar data dan pengguna tidak dapat menggunakannya dengan cepat, lapisan perantaraan diperlukan. Simpan data ini.
AMQP, Protokol Baris Gilir Mesej Lanjutan, ialah standard terbuka untuk protokol lapisan aplikasi dan direka bentuk untuk perisian tengah berorientasikan mesej. Tujuan utama perisian tengah mesej adalah untuk memisahkan komponen supaya penghantar dan penerima mesej tidak mengganggu antara satu sama lain dan bebas antara satu sama lain. Oleh itu, pengirim tidak perlu mengetahui kewujudan pengguna, begitu juga sebaliknya. Ciri-ciri utama AMQP termasuk orientasi mesej, baris gilir, penghalaan (termasuk titik-ke-titik dan terbitkan/langgan), kebolehpercayaan dan keselamatan.
RabbitMQ ialah pelaksanaan AMQP sumber terbuka Pelayan ditulis dalam bahasa Erlang dan menyokong pelbagai klien, seperti: Python, Ruby, .NET, Java, JMS, C, PHP, ActionScript, XMPP, STOMP, dsb. , menyokong AJAX. Teknologi ini menunjukkan kemudahan penggunaan yang baik, skalabiliti dan ketersediaan yang tinggi dalam menyimpan dan memajukan mesej dalam sistem yang diedarkan.
Biasanya apabila kita bercakap tentang perkhidmatan baris gilir, terdapat tiga konsep: penghantar mesej, baris gilir, penerima mesej, RabbitMQ ada di sini Pada bahagian atas konsep asas, lapisan abstraksi tambahan ditambah, dan pertukaran ditambah antara penghantar mesej dan baris gilir Dengan cara ini, tiada sambungan langsung antara penghantar mesej dan baris gilir, dan sebaliknya pengirim mesej itu mesej ke baris gilir, penukar menghantar mesej ke baris gilir mengikut dasar penjadualan
P di sebelah kiri mewakili pengeluar, iaitu program yang menghantar mesej kepada RabbitMQ .
Tengah ialah RabbitMQ, yang merangkumi suis dan baris gilir.
C di sebelah kanan mewakili pengguna, iaitu program yang mendapat mesej daripada RabbitMQ.
Antaranya, terdapat 4 konsep penting iaitu: hos maya, suis, baris gilir, dan mengikat.
Hos Maya: Hos maya memegang satu set suis, baris gilir dan pengikatan. Mengapa anda memerlukan berbilang hos maya? Ia sangat mudah dalam RabbitMQ, pengguna hanya boleh mengawal kebenaran pada butiran hos maya. Oleh itu, jika anda perlu melarang kumpulan A daripada mengakses suis/baris gilir/binding kumpulan B, anda mesti mencipta hos maya untuk A dan B masing-masing. Setiap pelayan RabbitMQ mempunyai hos maya lalai "/".
Tukar: Exchange digunakan untuk memajukan mesej, tetapi ia tidak akan menyimpannya Jika tiada Queue mengikat ke Exchange, ia akan terus membuang mesej yang dihantar oleh maklumat Pengeluar.
Terdapat konsep yang lebih penting di sini: kunci penghalaan. Mengikut kekunci penghalaan, suis memajukan mesej ke baris gilir yang sepadan.
Mengikat: Iaitu, suis perlu terikat pada baris gilir Seperti yang ditunjukkan dalam rajah di atas, ia adalah perhubungan banyak-ke-banyak.
Sangat mudah untuk menyepadukan RabbitMQ dengan SpringBoot Jika anda hanya menggunakannya dengan konfigurasi yang sangat sedikit, springboot menyediakan pelbagai sokongan untuk mesej dalam projek spring-boot-starter-amqp.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
2. Fail konfigurasi
Konfigurasikan alamat pemasangan, port dan maklumat akaun rabbitmq.spring.application.name=spirng-boot-rabbitmq
spring.rabbitmq.host=192.168.0.86
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456
3 konfigurasi
@Configuration public class RabbitConfig { @Bean public Queue Queue() { return new Queue("hello"); } }
rabbitTemplate是springboot 提供的默认实现 public class HelloSender { @Autowired private AmqpTemplate rabbitTemplate; public void send() { String context = "hello " + new Date(); System.out.println("Sender : " + context); this.rabbitTemplate.convertAndSend("hello", context); } }
@Component @RabbitListener(queues = "hello") public class HelloReceiver { @RabbitHandler public void process(String hello) { System.out.println("Receiver : " + hello); } }
Kegunaan banyak-ke-banyakSatu pengirim, N penerima atau Apa akan berlaku dengan N penghantar dan N penerima?
Penghantaran satu-ke-banyak
Pengubahsuaian kecil telah dibuat pada kod di atas penerima mendaftarkan dua Penerima, Penerima1 dan Penerima2 pengiraan parameter dan diterima Bahagian penerima mencetak parameter yang diterima Berikut ialah kod ujian, yang menghantar seratus mesej untuk melihat kesan pelaksanaan dua hujung penerima@RunWith(SpringRunner.class) @SpringBootTest public class RabbitMqHelloTest { @Autowired private HelloSender helloSender; @Test public void hello() throws Exception { helloSender.send(); } }
Hasilnya adalah seperti berikut :
Penerima 1: giliran spirng boot neo ****** 11
Penerima 2: giliran spirng boot neo ****** 12Penerima 2: gilir spirng boot neo ****** 14 Penerima 1: gilir spirng boot neo ****** 13Penerima 2: gilir spirng boot neo ****** 15
Penerima 1 : gilir spirng boot neo ****** 16Penerima 1: gilir spirng boot neo ****** 18Penerima 2: gilir spirng boot neo ****** 17
Penerima 2: giliran spirng boot neo ***** * 19
Penerima 1: giliran spirng boot neo ****** 20
根据返回结果得到以下结论
一个发送者,N个接受者,经过测试会均匀的将消息发送到N个接收者中
多对多发送
复制了一份发送者,加入标记,在一百个循环中相互交替发送
@Test public void manyToMany() throws Exception { for (int i=0;i<100;i++){ neoSender.send(i); neoSender2.send(i); } }
结果如下:
Receiver 1: spirng boot neo queue ****** 20
Receiver 2: spirng boot neo queue ****** 20
Receiver 1: spirng boot neo queue ****** 21
Receiver 2: spirng boot neo queue ****** 21
Receiver 1: spirng boot neo queue ****** 22
Receiver 2: spirng boot neo queue ****** 22
Receiver 1: spirng boot neo queue ****** 23
Receiver 2: spirng boot neo queue ****** 23
Receiver 1: spirng boot neo queue ****** 24
Receiver 2: spirng boot neo queue ****** 24
Receiver 1: spirng boot neo queue ****** 25
Receiver 2: spirng boot neo queue ****** 25
结论:和一对多一样,接收端仍然会均匀接收到消息.
//对象的支持 //springboot以及完美的支持对象的发送和接收,不需要格外的配置。 //发送者 public void send(User user) { System.out.println("Sender object: " + user.toString()); this.rabbitTemplate.convertAndSend("object", user); } ... //接受者 @RabbitHandler public void process(User user) { System.out.println("Receiver object : " + user); }
结果如下:
Sender object: User{name='neo', pass='123456'}
Receiver object : User{name='neo', pass='123456'}
在RabbitMQ中,Topic是最灵活的一种方式,它允许根据routing_key随意绑定到不同的队列
首先对topic规则配置,这里使用两个队列来测试
@Configuration public class TopicRabbitConfig { final static String message = "topic.message"; final static String messages = "topic.messages"; @Bean public Queue queueMessage() { return new Queue(TopicRabbitConfig.message); } @Bean public Queue queueMessages() { return new Queue(TopicRabbitConfig.messages); } @Bean TopicExchange exchange() { return new TopicExchange("exchange"); } @Bean Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) { return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message"); } @Bean Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) { return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#"); } }
使用queueMessages同时匹配两个队列,queueMessage只匹配"topic.message"队列
public void send1() { String context = "hi, i am message 1"; System.out.println("Sender : " + context); this.rabbitTemplate.convertAndSend("exchange", "topic.message", context); } public void send2() { String context = "hi, i am messages 2"; System.out.println("Sender : " + context); this.rabbitTemplate.convertAndSend("exchange", "topic.messages", context); }
发送send1会匹配到topic.#和topic.message 两个Receiver都可以收到消息,发送send2只有topic.#可以匹配所有只有Receiver2监听到消息
Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。
Fanout 相关配置:
@Configuration public class FanoutRabbitConfig { @Bean public Queue AMessage() { return new Queue("fanout.A"); } @Bean public Queue BMessage() { return new Queue("fanout.B"); } @Bean public Queue CMessage() { return new Queue("fanout.C"); } @Bean FanoutExchange fanoutExchange() { return new FanoutExchange("fanoutExchange"); } @Bean Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) { return BindingBuilder.bind(AMessage).to(fanoutExchange); } @Bean Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) { return BindingBuilder.bind(BMessage).to(fanoutExchange); } @Bean Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) { return BindingBuilder.bind(CMessage).to(fanoutExchange); } }
这里使用了A、B、C三个队列绑定到Fanout交换机上面,发送端的routing_key写任何字符都会被忽略:
public void send() { String context = "hi, fanout msg "; System.out.println("Sender : " + context); this.rabbitTemplate.convertAndSend("fanoutExchange","", context); }
结果如下:
Sender : hi, fanout msg
...
fanout Receiver B: hi, fanout msg
fanout Receiver A : hi, fanout msg
fanout Receiver C: hi, fanout msg
结果说明,绑定到fanout交换机上面的队列都收到了消息.
Atas ialah kandungan terperinci Bagaimana SpringBoot menyepadukan RabbitMQ. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!