秒杀系统:并发队列 接口设计 并发请求数据安全处理

看秒杀系统的时候看到的关于并发队列的介绍,摘抄如下

  • 并发队列的选择

Java的并发包提供了三个常用的并发队列实现,分别是:ArrayBlockingQueue、ConcurrentLinkedQueue 和 LinkedBlockingQueue  。

ArrayBlockingQueue是初始容量固定的阻塞队列,我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品,那么我们就设定一个10大小的数组队列。

ConcurrentLinkedQueue使用的是CAS原语无锁队列实现,是一个异步队列入队的速度很快,出队进行了加锁,性能稍慢。

LinkedBlockingQueue也是阻塞的队列,入队和出队都用了加锁,当队空的时候线程会暂时阻塞。

在请求预处理阶段,由于我们的系统入队需求要远大于出队需求,一般不会出现队空的情况,所以我们可以选择ConcurrentLinkedQueue来作为我们的请求队列实现

1. 请求接口的合理设计

一个秒杀或者抢购页面,通常分为2个部分,一个是静态的HTML等内容,另一个就是参与秒杀的Web后台请求接口。

通常静态HTML等内容,是通过CDN的部署,一般压力不大,核心瓶颈实际上在后台请求接口上。这个后端接口,必须能够支持高并发请求,同时,非常重要的一点,必须尽可能“快”,在最短的时间里返回用户的请求结果。为了实现尽可能快这一点,接口的后端存储使用内存级别的操作会更好一点。仍然直接面向MySQL之类的存储是不合适的,如果有这种复杂业务的需求,都建议采用异步写入。

当然,也有一些秒杀和抢购采用“滞后反馈”,就是说秒杀当下不知道结果,一段时间后才可以从页面中看到用户是否秒杀成功。但是,这种属于“偷懒”行为,同时给用户的体验也不好,容易被用户认为是“暗箱操作”。

高并发下的数据安全

我们知道在多线程写入同一个文件的时候,会存现“线程安全”的问题(多个线程同时运行同一段代码,如果每次运行结果和单线程运行的结果是一样的,结果和预期相同,就是线程安全的)。如果是MySQL数据库,可以使用它自带的锁机制很好的解决问题,但是,在大规模并发的场景中,是不推荐使用MySQL的。秒杀和抢购的场景中,还有另外一个问题,就是“超发”,如果在这方面控制不慎,会产生发送过多的情况。我们也曾经听说过,某些电商搞抢购活动,买家成功拍下后,商家却不承认订单有效,拒绝发货。这里的问题,也许并不一定是商家奸诈,而是系统技术层面存在超发风险导致的。

1. 超发的原因

假设某个抢购场景中,我们一共只有100个商品,在最后一刻,我们已经消耗了99个商品,仅剩最后一个。这个时候,系统发来多个并发请求,这批请求读取到的商品余量都是99个,然后都通过了这一个余量判断,最终导致超发。(同文章前面说的场景)

在上面的这个图中,就导致了并发用户B也“抢购成功”,多让一个人获得了商品。这种场景,在高并发的情况下非常容易出现。

2. 悲观锁思路

解决线程安全的思路很多,可以从“悲观锁”的方向开始讨论。

悲观锁,也就是在修改数据的时候,采用锁定状态,排斥外部请求的修改。遇到加锁的状态,就必须等待。

虽然上述的方案的确解决了线程安全的问题,但是,别忘记,我们的场景是“高并发”。也就是说,会很多这样的修改请求,每个请求都需要等待“锁”,某些线程可能永远都没有机会抢到这个“锁”,这种请求就会死在那里。同时,这种请求会很多,瞬间增大系统的平均响应时间,结果是可用连接数被耗尽,系统陷入异常。

3. FIFO队列思路

那好,那么我们稍微修改一下上面的场景,我们直接将请求放入队列中的,采用FIFO(First Input First Output,先进先出),这样的话,我们就不会导致某些请求永远获取不到锁。看到这里,是不是有点强行将多线程变成单线程的感觉哈。

然后,我们现在解决了锁的问题,全部请求采用“先进先出”的队列方式来处理。那么新的问题来了,高并发的场景下,因为请求很多,很可能一瞬间将队列内存“撑爆”,然后系统又陷入到了异常状态。或者设计一个极大的内存队列,也是一种方案,但是,系统处理完一个队列内请求的速度根本无法和疯狂涌入队列中的数目相比。也就是说,队列内的请求会越积累越多,最终Web系统平均响应时候还是会大幅下降,系统还是陷入异常。

4. 乐观锁思路

这个时候,我们就可以讨论一下“乐观锁”的思路了。乐观锁,是相对于“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新。实现就是,这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。这样的话,我们就不需要考虑队列的问题,不过,它会增大CPU的计算开销。但是,综合来说,这是一个比较好的解决方案。

有很多软件和服务都“乐观锁”功能的支持,例如Redis中的watch就是其中之一。通过这个实现,我们保证了数据的安全。

时间: 2024-10-14 08:20:54

秒杀系统:并发队列 接口设计 并发请求数据安全处理的相关文章

Java秒杀系统方案优化---高性能高并发实战

