. Net platform rabbitmq use encapsulation

Source: Internet
Author: User
Tags tojson
RabbitMq is not familiar to anyone. This article focuses on sharing rabbitmq. Client after RabbitMQ is learned. At the end of the article, I will present the encapsulated components and demos. Preface

RabbitMq is not familiar to anyone. This article focuses on sharing rabbitmq. Client after RabbitMQ is learned. At the end of the article, I will present the encapsulated components and demos.

Operation of Rabbitmq

It can be seen that the Publisher (Publisher) first sends the message to the Exchange switch, and then sends the message to the specified Queue from the switch. It has previously declared the binding relationship between the switch and the Queue, finally, the Customer passesSubscriptionOrActive retrievalSpecify the queue message for consumption.

The subscription and active fetch mentioned above can be understood as pushing (passive) and pulling (active ).

Push, as long as a message is added to the queueNotificationIdle consumers consume data. (I will wait for you to find me, observer mode)

The consumer will not be notified, but will trigger the round-robin or timed retrieval of queue messages by the consumer. (I need to find you)

For example, if there are two system order systems and delivery systems that initiate delivery message commands from the order system, the delivery system needs to subscribe to the queue for timely delivery, it can be processed as long as there are instructions.

However, the program occasionally encounters exceptions, such as network or DB timeout, and throws messages to the failed queue. in this case, the resend mechanism is required. However, I don't want to while (IsPostSuccess = True), because as long as an exception occurs, there will be exceptions in a certain period of time. such retries are meaningless.

In this case, messages do not need to be processed in a timely manner. there is a JOB scheduled or every several minutes (the number of failures * interval minutes) to retrieve the failure queue message and resend the message.

Publish (Publish) Encapsulation

Step: initialize the link-> declare a switch-> declare a queue-> bind a machine to a queue-> publish a message. Note that I saved the Model to ConcurrentDictionary because it was time-consuming to declare and bind the Model. Second, it was not necessary to re-initialize the message to the repeated queue.

