1.简介
2.什么是队列?
队列是一种线性的数据结构,队列中的数据只能先进先出。
拿现实中的场景举个例子,如下图所示。
当我们去游乐园时,当然需要排队了,那么排队的这个队伍就可以理解为队列,第一位叫队头,最后一位就是队尾
入队: 入队就是一个人刚到游乐园,这个时候肯定不能插队对吧,这个时候就老老实实在最后一位排队,这个操作就叫入队。
出队: 出队就是排在第一位的人进入游乐园后,出了排队的队伍,这个叫出队。紧跟后面的那位就变成队头了。
3.生产者和消费者
生产者和消费者的关系就好比如,当我需要寄一封信的时候,我首先需要写一封信,我把写好的信寄给邮局,写信寄信的这个人就成为消息的生产者。那么邮局会根据信件收件人的地址派发,收件人收到信封后这自然就是消费者了。这里的邮局就相当于是RabbitMQ服务器,主要负责接收、存储和转发数据
生产者: 生产者主是生产发送消息
消费者: 消费者主要是等待接收信息
4.消息
消息是由两部分内容组成的,有效内容和内容标签。
有效内容: 可以是任何内容,一个数组,一个集合,甚至二进制数据都可以
内容标签: 描述有效内容,是 RabbitMQ 用来决定谁将获得消息。前面说的邮件通信,必须明确指定发送方地址和收件方地址
5.信道
生产者产生了消息,然后发布到 RabbitMQ 服务器,这时候就需要先跟 RabbitMQ 服务器建立连接,
生产者与 rabbitmq 服务器之间建立一条 TCP 连接之后就可以发送消息了,同样消费者也需要先跟 RabbitMQ 服务器建立连接才能接收消息。
3.简单模式
4.队列模式
一个生产者对应多个消费者,但是只能有一个消费者获得消息。
举个例子,如果我们要打客服电话询问一些问题,那么客服小姐姐肯定是随机分配。当你的电话被分配到客服的时候,那么其他的客服就无法接听你的电话了。用代码实现下吧
首先创建两个控制台程序,一个客户,一个客服
Customer 客户代码
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;
namespace Customer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("爱调戏的周老板已上线,正在拨打客服电话!");
#region 初始化问题
List<string> question = new List<string>();
question.Add("今天天气怎么样?");
question.Add("你有男朋友吗?");
question.Add("现在几点钟?");
question.Add("小姐姐加个微信怎么样?");
question.Add("想做宝马里面哭吗?");
for (int i = 0; i < question.Count; i++)
{
Console.WriteLine("问题{0}:" + question[i],i);
}
#endregion
var factory = new ConnectionFactory() { HostName = "139.199.0.47", UserName = "guest", Password = "guest" };
//创建连接
using (var connection = factory.CreateConnection())
//创建信道
using (var channel = connection.CreateModel())
{
//声明队列
channel.QueueDeclare(queue: "task_queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
while (true)
{
Console.WriteLine("请选择问题!");
var number = Int32.Parse(Console.ReadLine());
var body = Encoding.UTF8.GetBytes(question[number]);
//向队列发送消息
channel.BasicPublish(exchange: "",
routingKey: "task_queue",
basicProperties: properties,
body: body);
}
}
}
}
}
CustomerService 客服代码
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
namespace CustomerService
{
class Program
{
static void Main(string[] args)
{
Random rand = new Random();
var id = rand.Next(100, 999);
Console.WriteLine("{0}号已上线!", id);
var factory = new ConnectionFactory() { HostName = "139.199.0.47", UserName = "guest", Password = "guest" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "task_queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
Console.WriteLine(" 正在等待来电...");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
Console.WriteLine("客服接听电话!");
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine("周先生:{0}", message);
Console.WriteLine("{0}号客服:滚!", id);
Console.WriteLine("");
Thread.Sleep(1000);
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: "task_queue",
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}
}
演示效果
运行一次客户控制台以及两次客服控制台程序
运行效果里我们发现,当我们向队列里发布一条消息后,只有一个消费者能消费,这就是竞争消费模式。
5.发布/订阅模式
还没写完持续更新。。。