Redis--消息队列
1:18
1.什么是高并发系统的消息队列?
队列:对头+队列容器+对尾
消息队列(MessageQueue MQ):有一个队列容器,生产者(入队列),消费者(出队列)
2.使用消息队列的场景(使用消息队列的原因):
2.1 分布式场景
2.1.1 异步处理
多线程可以节省时间,但是会降低cpu吞吐量
用消息队列也可以减少时间的消耗,当创建失败的时候,可以用消息队列的持久化机制处理
2.1.2 应用解耦
利用消息队列将客户都按和库存系统解耦(消除强依赖)
2.1.3 流量削峰
限制流量(接受客户端请求服务将客户的请求保存到消息队列中,业务服务用自己的最大的吞吐量去消息队列中获取客户请求,如果不能正常取到的,通过消息队列返回给客户端)
2.1.4 异步事务
2.2 日志场景
2.2.1 优化日志传输,提升系统性能
2.3 即时通讯
2.3.1 聊天室
3. 实现消息队列的发手段:
3.1 RabbitMQ
3.2 ActiveMQ
3.3 RocketMQ
3.4 Kafka
3.5 Redis
3.6 ZeroMQ
3.7 阿里MNS
4.应用Redis的消息队列
4.1 redis应用环境:
4.1.1 redis
4.1.2 service.stock(下载serviceStock.redis.dll)
创建客户端:RedisClient client = new RedisClient("localhost:6379");
4.1.3 redis生产者(可以存放2的32次方-1的数据大约是40亿)
//Lpush()从左边插入数据
//Rpush()从右边插入数据
byte[] bytes = System.Text.Encoding.UTF8.GetBytes("tony");
client.Lpush(“tonytest”, bytes );
4.1.4 redis消费者
//队列是左边插入数据,右边取数据;右边插入数据,左边取数据
Byte[] bytes = redisClient.RPop("tonytest");
string value = System.Text.Encoding.UTF8.GetString(bytes);
4.1.5 消息队列的两种模式
4.1.5.1 推模式
这是指消费者在获取消息队列中的数据的时候,当数据没有的时候,会按照制定的时长阻塞线程,在阻塞的过程中如果消息队列中有数据的话会自动推送到消费者。
被动的接收数据
//BRPop()
//BRLop()
//Byte[] bytes = redisClient.BRPopValue("tonytest", 60);//阻塞60s
while(true)
{
Byte[] bytes = redisClient.BRPopValue("tonytest", 10);
if(bytes != null)
{
string value = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine(value);
}
else
{
Console.WriteLine("队列中没有数据");
}
}
4.1.5.2 拉模式
主动的去消息队列中获取数据
//RPOP()
//LPop()
//Byte[] bytes = redisClient.RPop("tonytest");
while(true)
{
Thread.sleep(1000);
Byte[] bytes = redisClient.RPop("tonytest");
if(bytes != null)
{
string value = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine(value);
}
else
{
Console.WriteLine("队列中没有数据");
}
}
总结:消息队列的生产者和消费者是一对一的
4.1.6 redis关闭
redisClient.Dispose()
4.1.6 准备异步处理,应用解
情景:异步实现创建订单,添加积分,发送短信
4.1.6.1在创建订单的服务中
//1.创建订单
//2.创建连接
RedisClient client = new RedisClient("localhost:6379");
//3.生产消息
//3.1积分消息
byte[] bytes = System.Text.Encoding.UTF8.GetBytes("订单号");
client.Lpush(“order_points”, bytes );
//3.2短信消息
byte[] bytes = System.Text.Encoding.UTF8.GetBytes("订单号");
client.Lpush(“order_sms”, bytes );
4.1.6.2在积分服务中:
//1.创建连接
RedisClient client = new RedisClient("localhost:6379");
while(true)
{
Byte[] bytes = redisClient.RPop("order_points");
if(bytes != null)
{
string value = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine($"获取到的积分消息:{value}");
//增加积分
OrderPoint p = new OrderPoint();
p.AddPoint(value);
Console.WriteLine(value);
}
else
{
Console.WriteLine("队列中没有数据");
}
}
4.1.6.3 在短信服务中消费短信消息
//1.创建连接
RedisClient client = new RedisClient("localhost:6379");
while(true)
{
Byte[] bytes = redisClient.RPop("order_sms");
if(bytes != null)
{
string value = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine($"获取到的积分消息:{value}");
//消费短信消息,发送短信
OrderSms p = new OrderSms();
p.SendSms(value);
Console.WriteLine(value);
}
else
{
Console.WriteLine("队列中没有数据");
}
}