并发知识- (杂谈) 高并发高可用 VS 多线程正确性

本文最后更新于:5 个月前

写在前面

文章是学习并发编程的时候,觉得并发编程难学,想到什么情况下需要用到并发编程,然后想到了一些情况,故记录之

我认为最主要的两个场景应该是:

  1. 使用的人变多了,被迫需要高并发高可用

  2. 其次就是要将大任务进行一个拆分,需要使用多线程提高速度和效率

正文

假设我们现在有两个业务场景,一个是支付宝转账,一个是淘宝秒杀(抢火车票另说)

现在我们想想,哪个场景高可用高并发是要完全保证的,哪个场景是正确性优先的

这个时候你又会问了,为什么要有优先呢?不能两个都保证吗?

这里不讲原因,先摆事实:

你去支付宝还花呗或者微信提现的时候,是不是一般都会提示你,业务正在审核/处理,两个小时内完成/到帐,这个就是个铁证:

因为设计到转账,必须保证金额的正确性,加少了减少了谁负责?而对于并发量没有很高的要求(一不要求实时到账,二也没有那么多人会对同一个账户进行转账操作)

所以这些操作一般都是有一个最低时效,在时效内部,实际上是不保证操作的正确性的,例如:账也转了,钱也扣了,但是对方可能根本就没有收到,后台程序实际上还在处理后半部分的业务,这样就没有保证高可用(立刻响应,立刻处理完成),而完成了后面的业务处理之后,对方收到了款,才是一个真正的转账,最后才保证了正确性


然后就是淘宝秒杀,对于这个场景,高可用则肯定是需要完全保证的

你可能又会问了,那是不是就可以不保证正确性了呢?

那也不是,这里说的正确性是,不能多卖,说白了,库存100件,你也要保证最多只卖100件,不能多卖了

但是!

这样也不是说同时满足了高并发和完全正确性,只能说是部分的正确性,或者说对于原则行问题保证正确性(当然的,因为不能把程序写的有问题是写程序的起码要求),非原则问题在一定程度上牺牲正确性来实现高可用

什么叫一定程度上?

例如秒杀的时候,你可能会去用一个锁把查看库存,付款,扣库存这三个操作给锁住,保证多线程同步

那么如果是并发量不太大可能可以,但是并发量很大,那么很多付款就会一直阻塞,用户看不到付款的结果,体验很差,而且,服务器产生很多线程阻塞,可能 CPU 飙高乃至当机

一个可以的解决方法就是,设置会一个超时的锁,如果线程在设定好的时间范围内没有获取到锁,那么就直接返回,告诉用户付款超时,稍后再试

这样就是保证了服务器提供的服务是高可用的,因为不会产生大量线程阻塞,导致服务没有办法响应或者处理速度很慢,一定时间内没有拿到锁就返回失败结果,如果拿到锁,立刻处理完成就成功,说白了就是立刻响应,立刻处理

但是,实际上,服务器立刻响应,返回失败结果的时候,不是说库存卖完了,有可能库存还有,仅仅只是你没有获取到锁(买东西的资格),跟库存多少其实根本没关系,这个就是上面我理解的在一定范围内,牺牲非原则性正确性来保证服务的高可用