知乎:
开源社区:
1) 客户端通过算法进行过滤
2) 负载均衡分配
3) 队列计数
4) 秒杀完成,更新数据库
他人代码参考:
public ActionResult SecKill() { //双十一那天的秒杀活动, //早上11点钟的有611个名额,下午三点钟的有500个名额 int totalPlaces = 0;//名额 DateTime time11 = new DateTime(2015, 11, 11, 11, 0, 0); DateTime time15 = new DateTime(2015, 11, 11, 18, 0, 0); //根据时间获取队列的最大的容量 if(time11<DateTime.Now&&DateTime.Now<time15) { totalPlaces = 611; }else if(DateTime.Now>time15) { totalPlaces = 500; } SecKillQueue q = new SecKillQueue(totalPlaces);//创建队列 //入队 while (!q.IsFull()) { q.In(SessionContext.User.UserId); int count = totalPlaces - q.GetQueueLength(); return Json(new { leftCount=count });//返回剩下的名额 } //根据队列中保存的用户ID,异步往Consume表插入记录 Task.Run(() => InsertToConsume(q)); return Json(new { ret = 1, msg = "秒杀结束" }); }
public static void InsertToConsume(SecKillQueue q) { //出列 while (!q.IsEmpty()) { int userId = (int)q.Out(); User user = UserServices.GetItemById(userId); //这里还要判断当前出列的用户是否已经参与参与过秒杀活动了, //如果有的话就忽略,并且还要把名额重新添加到队列 Consume consume = new Consume() { WorkShopID = user.IsWorkShop == 2 ? (int)user.WorkShopID : user.Id, SerialNumber = PromotionHelper.getOrderCode() + "-" + new Random().Next(100000, 999999), Amount = 110, ConsumeType = 1, //本金预存 PayStatus = 0 //未支付 }; ConsumeServices.Insert(consume); } }