解决超卖问题的几种方式
- 用redis实现,redis的java api设置分布式锁很简单,只是需要在设置分布式锁的逻辑加上watch dog逻辑也就是在加锁的逻辑中另起一个线程不断去判断当前设置的锁的失效时间是否快接近了,这个程度自己把握,一般都是走了三分之一的时候开始去做续期操作。但是当业务量大的时候需要使用redis集群,当一个线程加锁成功,key还没同步到slave上去master就挂了,另外一个服务还是能加锁成功,所以redis不能主从方案,这时候要采取redis独立部署加红锁,在第一个redis加锁成功后立刻去第二个redis加锁,直到过半redis加锁成功才算成功,否则算失败,但是这种方式也出现超卖,如果redis挂掉一台马上重启,这台redis没有加锁信息,其他服务还是能加锁,这种只能延迟重启redis
- zookeper+mysql 乐观锁 :这种加锁会很慢,不做考虑
- 不使用分布式锁,使用并行方案:这种是淘宝使用的,暂时还不知道怎么实现
用mysql实现,在mysql表中存储一张表专门记录加锁对象的id的记录,设置过期时间,当过期时间到了由mysql的计划任务自动删除记录,多个服务同时去请求锁会先访问数据库的这种表。这种方法缺点是mysql资源开销大,而且mysql一般都是集群部署,容易出现主从同步延迟问题,导致不同服务读取的结果不同
注意:这上面模拟超卖的工具是jmeter 做压力测试,可以抽时间熟悉下