高并发系统的挑战
在部署分布式系统时,我们通常把多个微服务部署在内网集群中,再用API网关聚合起来对外提供。为了做负载均衡,通常会对每个微服务都启动多个运行实例,通过注册中心去调用。
那么问题来了,因为有多个实例运行都是同一个应用,虽然微服务网关会把每一个请求只转发给一个实例,但当面对高并发时,但它们仍然可能同时操作同一个数据库表,这会不会引发什么问题呢?
悲观锁的问题
比如电商中常见的商品秒杀系统,在用户抢购商品过程中,会有大量并发请求,很可能同时读写一个包含商品剩余数量的表,这种一般要给数据库加锁,否则很容易出现商品超卖错卖的情况。
如果使用数据库自带的锁机制,也就是悲观锁,在写入的时候锁定数据库,其他修改请求到来时就必须等待锁释放,但这就使效率降下来了,而且高并发场景下可能有的请求一直抢不到锁,就会长时间卡在那导致请求失败,然后有大量重试,系统可能会发生连接数耗尽等异常。
乐观锁是个好东西
查阅资料发现乐观锁是个好东西,它是为数据库表增加一个标识数据版本的version字段来实现的,读取数据时把version字段一同读出,写入数据库时比对version字段就知道数据是否被更改过,如果version不相等就说明持有的是过期数据,不能写入,如果相等就可以写入,并把version加一。