1 ///2 // switch statement 3 ///4 ///5 ///Switch6 ///Switch type: 7 // 1. Direct Exchange-process route key. To bind a queue to a vSwitch, the message must be exactly 8 // matched with a specific route key. This is a complete match. If a queue is bound to a vSwitch and the route key "dog" is required, only the 9 // message marked as "dog" is forwarded and dog is not forwarded. puppy, and does not forward dog. guard, only dog10 // 2, Fanout Exchange-do not process the route key. You only need to simply bind the queue to the vSwitch. All messages sent to a vSwitch are 11 // forwarded to all the queues bound to the vSwitch. Similar to subnet broadcast, each host in the subnetwork receives a copy message. Fanout12 // The fastest message forwarded by the vSwitch. 13 // 3. Topic Exchange-match the route key with a certain mode. In this case, the queue needs to be bound to a mode. The symbol "#" matches one or more 14 // words. the symbol "*" does not match many words. Therefore, "audit. #" can match "audit. irs. audit ate", but "audit. *" 15 // only matches "audit. irs ".16 ///Persistence17 ///Automatic deletion18 ///Parameters19 private static void ExchangeDeclare (IModel iModel, string exchange, string type = ExchangeType. Direct, 20 bool durable = true, 21 bool autoDelete = false, IDictionary
 
  
Arguments = null) 22 {23 exchange = exchange. IsNullOrWhiteSpace ()? "": Exchange. Trim (); 24 iModel. ExchangeDeclare (exchange, type, durable, autoDelete, arguments); 25} 26 27 ///
  28 // queue statement 29 ///30 ///
  31 ///
  Queue32 ///
  Persistence33 ///
  Exclusive queue. if a queue is declared as an exclusive queue, the queue is visible only for the connection that is declared for the first time. 34 // and is automatically deleted when the connection is disconnected. Note the following three points: first, the exclusive queue is visible based on connections. different channels of the same connection can access the exclusive queue created by the same connection at the same time. Second, "for the first time", if an exclusive queue has been declared for a connection, other connections 36 // are not allowed to create an exclusive queue with the same name, which is different from a common queue. Third, even if the queue is persistent, the exclusive queue will be automatically deleted once the connection is closed or 37 // The client exits. This queue is applicable to scenarios where only one client sends and reads messages.38 ///
  Automatic deletion39 ///
  Parameters40 private static void QueueDeclare (IModel channel, string queue, bool durable = true, bool exclusive = false, 41 bool autoDelete = false, IDictionary
  
   
Arguments = null) 42 {43 queue = queue. IsNullOrWhiteSpace ()? "UndefinedQueueName": queue. Trim (); 44 channel. QueueDeclare (queue, durable, exclusive, autoDelete, arguments); 45} 46 47 ///
   48 // get Model49 ///50 ///
   VSwitch name51 ///
   Queue name52 ///
   53 ///
   Persistent or not54 ///
   55 private static IModel GetModel (string exchange, string queue, string routingKey, bool isProperties = false) 56 {57 return ModelDic. getOrAdd (queue, key => 58 {59 var model = _ conn. createModel (); 60 ExchangeDeclare (model, exchange, ExchangeType. fanout, isProperties); 61 QueueDeclare (model, queue, isProperties); 62 model. queueBind (queue, exchange, routingKey); 63 ModelDic [queue] = model; 64 return model; 65}); 66} 67 68 ///
   69 // publish message 70 ///71 ///
   Route key72 ///
   Queue information73 ///
   VSwitch name74 ///
   Queue name75 ///
   Persistent or not76 ///
   77 public void Publish (string exchange, string queue, string routingKey, string body, bool isProperties = false) 78 {79 var channel = GetModel (exchange, queue, routingKey, isProperties ); 80 81 try82 {83 channel. basicPublish (exchange, routingKey, null, body. serializeUtf8 (); 84} 85 catch (Exception ex) 86 {87 throw ex. getInnestException (); 88} 89}
  
 

View Code

Next is the release speed of the local test:

4.2 W/S is a stable speed, and the deserialization (ToJson) will be slightly faster.

Subscription encapsulation

During the release, the switch and the queue are declared and bound. However, you only need to declare the queue when subscribing. The following code shows that when an exception is caught, the message is sent to the custom "dead message queue", and the other JOB regularly resends the message. therefore, finally: the response is successful.

////// Obtain the Model //////Queue name//////
 Private static IModel GetModel (string queue, bool isProperties = false) {return ModelDic. getOrAdd (queue, value => {var model = _ conn. createModel (); QueueDeclare (model, queue, isProperties); // model of the number of messages consumed each time. basicQos (0, 1, false); ModelDic [queue] = model; return model ;});}////// Receive the message //////
 ///Queue name//////Consumption processing///Public void Subscribe
 
  
(String queue, bool isProperties, Action
  
   
Handler, bool isDeadLetter) where T: class {// queue declaration var channel = GetModel (queue, isProperties); var consumer = new EventingBasicConsumer (channel); consumer. stored Ed + = (model, ea) =>{ var body = ea. body; var msgStr = body. deserializeUtf8 (); var msg = msgStr. fromJson
   
    
(); Try {handler (msg);} catch (Exception ex) {ex. GetInnestException (). WriteToFile ("queue receiving message", "RabbitMq"); if (! IsDeadLetter) PublishToDead
    
     
(Queue, msgStr, ex) ;}finally {channel. BasicAck (ea. DeliveryTag, false) ;}; channel. BasicConsume (queue, false, consumer );}
    
   
  
 

View Code

Next is the release speed of the local test:

There are 1.9 K/S in fast time, and 1.7 K/S in slow time.

Pull (Pull) Encapsulation

Directly run the code:

////// Get the message //////
 ////////////Consumption processingPrivate void Poll
 
  
(String exchange, string queue, string routingKey, Action
  
   
Handler) where T: class {var channel = GetModel (exchange, queue, routingKey); var result = channel. basicGet (queue, false); if (result. isNull () return; var msg = result. body. deserializeUtf8 (). fromJson
   
    
(); Try {handler (msg);} catch (Exception ex) {ex. getInnestException (). writeToFile ("receive messages in the queue", "RabbitMq");} finally {channel. basicAck (result. deliveryTag, false );}}
   
  
 

View Code

There are 1.8 K/s at a high speed, and the stability is 1.5 K/S.

Rpc (Remote Call) Encapsulation

First of all, RabbitMq only provides this RPC function, but it is not a real RPC. why do we say this:

1. traditional Rpc hides call details, passing parameters and throwing exceptions like calling local methods

2. the Rpc of RabbitMq is message-based. after the consumer consumes the message, the response result is returned through the new queue.

////// RPC client /////////////////////
 Public string RpcClient (string exchange, string queue, string routingKey, string body, bool isProperties = false) {var channel = GetModel (exchange, queue, routingKey, isProperties ); var consumer = new QueueingBasicConsumer (channel); channel. basicConsume (queue, true, consumer); try {var correlationId = Guid. newGuid (). toString (); var basicProperties = channel. createBasicProperties (); basicProperties. replyTo = queue; basicProperties. correlationId = correlationId; channel. basicPublish (exchange, routingKey, basicProperties, body. serializeUtf8 (); var sw = Stopwatch. startNew (); while (true) {var ea = consumer. queue. dequeue (); if (ea. basicProperties. correlationId = correlationId) {return ea. body. deserializeUtf8 ();} if (sw. elapsedMilliseconds> 30000) throw new Exception ("Wait for response timeout");} catch (Exception ex) {throw ex. getInnestException ();}}////// RPC server //////
 ///////////////Public void RpcService
 
  
(String exchange, string queue, bool isProperties, Func
  
   
Handler, bool isDeadLetter) {// queue declaration var channel = GetModel (queue, isProperties); var consumer = new EventingBasicConsumer (channel); consumer. stored Ed + = (model, ea) =>{ var body = ea. body; var msgStr = body. deserializeUtf8 (); var msg = msgStr. fromJson
   
    
(); Var props = ea. basicProperties; var replyProps = channel. createBasicProperties (); replyProps. correlationId = props. correlationId; try {msg = handler (msg);} catch (Exception ex) {ex. getInnestException (). writeToFile ("receive messages in the queue", "RabbitMq");} finally {channel. basicPublish (exchange, props. replyTo, replyProps, msg. toJson (). serializeUtf8 (); channel. basicAck (ea. deliveryTag, false) ;}}; channel. basicConsume (queue, false, consumer );}
   
  
 

View Code

Yes, but it is not recommended. You can consider other RPC frameworks. Grpc and thrift.

End

In this article, there is not much knowledge about RabbitMq, because garden has too many study notes. Next I will provide my code #. If you find something wrong, please comment out, I will modify it in time to avoid misleading others.

If this article is useful, click here for recommendations. thank you for reading it.

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.