电商的秒杀和抢购,对程序员来说,都不是一个陌生的东西。然而,从技术的角度来说,这对于Web系统是一个巨大的考验。当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要。
我们直接将请求放入队列Queue中的,采用FIFO(First Input First Output,先进先出),这样的话,我们就不会导致某些请求永远获取不到锁。这里有点强行将多线程变成单线程的感觉。
秒杀看似简单,但是可能会存在两个问题:高并发和超卖
高并发:比较火秒杀活动同时参与秒杀人数都是10w+的,如此之高的秒杀人数对于网站架构从前到后都是一种考验。
超卖:秒杀商品都会有固定的数量,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的一大难题。
此代码简单说明问题,例如有10万个人秒杀10个商品,我们定义队列queueAll 存放并发的10万人,queueCur存放已经抢到的10个人
private static int cnt =10;
private static Queue<string> queueAll = new Queue<string>();
private static Queue<string> queueCur = new Queue<string>();
购买代码
public RetData Buy(string uid)
{
queueAll.Enqueue(uid); if (queueAll.Count > cnt){
return new RetData {Code = -1, Msg = "商品抢光了", Cnt = 0};
}
queueCur.Enqueue(uid);
return new RetData { Code = 1, Msg = "恭喜已抢到", Cnt = cnt - queueAll.Count };
}
public class RetData
{
public int Code { get; set; }
public string Msg { get; set; }
public int Cnt { get; set; }
}
处理订单
public static void HandleQueue()
{
Task.Factory.StartNew(() =>
{
while (true) if (queueCur.Count > 0) HandleOrder();
});
} public static void HandleOrder()
{
while (queueCur.Count != 0)
{
Console.WriteLine("处理用户订单中:" + queueCur.Dequeue());
}
}
Parallel模拟10万用户并发请求
var tt = new ThreadPar();
Parallel.For(0, 100000, (t, state) =>
{
var uid = "用户" + t;
var x = tt.Buy(uid);
if (x.Code == -1)
{
Console.WriteLine(uid + ":" + x.Msg);
//state.Break();
}
else
Console.WriteLine(uid + ":" + x.Msg + "还剩下:" + x.Cnt + "件");
});
处理中,由于数据太多看不到谁抢到了商品,后面注释了抢不到的输出
用户0、1、75000、50000、50001、50002 、50003 、50004、25000、75001 这10位抢到了商品,其他人都没有抢到,
全部代码示例:
public class ThreadPar
{
private static int cnt =;
private static Queue<string> queueAll = new Queue<string>();
private static Queue<string> queueCur = new Queue<string>();
//private static object ol = new object(); static ThreadPar()
{
HandleQueue();
} public RetData Buy(string uid)
{
queueAll.Enqueue(uid); if (queueAll.Count > cnt){
return new RetData {Code = -, Msg = "商品抢光了", Cnt = };
}
queueCur.Enqueue(uid);
return new RetData { Code = , Msg = "恭喜已抢到", Cnt = cnt - queueAll.Count };
}
public class RetData
{
public int Code { get; set; }
public string Msg { get; set; }
public int Cnt { get; set; }
}
public static void HandleQueue()
{
Task.Factory.StartNew(() =>
{
while (true) if (queueCur.Count > ) HandleOrder();
});
} public static void HandleOrder()
{
while (queueCur.Count != )
{
Console.WriteLine("处理用户订单中:" + queueCur.Dequeue());
}
} }
class Program
{
static void Main()
{
ThreadBuy(); Console.WriteLine("----------操作完成----------");
Console.ReadKey();
} //秒杀
static void ThreadBuy()
{
System.Threading.Thread.Sleep();
var tt = new ThreadPar();
Parallel.For(, , (t, state) =>
{
var uid = "用户" + t;
var x = tt.Buy(uid);
if (x.Code == -)
{
Console.WriteLine(uid + ":" + x.Msg);
//state.Break();
}
else
{
Console.WriteLine(uid + ":" + x.Msg + "还剩下:" + x.Cnt + "件");
} }); } }
控制台程序
C#队列Queue实现一个简单的电商网站秒杀程序的更多相关文章
-
使用队列queue实现一个简单的生产者消费者模型
一.生产者消费者模型 我们去超市商店等地购买商品时,我们大部分人都会说自己是消费者,而超市的各大供货商.工厂等,自然而然地也就成了我们的生产者.如此一来,生产者有了,消费者也有了,那么将二者联系起来的 ...
-
用JS做一个简单的电商产品放大镜功能
使用js制作一个简单的产品放大图 购物网站的产品页经常会放有一个产品展示图区.该图区有一个功能就是产品图的放大功能,移动左侧的焦点区域,可以放大细节部分观看,详情如下图.实现该功能的方法也非常简单. ...
-
PHP大型电商网站秒杀思路
秒杀/抢购 技术:高可用,高并发 市场:用户体验,曝光度,促销 秒杀放单独服务器,这样即使崩溃不影响网站其他功能. 高可用:双活. 高并发:负载均衡,安全过滤. 阿里云:云监控 分流,CDN加速 业务 ...
-
[.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(二)
一步步打造一个简单的 MVC 电商网站 - BooksStore(二) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore 前: ...
-
[.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(三)
一步步打造一个简单的 MVC 电商网站 - BooksStore(三) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...
-
[.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(四)
一步步打造一个简单的 MVC 电商网站 - BooksStore(四) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...
-
[.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(一)
一步步打造一个简单的 MVC 电商网站 - BooksStore(一) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...
-
[.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(一) (转)
http://www.cnblogs.com/liqingwen/p/6640861.html 一步步打造一个简单的 MVC 电商网站 - BooksStore(一) 本系列的 GitHub地址:ht ...
-
如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念
一.前言 DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...
随机推荐
-
Angular JS的依赖注入
依赖注入是一个在组件中给出的替代了硬的组件内的编码它们的依赖关系的软件设计模式.这减轻一个组成部分,从定位的依赖,依赖配置.这有助于使组件可重用,维护和测试. AngularJS提供了一个至高无上的依 ...
-
【SpringMVC】SpringMVC系列5之@RequestHeader 映射请求头属性值
5.@RequestHeader 映射请求头属性值 5.1.概述 请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中 ...
-
第十九章——使用资源调控器管理资源(2)——使用T-SQL配置资源调控器
原文:第十九章--使用资源调控器管理资源(2)--使用T-SQL配置资源调控器 前言: 在前一章已经演示了如何使用SSMS来配置资源调控器.但是作为DBA,总有需要写脚本的时候,因为它可以重用及扩展. ...
-
【译】使用 Flutter 实现跨平台移动端开发
作者: Mike Bluestein | 原文地址:[https://www.smashingmagazine.com/2018/06/google-flutter-mobile-developm ...
-
es6 初级之展开运算符
1.1 先看一个求最大值的例子 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
-
20155229《网络对抗技术》Exp2:后门原理与实践
实验预习 后门: 指绕过安全控制而获取对程序或系统访问权的方法.最主要目的就是方便以后再次秘密进入或者控制系统. 木马与后门的区别: 木马:通过欺骗用户的方法(包含捆绑,利用网页等)让用户不知不觉的安 ...
-
在CentOS7上部署PostgreSQL11数据库系统
在数据库上的选择,也是基于了稳定性为前提.其实选择的范围并不是太大,基本可以选择的范围也就是SQLServer.MySQL.PostgreSQL这三种.SQL Server是微软的商业数据库,无论是性 ...
-
Microsoft Bot Builder Overview
微软机器人构建器概述 微软机器人Builder是一个强大的框架构建机器人可以处理*交互和更多的引导,这种可能性是显式地显示给用户. 它很容易使用和利用c#写机器人提供一个自然的方式. 高级功能: 强 ...
-
【UVA11419 训练指南】我是SAM 【二分图最小覆盖,最小割】
题意 给出一个R*C大小的网格,网格上面放了一些目标.可以在网格外发射子弹,子弹会沿着垂直或者水平方向飞行,并且打掉飞行路径上的所有目标.你的任务是计算最少需要多少子弹,各从哪些位置发射,才能把所有目 ...
-
code1174 靶形数独
主要是优化搜索顺序 从选择较少的点开始,可以大大提高效率 在search(x,y)找点的时候,对于一个空点(x y),设置一个评分score: score=min{ 横线x上能填的数字个数,竖线y上. ...