How to use the RABBITMQ gracefully

Source: Internet
Author: User
Tags app service

RABBITMQ is undoubtedly one of the most popular message queues in the world, and support for various locales is also plentiful, and it is necessary to learn and understand this tool as a. NET developer. There are about 3 usage scenarios for Message Queuing:

1, system integration, the design of distributed systems. Various subsystems are connected via messages, and this solution has evolved into an architectural style, the "architecture through messaging".

2, when the synchronization process in the system seriously affect the throughput, such as logging. If you need to record all the user behavior logs in the system, if the log is bound to affect the response speed of the system, when we send the log message to the message queue, the logging subsystem will consume the log message asynchronously.

3, the high availability of the system, such as the e-commerce of the second kill scene. A system outage occurs when the application server or database server receives a large number of requests at a time. If the request can be forwarded to the message queue, then there are servers to consume these messages will make the request smooth, improve the system availability.

First, start using RABBITMQ

The RABBITMQ website provides detailed installation steps, as well as a tutorial on the use of RABBITMQ in six different scenarios. Tutorials 1, 3, and 6 will cover 99% of usage scenarios, so it's normal to get started with just a few 3 tutorials.

Second, simple analysis

We do a simple comb with the official Tutorial 1: This tutorial shows how producer sends a message to a message queue, which is consumed by the message consumer (Consumer) after it receives the message.

