关于高并发问题的点滴思考

问题背景:

曾经做过一个项目,医院预约挂号系统,挂号的话专家号很多人抢,这是一个高并发的问题,我以前针对专家号系统的解决方案就是直接在数据库MySQL上面加锁,简单有效,完美完成任务,但是这是针对并发量很少的情况,最近在思考,如果并发量很大的话,我的专家号系统模块应该怎么办呢?


专家号系统模块需要解决的问题:

1.瞬间高并发(很多人在同一时间抢购专家号)

2.超卖问题(防止出售超过库存数量的专家号)


高并发问题的解决方案:

提高系统的并发能力的方式主要有两种:垂直扩展和水平扩展,前者垂直扩展可以通过提升单机的硬件性能,或者提高单机的架构性能,来提高并发性,但是单机的性能总是有限的,所以高并发的终极解决方案还是水平扩展

(以下方案为自己暂时可以想到的方法,可能不成体系)


一.前端层设计(核心是请求拦截):

1.对于抢专家号系统的那个页面的立即抢购按钮,设置为只能点击一次,避免用户重复点击导致不断发送请求

2.限制一个用户在x秒之内只能发送一次抢购请求

3.同一个IP在x秒之内只能提交一个抢购请求


二.服务层设计(核心是充分利用缓存):

1.使用线程池,降低线程建立和销毁的开销

2.降低锁的粒度:为每个专家的专家号设置一个互斥锁,这样可以做到只有争抢同一个专家号的线程互斥,而不是所有线程互斥

3.采用消息队列缓存请求:后台根据自己的能力,从消息队列中主动的拉取请求消息进行处理,这样可以拦截大量的并发请求

4.用户请求预处理:如果所需的专家号没有了,那么就不用处理这个请求了,直接返回失败

5.利用缓存对于读请求:因为大部分请求是读请求,所以可以利用缓存分担数据库压力

6.利用缓存对于写请求:利用Redis作为中间件,把MySQL数据库中的专家号的那部分数据放入到Redis缓存中,所有的减少库存操作都在Redis中进行,然后再跟MySQL数据库进行数据同步


三.数据库层设计(核心是数据库的优化):

1.建立数据库链接池,降低数据库链接建立和销毁的开销

2.数据库优化

    *SQL语句优化

    *索引优化

    *数据库表结构优化(合适的数据类型,遵循三大范式,表的拆分)

    *配置系统的优化(增加TCP支持的队列数,增加缓存池的大小和数量)

    *硬件优化:多核心的高主频CPU,大的内存,高性能的磁盘


ps:还要一个最重要的,将专家号系统模块独立部署,避免该模块的高并发情况影响整个医院预约挂号系统的正常业务


超卖问题的解决方案

1.悲观锁:在一个线程修改数据的时候,采用锁定状态,排斥外部请求的修改

2.FIF0队列:同一商品的请求放入同一队列中,串行处理

3.乐观锁:采用带版本号的更新实现,也就是对这个数据而言所有的请求都有资格去修改,但是会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回失败


总结:以上的策略都是自己暂时可以想到的,等知识完善了再过来填坑,抢专家号系统模块目前正在改进中!



猜你喜欢

转载自www.cnblogs.com/yinbiao/p/10682535.html