众所周知,我们开发当中多多少少会遇到mysql死锁问题,这个也是大厂面试经常问的问题!
以mysql的InnoDB的默认的RR隔离级别来说。
-
死锁成因:不同事物相互等待对方的资源,形成环路
当两个事物相互等待对方的资源,可以设置InnoDB_lockWait_timeout.不会一直等待,而是超过这个设置的获取锁的等待时间就会自动进行回滚,使得另外一个事物正常执行
-
首先通过日志开始排查:
show engine innodb status
命令来记录死锁信息,但是这个命令优缺点,就是只能记录最近一次的死锁日志;所以我们还是开启mysql相关的系统参数来开始standard monitor
&lock monitor
,另外mysql还专门提供了用于死锁的监控set global innodb_print_all_deadlocks=ON
,然后从DBA那里拿到死锁日志,总而言之,需要结合业务代码和bin log 以及死锁日志分析; -
行锁:共享锁
S
,排它锁X
, 记录锁Record Lock
, 间隙锁Gap Lock
,临键锁Next Lock
, -
表级别锁,排他意向锁,共享意向锁
-
如何避免?不同事务SQL执行加锁顺序不一致,前后杂乱,最好按照主键顺序来,不要混乱交错,大事务化小,必要的时候可以降低InnoDB的事务隔离级别默认RR,可以适当降级为RC;建立合理的索引,不走索引往往会增加死锁的概率,合理设置
innodb_lockwait_timeout
,默认50秒当然也可以配置。
如果说client ACK丢失怎么办?
服务端会有重传机制这个次数默认5次,如果超过这个次数之后还未收到client的ACK就自动关闭建立连接,但是此时client端已经是SYN_ESTABLISH连接建立状态,但是我们server其实还是就绪状态SYN_RES,然后重传5次之后还未收到ACK的话就会自动管理连接求情,然后client发送数据就会返回一个指定的错误
TCP三次握手详解
TCP四次挥手详解
2MSL以及FIN丢失咋办
API网关层做了哪些事情?
可以做限流,包括请求频率和并发量做限制以及传输速率限流,然后返回的策略有:
- 拒接服务,做一个友好提示,给前端一个302重定向
- 加入等待队列,MQ可以起到削峰限流异步的作用
- 服务降级
网关层作为整个分布式系统的入口,承担了所有用户请求,在网关层限流也被称为接入层限流
如果使用nginx的相关指令很容易实现限流,limit_conn_zone,limit_requ_zone,limit_rate
;另一种解决方案是中间限流,将限流的逻辑下沉到服务层。除了使用Redis,其他的分布式中间件。
如果说网关层也进行集群部署呢?