电商的秒杀和抢购,对程序员来说,都不是一个陌生的东西。然而,从技术的角度来说,这对于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实现一个简单的电商网站秒杀程序的更多相关文章

  1. 使用队列queue实现一个简单的生产者消费者模型

    一.生产者消费者模型 我们去超市商店等地购买商品时,我们大部分人都会说自己是消费者,而超市的各大供货商.工厂等,自然而然地也就成了我们的生产者.如此一来,生产者有了,消费者也有了,那么将二者联系起来的 ...

  2. 用JS做一个简单的电商产品放大镜功能

    使用js制作一个简单的产品放大图 购物网站的产品页经常会放有一个产品展示图区.该图区有一个功能就是产品图的放大功能,移动左侧的焦点区域,可以放大细节部分观看,详情如下图.实现该功能的方法也非常简单. ...

  3. PHP大型电商网站秒杀思路

    秒杀/抢购 技术:高可用,高并发 市场:用户体验,曝光度,促销 秒杀放单独服务器,这样即使崩溃不影响网站其他功能. 高可用:双活. 高并发:负载均衡,安全过滤. 阿里云:云监控 分流,CDN加速 业务 ...

  4. [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(二)

    一步步打造一个简单的 MVC 电商网站 - BooksStore(二) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore 前: ...

  5. [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(三)

    一步步打造一个简单的 MVC 电商网站 - BooksStore(三) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...

  6. [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(四)

    一步步打造一个简单的 MVC 电商网站 - BooksStore(四) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...

  7. [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(一)

    一步步打造一个简单的 MVC 电商网站 - BooksStore(一) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...

  8. [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(一) (转)

    http://www.cnblogs.com/liqingwen/p/6640861.html 一步步打造一个简单的 MVC 电商网站 - BooksStore(一) 本系列的 GitHub地址:ht ...

  9. 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念

    一.前言     DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...

随机推荐

  1. Go web编程实例

    1. go web编程入门 记录个web编程例子方便以后使用. 主要有: chan的使用(带缓存,不带缓存) client发起get/post请求 server解析get/post请求参数 http. ...

  2. Python学习笔记:Flask-Migrate基于model做upgrade的基本原理

      1)flask-migrate的官网:https://flask-migrate.readthedocs.io/en/latest/  2)获取帮助,在pycharm的控制台中输入 flask d ...

  3. centos7下使用rpm包安装clickhouse

    clickhouse是由俄罗斯Yandex公司开发的列式存储数据库,于2016年开源,clickhouse的定位是快速的数据分析,对于处理海量数据的情况性能非常好,在网上也有很多测试的案例,在大数据的 ...

  4. C++异常处理解析: 异常的引发(throw), 捕获(try catch)、异常安全

    前言: C++的异常处理机制是用于将运行时错误检测和错误处理功能分离的一 种机制(符合高内聚低耦合的软件工程设计要求),  这里主要总结一下C++异常处理的基础知识, 包括基本的如何引发异常(使用th ...

  5. Netty实战 - 1. 基本概念

    1. Netty简介 Netty是由JBOSS提供的一个java开源框架.它提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.Netty是一个基于NI ...

  6. debian linux sudo 无法执行以添加普通用户到sudo

    安装debian时,默认创建了root用户,和一个普通用户: 用普通用户登录电脑,无法执行sudo命令: 查看 /etc/sudoers 无此文件: 那么说明,本机没有安装sudo 解决方式: 终端 ...

  7. 每天一个linux命令(9):touch

    1.命令简介 touch命令将每个文件的访问时间和修改时间改为当前时间. 2.用法 touch [选项]... 文件... 3.选项 -a 只更改访问时间 -c, --no-create 不创建任何文 ...

  8. 分析轮子(二)- << ,>>,>> (左移、右移、无符号右移)

    前言:写 分析轮子(一)-ArrayList.java 的时候看到源码中有 int newCapacity = oldCapacity + (oldCapacity >> 1); 这样的代 ...

  9. apache中如何调用CGI脚本

    参考: http://www.jdon.com/idea/cgi.htm http://www.jb51.net/article/49069.htm 在Apache在配置对CGI的支持 LoadMod ...

  10. Linux报swap空间占用过高,但物理内存还有空余

    收到报警,swap空间占用过高,登录到系统查看内存使用详情,看到物理内存还有很多未使用 问题分析 Swap配置对性能的影响分配太多的Swap空间会浪费磁盘空间,而Swap空间太少,则系统会发生错误.如 ...