C#实现消息队列_Shuai_Sir的博客-CSDN博客_c# 消息队列

来源: C#实现消息队列_Shuai_Sir的博客-CSDN博客_c# 消息队列

C#实现消息队列
1.认识消息队列
消息队列 (MSMQ Microsoft Message Queuing)是MS提供的服务,也就是Windows操作系统的功能,并不是.Net提供的。

2.什么是消息队列
消息队列一般简称为 MQ (Messges Queue),是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成,是在消息的传输过程中保存消息的容器。消息队列本质上是一个队列,而队列中存放的是一个个消息。

队列是一个数据结构,具有先进先出的特点。而消息队列就是将消息放到队列里,用队列做存储消息的介质。消息的发送放称为生产者,消息的接收方称为消费者。

消息队列由 Broker(消息服务器,核心部分)、Producer(消息生产者)、Consumer(消息消费者)、Topic(主题)、Queue(队列)和Message(消息体)组成。

3. 消息队列特点
消息队列有三个作用,分别是削峰、解耦和异步。

流量削峰:主要用于在高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。

假设系统只能处理1000个请求,但这时突然来了3000个请求,如果不加以限制就会造成系统瘫痪。使用消息队列做缓冲,将多余的请求存放在消息队列中,等系统根据自己处理请求的能力去消息队列去。

应用解耦:主要用于当一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理时,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。

假设某个服务 A 需要调用服务 B,但是服务 B 突然出现问题,这样会导致服务 A 也会出现问题。如果使用消息队列,当服务 A 执行完成之后,发送一条消息到队列中,服务 B 读取到这条消息,那么它立刻开始进行业务的执行。

异步通信:主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验。

假设有一个业务,要先执行服务 A ,然后服务 A 去调用服务 B ,当服务 B 完成之后,服务 A 调用服务 C,这个业务需要一步步走下去。当使用了消息队列之后,服务 A 完成之后,可以同时执行服务 B 和 服务 C ,这样就减低业务的响应时间,提高用户体验。

消息队列简单例子
一下是WIN10的操作步骤:
1.打开运行,输入”OptionalFeatures”,钩上Microsoft Message Queue(MSMQ)服务器。

2. 消息队列分为以下几种,每种队列的路径表示形式如下:

公用队列 MachineName\QueueName

专用队列 MachineName\Private$\QueueName

日记队列 MachineName\QueueName\Journal$

计算机日记队列 MachineName\Journal$

计算机死信队列 MachineName\Deadletter$

计算机事务性死信队列 MachineName\XactDeadletter$

这里的MachineName可以用 “.”代替,代表当前计算机

3.打开“此电脑”–>左上角点击“计算机”–>点击“管理”

注意:如果没看到“消息队列”这个选项,那就是这东西在这电脑上还没使用过,没关系,一会编程的时候创建就会显示出来了(我印象中一开始我也没有这个选项,写了代码后就有了)

知道这东西在哪里后,开始进入正题。C#中使用消息队列需要添加新的引用System.Messaging

4.添加引用后在代码里添加命名空间就可以开始了

这里我们新建一个控制台程序:

存入数据:

static void Main()
{
//存
string msgPath = “.\\Private$\\MyMsg”;
//指定路径一个名称为“MyMsg”的专用队列的路径字符串
string studentName = “hello word”;
// 要写入消息消息队列的信息
SendMsg(msgPath, studentName);
Console.WriteLine(“发送成功” + studentName);
Console.ReadLine();
}
/// 存
/// </summary>
/// <param name=”mQPath”></param>
/// <param name=”studentName”></param>
public static void SendMsg (string mQPath,string studentName)
{
//先判断这个消息队列是否存在,如果存在则直接实例化对象,如果不存在则创建该消息队列
MessageQueue mq = (MessageQueue.Exists(mQPath)) ? (new MessageQueue(mQPath)) : (MessageQueue.Create(mQPath));
mq.Send(studentName);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
读取数据:

static void Main()
{
//读取数据
string msgPath = “.\\Private$\\MyMsg”;
ReceiveMsg(msgPath);//异步读取
// ReceiveMsgT(msgPath); 同步读取
Console.ReadLine();

}
///异步读取
private static void ReceiveMsg(string msgPath) {
if (MessageQueue.Exists(msgPath))
{
MessageQueue mq=new MessageQueue(msgPath);
mq.ReceiveCompleted += new ReceiveCompletedEventHandler(ReceiveMethon);
mq.BeginReceive(MessageQueue.InfiniteTimeout);
Console.WriteLine(“异步已接收数据”);
}

}
static readonly XmlMessageFormatter f=new XmlMessageFormatter(new Type[] { typeof(string)}); //格式
private static void ReceiveMethon(object sender,ReceiveCompletedEventArgs e) {
Message m=e.Message;
m.Formatter = f;//转换格式
Console.WriteLine(m.Body.ToString());
}
//同步读取
private static void ReceiveMsgT(string msgPath) {
if (MessageQueue.Exists(msgPath))
{
MessageQueue mq= new MessageQueue(msgPath);
Message m = mq.Receive();
m.Formatter= f;//格式转换
Console.WriteLine(m.Body.ToString());
Console.WriteLine(“同步已接受数据”);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
这里简单说一下两种方式读取的区别,同步读取数据的话,会堵塞当前线程,直到读到数据为止才继续运行之后的程序,异步读取的话就避免了这个问题。如果读取的数据量小、速度快,为了编写代码方便可选择同步读取,如果读取的数据量大、速度慢,则建议使用异步读取。

消息队列有点像我们常见的数据库,能进行数据的存取,但是与数据库其中一点不同的就是消息队里中的消息被读取后就会被销毁,不需要我们手动删除。
————————————————
版权声明:本文为CSDN博主「Shuai_Sir」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Shuai_Sir/article/details/127899893

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