那么处理这个 100 个并发请求也是绰绰有余的。
同样,如果是每秒 100 个并发请求源源不断的过来,那么很快就会抛出线程池满的异常:
解决套路其实是和 Tomcat 的情况差不多的,调参数,改系统,加异步。
这个情况下的并发,大多数系统还是抗住的。
面试官还可以接着追问:如果这时由于搞促销活动,系统流量翻了好倍,那你说这种情况下最先出现性能瓶颈的地方是什么?
最先出问题的地方肯定是数据库嘛,对吧。
那么怎么办?
分散压力。分库分表、读写分离这些东西往上套就完事了。
然后在系统入口的地方削峰填谷,引入缓存,如果可以,把绝大部分流量拦截在入口处。
对于拦不住的大批流量,关键服务节点还需要支持服务熔断、服务降级。
实在不行,加钱,堆机器。没有问题是不能通过堆机器解决的,如果有,那么就是你堆的机器不够多。
面试反正也就是这样的套路。看似一个发散性的题目,其实都是有套路可寻的。
好了,第一个角度我觉得我能想到的就是这么多了。
首先正面回答了面试官线程池设计的问题。
然后分情况聊了一下如果我们项目中没有用线程池,能不能直接抗住这 1000 的并发。
最后简单讲了一下突发流量的情况。
接下来,我们聊聊负载均衡。
负载均衡策略
我觉得这个考点虽然稍微隐藏了一下,但还是很容易就挖掘到的。
毕竟题目中已经说了:10 台机器。
而且我们也假设了平均 1 台处理 100 个情况。
这个假设的背后其实就是一个负载均衡策略:轮询负载均衡。
如果负载均衡策略不是轮询的话,那么我们前面的线程池队列长度设计也是有可能不成立的。
还是前面的场景,如果我们是运行在 Tomcat 容器中,假设前面是 nginx,那么 nginx 的负载均衡策略有如下几种:
- (加权)轮询负载均衡
- 随机负载均衡
- 最少连接数负载均衡
- 最小响应时间负载均衡
- ip_hash负载均衡
- url_hash负载均衡
如果是 RPC 服务,以 Dubbo 为例,有下面几种负载均衡策略:
- (加权)轮询负载均衡
- 随机负载均衡
- 最少活跃数负载均衡
- 最小响应时间负载均衡
- 一致性哈希负载均衡
哦,对了。记得之前还有一个小伙伴问我,在 Dubbo + zookeeper 的场景下,负载均衡是 Dubbo 做的还是 zk 做的?
肯定是 Dubbo 啊,朋友。源码都写在 Dubbo 里面的,zk 只是一个注册中心,关心的是自己管理着几个服务,和这几个服务的上下线。
你要用的时候,我把所有能用的都给你,至于你到底要用那个服务,也就是所谓的负载均衡策略,这不是 zk 关心的事情。
不扯远了,说回来。
假设我们用的是随机负载均衡,我们就不能保证每台机器各自承担 100 个请求了。
这时候我们前面给出的线程池设置就是不合理的。
常见的负载均衡策略对应的优缺点、适用场景可以看这个表格:
关于负载均衡策略,我的《吐血输出:2万字长文带你细细盘点五种负载均衡策略》这篇文章,写了 2 万多字,算是写的很清楚了,这里就不赘述了。
说起负载均衡,我还想起了之前阿里举办的一个程序设计大赛。赛题是《自适应负载均衡的设计实现》。
赛题的背景是这样的:
负载均衡是大规模计算机系统中的一个基础问题。灵活的负载均衡算法可以将请求合理地分配到负载较少的服务器上。
理想状态下,一个负载均衡算法应该能够最小化服务响应时间(RTT),使系统吞吐量最高,保持高性能服务能力。
自适应负载均衡是指无论处在空闲、稳定还是繁忙状态,负载均衡算法都会自动评估系统的服务能力,更好的进行流量分配,使整个系统始终保持较好的性能,不产生饥饿或者过载、宕机。
具体题目和获奖团队答辩可以看这里:
题目:https://tianchi.aliyun.com/competition/entrance/231714/information?spm=a2c22.12849246.1359729.1.6b0d372cO8oYGK 答辩:https://tianchi.aliyun.com/course/video?spm=5176.12586971.1001.1.32de8188ivjLZj&liveId=41090
推荐大家有兴趣的去看一下,还是很有意思的,可以学到很多的东西。