因为场景题还是比较多的,发现除非是自己真正做过的或非常熟悉的,不知道整体回答思路,只能想到哪里回答哪里,而且很多次发现不知道具体用什么工具,就给人的感觉是碰巧乱答的于是总结一下。
三个问题,分别是:
1.CPU 使用率达到 100%,怎么办?
2.QPS 从 1 万提升到 10 万怎么解决?
3.如何设计一个分布式锁
第一个是性能工具的学习,关于 top
直接输入一个 top 能查看各进程的 CPU 使用情况,top-H-p 进程号可以查看进程号下面的线程的CPU 使用情况,(这里大于 100 也是正常的数据因为一个线程可能使用多个核心。
具体第一个问题的回答
第一步 top 查看 CPU 使用情况,第二步查看使用 CPU 率高的进程的线程的 CPU 使用情况,第三步通过 perf 性能工具定位到热点函数,判断是忙等待,死循环,重复计算还是什么原因。
定位以后如果是重复计算死循环就需要优化代码,如果是忙等待可以使用异步处理。
针对第二个问题
这个问题的回答主要是考量到 QPS 增加可能导致瓶颈的原因有很多,网络 IO,数据库延迟,CPU 使用率,另外因为是具体场景题要有指标,要具体验证。
答:首先我会定位性能瓶颈,针对延迟要求和错误率要求,定位是 CPU 瓶颈,网络 IO 瓶颈,数据库还是因为其他问题。
如果是 CPU 瓶颈,使用 perf 定位到热点函数,判断是忙等待,重复计算还是死锁,进行优化。
如果是网络 IO 瓶颈,使用 epoll 和非阻塞模式处理,如果是因为任务堆积,考虑线程池模型更改去优化。
如果是因为数据库延迟,就考虑增加连接数,优化慢查询,分库分表减少数据库压力,横向扩展等方式。
最后是在监控日志,通过压测判断延迟和错误率是否达到要求。
第三个问题
使用 redis,这里使用 set lockkey value nx px time
的方式,nx 是代表没有这个 key 才设置,px 是设置过期时间。
设置 value 的意义是在区分不同的实例,不同的实例使用不同的 value,释放锁的时候通过 lua 脚本判断是同一个获取锁的实例在释放,才能允许释放,过期时间存在的意义是避免因为客户端宕机导致锁得不到释放,在实际使用过程中使用多实例的 Redis 申请锁避免因为一个 Redis 挂掉导致服务不可用。
这里除了这些还有一个叫做看门狗机制的东西,所谓的看门狗机制就是可能申请锁 30s,但是 30s 不能处理完,如果这时候锁被其他人获取,那这里就会有一个问题访问问题,所以需要提前续费,比如每 10s 去重新设置一次过期时间,只要自己还打算用。
总结 昨天学习的查看 coredump 的问题
主要流程是
1.编译时开启调试模型,关闭编译优化
2.调试
3.bt 查看堆栈信息
4.fRame 切换栈帧
5.info Locals 查看局部变量
6.p 查看更具体的
今天学到的主要是 top 查看进程,top-H-p 查看具体线程的 CPU 使用情况,perf 定位到热点函数,这里也可以结合 gdb 的堆栈信息,然后去分析问题。
对于 QPS 这个问题,基本上如果只要在自己的简历写过压测,感觉都会被提问,最开始面试的时候会被问 QPS 提升的问题,当时就是完全没有看过什么面经,不知道怎么回答,对于分布式限流这个主要是因为实习相关经历所以也被问到过。