In front of me, there was a blog about the RABBITMQ to implement a watch function similar to ZK, but that blog did not have a code instance, and later made a demo to make it easier to understand. The demo mainly uses the spring boot configuration method,
First, the consumer (ie Watcher) configuration
Configuration is configured with spring annotations
1. Create a connection
@Bean Public connectionfactory createconnectionfactory () { new cachingconnectionfactory ();
Set the IP and Port connectionfactory.setaddresses ("127.0.0.1") of the RABBITMQ; Connectionfactory.setport (5672); Connectionfactory.setvirtualhost ("/"); Connectionfactory.setpublisherconfirms (true); return connectionfactory; }
2. Create a switch
@Bean public Exchange fanoutexchange () { returnnew Fanoutexchange ("Ex_rabbit_test"); }
Create a switch named Ex_rabbit_test, the type of the switch is broadcast type (in order to enable broadcast of the message)
3. Create the queue and bind to the switch
@Bean public Queue queueone () { returnnewfalse false true ); } @Bean public Binding bindingone (Queue queueone, Fanoutexchange fanoutexchange) { return bindingbuilder.bind (Queueone) to (Fanoutexchange); }
Each consumer has its own queue, consuming only the messages of his own queue; after binding the queue and the switch, the Exchange will place the message from the producer in all the bound queues, but only in broadcast mode, and the other modes will route messages according to certain routing rules. For example, a topic type of switch will route messages according to Routingkey.
Note: In broadcast mode, in order to implement message listening, each consumer needs to start a queue, and the queue name is not the same, for example, there is now another consumer:
@Bean public Queue queuetwo () { returnnewfalse false true ); } @Bean public Binding bingdingtwo (Queue queuetwo, Fanoutexchange fanoutexchange) { return bindingbuilder.bind (queuetwo) to (Fanoutexchange); }
As a result, when the producer sends the message to the switch ex_rabbit_test, the switch sends the message to the Queue_one and Queue_two two queues, and two consumers consume two queue messages respectively.
4. Consumer News
@Bean PublicSimplemessagelistenercontainer Execmessagecontainerone () {
Set listener "container" Simplemessagelistenercontainer container=NewSimplemessagelistenercontainer (Createconnectionfactory ());
Set queue name Container.setqueuenames ("Queue_one");
Sets the number of listeners, that is, the number of consuming threads container.setconcurrentconsumers (1); Container.setmessagelistener ((Channelawaremessagelistener) (message, channel)- { byte[] BODY =Message.getbody (); if(NULL!=body) { Try{String msg=NewString (body); String usr= "Consumer One"; Consumerservice.doprocess (usr, msg);//Consumer message}Catch(Exception e) {e.printstacktrace (); } } }); returncontainer; } @Bean PublicSimplemessagelistenercontainer Execmessagecontainertwo () {Simplemessagelistenercontainer container=NewSimplemessagelistenercontainer (Createconnectionfactory ()); Container.setqueuenames ("Queue_two"); Container.setconcurrentconsumers (1); Container.setmessagelistener ((Channelawaremessagelistener) (message, channel)-{ byte[] BODY =Message.getbody (); if(NULL!=body) { Try{String msg=NewString (body); String usr= "Consumer"; Consumerservice.doprocess (usr, msg);//Consumer message}Catch(Exception e) {e.printstacktrace (); } } }); returncontainer; }
Consumerservice provides services for consuming messages, perform the following methods
Public void doprocess (string usr, string msg) { + "Receive message from Producer:" + msg); }
Second, the producer configuration
1, the same way as consumers to establish the RABBITMQ connection
2. Set the switch in the same way as the consumer, the switch name is also ex_rabbit_test (if the switch is already present in the RABBITMQ, it can not be created)
3, as to whether to establish a queue and bind the queue to the switch, my understanding is this:
If you build a queue in the producer's code and bind it to the switch, you must establish all of the consumer's queues and bind all the queues to the switch, and if you do, you can omit this configuration from the consumer. In fact, it is a bit of a loss to do so, and I do not agree to do so, just to show that doing so can also be achieved.
4. Create rabbit template (org.springframework.amqp.rabbit.core.RabbitTemplate)
@Bean public rabbittemplate rabbittemplateproducer () { new Rabbittemplate (this. Createconnectionfactory ()); Rabbittemplate.setexchange ("ex_rabbit_test"); return rabbittemplate; }
5. Implement message sending
The demo uses the spring Web to initiate message sending, and the following is the code for the Controller and service
@Controller @requestmapping (value = "/index" ) public Class Producercontroller {@Autowired Private Producerservice Producerservice; @RequestMapping (Value = "/send" public string sendmsg (@RequestParam string msg) {producerservice.send (msg); return "Success" ; }}
@Service Public class Producerservice { = "Rabbittemplateproducer") private rabbittemplate rabbittemplate; Public void Send (String msg) { = "Hello, consumer. Sending: "+ msg; Rabbittemplate.convertandsend (message);} }
Three, pom file
In consumer, you only need to introduce spring AMPQ dependencies.
<Dependencies> <Dependency> <groupId>Org.springframework.boot</groupId> <Artifactid>Spring-boot-starter-amqp</Artifactid> <version>1.5.3.RELEASE</version> </Dependency> </Dependencies>
Spring AMPQ dependencies need to be introduced in Prudocer, and because Web projects are started, it is necessary to rely on spring web
<Dependencies> <Dependency> <groupId>Org.springframework.boot</groupId> <Artifactid>Spring-boot-starter-amqp</Artifactid> <version>1.5.3.RELEASE</version> </Dependency> <Dependency> <groupId>Org.springframework.boot</groupId> <Artifactid>Spring-boot-starter-web</Artifactid> <version>1.5.3.RELEASE</version> </Dependency> </Dependencies>
Iv. startup projects and test results
Use spring boot to start your project quickly, first, start producer on Port 8882, and then start consumer. Through the access address defined in the controller Http://localhost:8882/index/send?msg=hello everybody (where msg must have, because @requestparam annotations), You can see that two consumers are consuming this message.
Consumer one receive message from Producer:hello, Consumer. Sending:hello Everybodyconsumer-Receive message from Producer:hello, consumer. Sending:hello Everybody
You can see the switches and queues you just created from the background of RABBITMQ (http://localhost:15672 usrname:guest pasword:guest).
When consumers become more, or for the sake of unified code management, each consumer's code needs to be the same, in order to achieve broadcast demand, each consumer needs to set a different queue name. In this case, the UUID can be used to create a unique random queue name for each consumer. The code for creating the queue name in the UUID mode can be found in the AMPQ jar package Org.springframework.amqp.core.AnonymousQueue
PublicString generatename () {uuid UUID=Uuid.randomuuid (); Bytebuffer BB= Bytebuffer.wrap (New byte[16]); Bb.putlong (Uuid.getmostsignificantbits ()). Putlong (Uuid.getleastsignificantbits ()); //Todo:when Spring 4.2.4 is the minimum spring Framework version with use Encodetourlsafestring () SPR-13784. return This. prefix +base64utils.encodetostring (Bb.array ()). ReplaceAll ("\\+", "-"). ReplaceAll ("/", "_") //But this would remain. ReplaceAll ("=", "" "); }
The return value of the UUID method can be appended to the fixed queue name, resulting in a unique random queue name. A description of the UUID can be self-Baidu.
PS: Some time ago, when I looked at Spring cloud, and saw one of the tools, Spring cloud Bus can also be used as a message listener, and after the discovery, Spring Cloud Bus also encapsulates the RABBITMQ and implements Message Queuing.
RABBITMQ and spring boot pairing for monitoring