Java秒杀系统方案优化---高性能高并发实战网盘地址:https://pan.baidu.com/s/1htNv2zq 密码: ssyt备用地址(腾讯微云):https://share.weiyun.com/889808c023b6e9d9f504399a5b07276f 密码:1WaUHB 亮眼的!高并发秒杀系统核心技术 课程以"秒杀"场景为例,但技术都是通用的,举一反三,方得始终应对大并发:多层次多粒度缓存+消息队列异步+服务器分布式部署 专业的压测工具:有依有据,鉴证系统的优化

电子商务系统的设计与实现(五):账务系统的功能接口设计

电商系统.p2p网贷系统.第三方支付都可以有自己的账务系统,账务系统与用户系统可以完全独立,不需要用户ID等信息,只提供给其它系统若干接口.服务可以用WebService的方式实现,对内提供服务非常方便,调用接口,就要调用普通的API一样.也可以做成HTTP的方式,外部使用相对麻烦一些.疑问:WebService提供的接口,可以直接用HTTP的方式调用么? 账务系统的功能接口设计 1.开户  可选输入:用户ID.账户资金类型(人民币.美元)  功能描述:创建一个账户.  理论上不需要存入用户的I

项目四:Java秒杀系统方案优化-高性能高并发实战

技术栈 前端:Thymeleaf.Bootstrap.JQuery 后端:SpringBoot.JSR303.MyBatis 中间件:RabbitMQ.Redis.Druid 功能模块 分布式会话,商品列表页,商品详情页,订单详情页,系统压测,缓存优化,消息队列,接口安全. 一.项目框架搭建 1.Spring Boot环境搭建 2.集成Thymeleaf,Result结果封装 3.集成Mybatis+Druid 4.集成Jedis+Redis安装+通用缓存Key封装 二.实现登录功能 1.数据库

Java秒杀系统方案优化 高性能高并发实战 视频教程

第1章 课程介绍及项目框架搭建 1-1 Java高并发商城秒杀优化导学 1-2 项目环境搭建(Eclipse) 1-3 项目环境搭建(IDEA) 1-4 集成mybatis 1-5 安装redis 1-6 集成redis上 1-7 集成redis中 1-8 集成redis下第2章 实现用户登录以及分布式session功能 2-1 两次md5 2-2 登录功能实现上 2-3 登录功能实现下 2-4 jsr303参数校验 2-5 异常处理 2-6 分布式session上 2-7 分布式session

PK2244-Java秒杀系统方案优化 高性能高并发实战

新年伊始,学习要趁早,点滴记录,学习就是进步! 随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到程序开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了.对于学习有困难不知道如何提升自己可以加扣:1225462853  获取资料. 下载地址:http://pan.baidu.com/s/1jI05TPW 谢谢大家的支持,我会努力给大家分享高质量教程 作者:源猿缘链接:https://www.jianshu.com/

格式文件读取&图形界面系统框架/应用接口设计

https://baobao.baidu.com/article/f3cb07d568d9f9b3bcc5d5bea73a7135.html https://baobao.baidu.com/article/2c48aa9d71e494e83cd8c8dfc5c75737.html https://baobao.baidu.com/article/f058f8db7b292a21f20682f2b479c21b.html https://baobao.baidu.com/article/b595

全流程开发 GO实战电商网站高并发秒杀系统

获取资源点击这里:全流程开发 GO实战电商网站高并发秒杀系统 第1章 课程介绍[学前须知] 本章对这门课程进行说明,包括:秒杀系统涉及模块的介绍,秒杀核心的知识点的介绍,课程的学习规划等. 1-1 课程介绍试看 第2章 需求整理&系统设计 [明确需求] 本章对秒杀系统整体需求进行梳理,明确系统具体需求,讲解系统原型设计工具的使用,并结合秒杀系统进行整体架构设计. 2-1 需求分析 2-2 系统架构设计 2-3 [总结&扩展]需求整理&系统设计 2-4 [勤于思考,夯实学习成果]阶段

PHP秒杀系统 高并发高性能的极致挑战

第1章 课程介绍秒杀系统在各种网站和应用中经常会用到.本课程从基本的系统设计和基础功能开始教导大家用PHP来设计和实现秒杀系统,并且为海量并发提供更高级的技术方案和实现手段.1-1 课程导学1-2 课程目标1-3 秒杀系统特点1-4 课程技术分析 第2章 系统技术选型分析本章节需要大家掌握基础的LNMP平台的开发,提供基础的数据封装类,让后续的开发得心应手.我们会讲解到系统环境的技术选型,我们采用的数据库是Mysql,还用到Redis来作为高性能缓存, 为了让大家不拘泥于框架的选择,巩固基础知识

php高并发秒杀系统的搭建总结思考(一)

秒杀系统大致分为三大块.客户端,服务器,后台管理.秒杀系统具有大流量高并发的特点. 对于web前端的处理,一般是页面静态化+CDN分布式缓存. 因为静态页面的处理速度是最快的.假设单台服务器nginx,1秒内可以处理的静态页面请求是1w,处理php程序可能是500每秒.这样在效率上就差很多.原因是php属于动态语言,服务器需要解释运行,这当中可能大量的I/O操作,加载扩展等.这就导致处理的时间比较长. 所以对于秒杀产品,一般都是在活动快要开始时,上线静态页面. 原文地址:https://blog