1, producer end:

           var factory = new ConnectionFactory () {HostName = "localhost"}; using (var connection = factory. CreateConnection ()) {while (Console.ReadLine ()! = null) {USI Ng (var channel = connection. Createmodel ()) {//Create a message queue channel called "Hello".                            Queuedeclare (queue: "Hello", Durable:false, Exclusive:false,                        Autodelete:false, Arguments:null);                        var message = "Hello world!";                        var BODY = Encoding.UTF8.GetBytes (message); Sends messages to the message Queue message channel. Basicpublish (Exchange: "", Routingkey: "Hello", Basicproperties:nul                        L, Body:body); Console.WriteLine ("[X] Sent {0} ", message); }                }            }

The code is very simple and almost impossible to streamline: Create a channel, create a queue, and send messages to that queue.

2, Consumer end

           var factory = new ConnectionFactory () {HostName = "localhost"}; using (var connection = factory. CreateConnection ()) {using (var channel = connection. Createmodel ()) {//Create a queue named "Hello" to prevent the producer side from creating the queue channel.                                         Queuedeclare (queue: "Hello", Durable:false, Exclusive:false, Autodelete:false, AR                    Guments:null);                    Callback, which executes the function when consumer receives the message var consumer = new Eventingbasicconsumer (channel); Consumer. Received + = (model, ea) = {var BODY = ea.                        Body;                        var message = Encoding.UTF8.GetString (body);                    Console.WriteLine ("[x] Received {0}", message);                    }; Consumer queueThe message channel in "Hell".                                         Basicconsume (queue: "Hello", Noack:true,                    Consumer:consumer);                    Console.WriteLine ("Press [Enter] to exit.");                Console.ReadLine (); }            }

This code can be understood as: Create a queue, create a channel, define a callback function, and consume messages.

This example can be easily understood as a 1 (producer) VS 1 (consumer) scenario;

Example 3 describes the Publish/subscriber mode, which is 1 (producer) VS multiple (consumer);

In the above two examples, producer only needs to send a message, and does not care about the return result of consumer. Example 6 describes an RPC invocation scenario that producer sends a message and receives the return result of consumer, a scenario that seems to contradict the purpose of using Message Queuing. Because one of the purposes of using Message Queuing is to be asynchronous, this scenario seems to be asynchronous, but this scenario is also useful, such as when a user operation generates a message that the application service has executed some logic and has changed the database. The UI will wait until the app service's return results to refresh the page.

III. Discovery of Abstraction

I have a rabbitmq in Action on my desk, and the documentation provided on the website is very detailed, I feel that in one months I will be able to master RABBITMQ, then the resume can be written on the "mastery ...", feeling a little proud of it ..., But I know this is not the best way to use RABBITMQ.

We know that abstraction can help us hide some of the technical details, let us focus on the core business, such as a person asked you: "How To go wild Goose Pagoda?" "Your answer may be" small village east, always walk two stations, right hand side ", if you answer:" Turn right 45 degrees, go forward 100 meters, then turn 90 degrees ... ", the other side will be lost in these details.

The use of Message Queuing actually hides an abstraction-service bus.

We look back at the first example, this example implies that the business is: Clienta sends an instruction, CLIENTB responds after receiving the instruction. If so, why should we care how to create a channel and how to create a queue? I just want to send a message. In addition, this example is not strong enough to write:

There is no retry mechanism: If CLIENTB is not executed for the first time how does it handle the message?

There is no error handling mechanism: What if CLIENTB is handling the message after retrying n times or exception?

no fusing mechanism;

How to do a schedule to Clienta (planning), such as the timing of sending;

No information audit mechanism;

Unable to trace the status of the message;

Handling of things.

Service bus is the abstraction of this scenario and provides us with these mechanisms, so let's take a quick look at it.

Four, the initial view masstransit

Masstransit is an open-source, free ESB product under the. NET platform: Http://masstransit-project.com/,GitHub star,500 Fork, similar products and Nservicebus, The reason is to choose masstransit because he is more lightweight than Nservicebus, and in the beginning of the masstransit development of the selection of RABBITMQ as a message transmission; and I want to compare him to Nservicebus, See what the focus is on them.

1. New Console Application: Masstransit.RabbitMQ.GreetingClient

Use Masstransit to install from NuGet:

Install-package MASSTRANSIT.RABBITMQ

2. Create a service bus and send a command

        static void Main (string[] args) {Console.WriteLine ("Press ' Enter ' to send a message.            To exit, Ctrl + C ");            var bus = Buscreator.createbus ();            var Sendtouri = new Uri ($ "{rabbitmqconstants.rabbitmquri}{rabbitmqconstants.greetingqueue}"); while (Console.ReadLine ()!=null) {Task.run (() = SendCommand (bus, Sendtouri)).            Wait ();        } console.readline (); } private static Async void SendCommand (Ibuscontrol Bus,uri sendtouri) {var endPoint =await bus.            Getsendendpoint (Sendtouri); var command = new Greetingcommand () {Id = Guid.NewGuid (), DateTime = datetime.no            W};            await Endpoint.send (command); Console.WriteLine ($ "Send Command:id={command. Id},{command.         DateTime} "); }

This piece of code hides a lot of detail about Message Queuing, focusing our attention on sending messages, while Servicebus provides an API that is closer to the business, although we are sending a message, but in this scenario it is a command, send (command) This API describes our intentions.

3, the service side receive this command

Create a new command console control program: Masstransit.RabbitMQ.GreetingServer

            var bus = Buscreator.createbus (cfg, host) = = (cfg)                . Receiveendpoint (host, rabbitmqconstants.greetingqueue, E =                {                    e.consumer<greetingconsumer> ();                });            });

This code can be understood as the service side in the listener message, we registered on the server named "Greetingconsumer" consumer, Greetingconsumer definition:

    public class greetingconsumer:iconsumer<greetingcommand>    {public        async Task consume (consumecontext <GreetingCommand> context)        {            await Console.Out.WriteLineAsync ($ "Receive greeting Commmand: {context. Message.id},{context. Message.datetime} ");        }    }

The consumer can consume messages of type Greetingcommand. This example hides the technical details about RABBITMQ, puts the code center in the business, and tries to run the two console applications:

V. Realization of Publish/subscribe Mode

The Publish/Subscribe model makes it possible to have a messaging-based software architecture that behaves as Clienta send messages X,CLIENTB and CLIENTC can subscribe to Message x.

1, we change in the above example, when Greetingconsumer received greetingcommand after sending a greetingevent:

           var greetingevent = new Greetingevent ()            {                Id = context. Message.id,                DateTime = DateTime.Now            };            Await the context. Publish (greetingevent);

2. New Console program Masstransit.RabbitMQ.GreetingEvent.SubscriberA to subscribe to greetingevent messages:

           var bus = Buscreator.createbus (cfg, host) = = (cfg)                . Receiveendpoint (host, rabbitmqconstants.greetingeventsubscriberaqueue, E =                {                    e.consumer< Greetingeventconsumer> ();                }            ); Bus. Start ();

Define Greetingeventconsumer:

   public class greetingeventconsumer:iconsumer<greeting.message.greetingevent>    {public        async Task Consume (consumecontext<greeting.message.greetingevent> context)        {            await Console.Out.WriteLineAsync ($ "Receive greeting Event:id {context. Message.id} ");        }    }

This code is almost identical to Masstransit.RabbitMQ.GreetingServer's acceptance of a command, the only difference being:

In send/receive mode, the client first obtains the other's endpoint (endpoint) and sends the command directly to the end point. The server listens to its own endpoints and consumes commands.

While the client publish an event in the Publish/subscribe mode, Subscribera listens for events at its own endpoint (Endpointa), Subscriberb listens for events at its own end point (ENDPOINTB).

3, according to the above analysis and then define a Masstransit.RabbitMQ.GreetingEvent.SubscriberB

4. Run 4 console applications to see

Vi. Implementing RPC Mode

This pattern is called Request/response mode in Masstransit, and is implemented by Irequestclient<isimplerequest, isimpleresponse> interface. A related example is on the official GitHub.

Conclusion: This article analyzes how to use Masstransit to abstract the business, avoid direct use of the specific message queue, of course, the many service bus mechanisms mentioned in this article, such as "Retry, fuse, etc." did not appear in the article, we need to further understand the project.

By comparing some trial and Nservicebus of Masstransit, Masstransit is easy to use and free in practical projects, and the definitions of various APIs are also very clear, but the official documents are a little too simple, so we need to do in-depth research on the actual usage. As. NET platform under the small number of ESB open-source products, its attention is not enough, looking forward to the open source projects to contribute.

Examples of this article are available for download: Http://git.oschina.net/richieyangs/RabbitMQ.Practice

How to use the RABBITMQ gracefully

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.