知乎:
开源社区:
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);
}
}