.Net网站架构设计(五) 消息中间件

来源:互联网 发布:c语言初学者看什么书 编辑:程序博客网 时间:2024/06/06 04:18

.Net网站架构设计(五) 消息中间件

.Net网站架构设计(五)消息中间件

消息中间件是异步化、解耦、流量削峰的利器

在设计互联架构是,往往遇到需要推送消息,而推送消息比较耗时。

做法

       1:直接执行业务,调用推送

       

[csharp] view plain copy
  1. int main()  
  2. {  
  3. 执行业务代码  
  4. doBussiness();//调用消息推送  
  5. NoteMessageObject obj = (NoteMessageObject)state;NoteXmppMessage nXmpp = new NoteXmppMessage(obj.noteInfo, obj.listNoteSendToObjects);  
  6. }  

优点:开发简单

缺点:由于推送需要时间,所以返回到客户端时间有延迟,较长

       2:开启线程执行推送

[csharp] view plain copy
  1. int main()  
  2. {  
  3.   
  4. //执行业务代码  
  5.   
  6. doBussiness();  
  7. Thread r=ThreadStart(doSendNoteMessage);  
  8. r.Start();  
  9. }  
  10.   
  11.  name="code" class="csharp">void doSendNoteMessage(object state)  
  12.         {  
  13.             try  
  14.             {  
  15. <pre name="code" class="csharp">                //调用消息推送  
  16.   NoteMessageObject obj = (NoteMessageObject)state; NoteXmppMessage nXmpp = new NoteXmppMessage(obj.noteInfo, obj.listNoteSendToObjects); nXmpp.SendMessage(); } catch(Exception e) { // MagicSales.CommonTools.Log.WriteLog(e.Message); // CommonTools.Log.WriteLog(e.Message); } }  
优点:执行完代码不用管推送是否成功直接返回给客户端,把推送交给线程,提高了系统响应速度;

缺点:a大量消息并发,开启线程十分耗费资源,当线程开启到一定程度,会报一些莫名其妙的错误;

           b需要维护系统重启,未完成的推送消息丢失。

       3:利用线程池开启线程实现推送

[csharp] view plain copy
  1. int main()  
  2. {  
  3.   
  4. //执行业务代码  
  5.   
  6. doBussiness();  
  7. NoteMessageObject obj = new NoteMessageObject();  
  8. obj.noteInfo = noteInfo;  
  9. obj.listNoteSendToObjects = listNoteSendToObjects;  
  10. ThreadPool.QueueUserWorkItem(doSendNoteMessage, obj);//开启线程池  
  11. }  
  12.   
  13. void doSendNoteMessage(object state)  
  14.         {  
  15.             try  
  16.             {  
  17.   
  18.                 //调用消息推送  
  19.   
  20.                NoteMessageObject obj = (NoteMessageObject)state;  
  21.                 NoteXmppMessage nXmpp = new NoteXmppMessage(obj.noteInfo, obj.listNoteSendToObjects);  
  22.                   
  23.                 nXmpp.SendMessage();  
  24.             }  
  25.             catch(Exception e)  
  26.             {  
  27.                // MagicSales.CommonTools.Log.WriteLog(e.Message);  
  28.              //   CommonTools.Log.WriteLog(e.Message);  
  29.             }  
  30.         }  
优点:有了线程池管理线程,很好的解决的多线程时,线程资源的复用,大大提供了效率,减少了由于线程过多带来的问题。

缺点:随着推送消息的增多,大量消息堆积。系统负荷增大。

            重启系统后,推送消息丢失。

       4:利用消息队列实现。

1,第一要选用一种消息队列,可备选项目有:RabbitMQ,MSMQ,AcivityMQ,Kafka 有关他们几个的对比请参考

      我这里选择RabbitMQ.net RabbitMQ参考

用RabbitMQ就要分生产者,和消费者  

生产者代码:

[csharp] view plain copy
  1. static void Main(string[] args)  
  2.         {  
  3.   
  4.           //执行业务代码  
  5.            doBussiness();  
  6.  var factory = new ConnectionFactory(); factory.HostName = "192.168.1.219"; factory.UserName = "lim";   
  7. factory.Password = "liming!123"using (  
  8. var connection = factory.CreateConnection())   
  9. {   
  10. using (var channel = connection.CreateModel())   
  11. {   
  12. bool durable = true; channel.QueueDeclare("task_queue", durable, falsefalsenull);   
  13. NoteMessageObject obj = new NoteMessageObject();   
  14. obj.noteInfo = noteInfo; obj.listNoteSendToObjects = listNoteSendToObjects;  
  15. string message = Json.Convert(obj) ;//序列化   
  16. var properties = channel.CreateBasicProperties();  
  17.  properties.SetPersistent(true);   
  18. var body = Encoding.UTF8.GetBytes(message);  
  19.  channel.BasicPublish("""task_queue", properties, body);  
  20.  Console.WriteLine(" set {0}", message); }  
  21.  } Console.ReadKey();  
  22. <pre>  
消费者代码:

[csharp] view plain copy
  1.  static void Main(string[] args)  
  2.         {  
  3.             var factory = new ConnectionFactory();  
  4.             factory.HostName = "192.168.1.219";  
  5.             factory.UserName = "lim";  
  6.             factory.Password = "liming!123";  
  7.   
  8.             using (var connection = factory.CreateConnection())  
  9.                 using (var channel = connection.CreateModel())  
  10.                 {  
  11.                     bool durable = true;  
  12.                     channel.QueueDeclare("task_queue", durable, falsefalsenull);  
  13.                     channel.BasicQos(0, 1, false);  
  14.   
  15.                     var consumer = new QueueingBasicConsumer(channel);  
  16.                     channel.BasicConsume("task_queue"false, consumer);  
  17.   
  18.                     while (true)  
  19.                     {  
  20.                         var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();  
  21.   
  22.                         var body = ea.Body;  
  23.                         var message = Encoding.UTF8.GetString(body);  
  24.   
  25.                        NoteMessageObject obj = Json.DescConvert(message) ;//反序列化  
  26.               
  27.   
  28.                      NoteXmppMessage nXmpp = new NoteXmppMessage(obj.noteInfo, obj.listNoteSendToObjects);  
  29.           nXmpp.SendMessage();  
  30.   
  31.   
  32. channel.BasicAck(ea.DeliveryTag, false); } } }  
优点:a生产者,和消费者分离, b.消息持久化保存,重启RabbitMQ,和应用系统,消费者,生产者程序,都不会丢失消息。 c:当列队待处理消息大量滞留时,可以单纯的增加消费者个数来,提高消费能力。缺点:开发部署较为复杂
原创粉丝点击