这道面试题涉及的知识点比较多,主要考察的是面试者的综合技术能力。高并发系统的设计手段有很多,主要体现在以下五个方面。
1、前端层优化
① 静态资源缓存:将活动页面上的所有可以静态的元素全部静态化,尽量减少动态元素;通过 CDN、浏览器缓存,来减少客户端向服务器端的数据请求。
② 禁止重复提交:用户提交之后按钮置灰,禁止重复提交。
③ 用户限流:在某一时间段内只允许用户提交一次请求,比如,采取 IP 限流。
2、中间层负载分发
可利用负载均衡,比如 nginx 等工具,可以将并发请求分配到不同的服务器,从而提高了系统处理并发的能力。
nginx 负载分发的五种方式:
① 轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器不能正常响应,nginx 能自动剔除故障服务器。
② 按权重(weight)使用 weight 参数,指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况,配置如下:
upstream backend { server 192.168.0.14 weight=10; server 192.168.0.15 weight=10; }
③ IP 哈希值(ip_hash)每个请求按访问 IP 的哈希值分配,这样每个访客固定访问一个后端服务器,可以解决 session 共享的问题,配置如下:
upstream backend { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80; }
④ 响应时间(fair)按后端服务器的响应时间来分配请求,响应时间短的优先分配,配置如下:
upstream backend { fair; server server1.com; server server2.com; }
⑤ URL 哈希值(url_hash)按访问 url 的 hash 结果来分配请求,和 IP 哈希值类似。
upstream backend { hash $request_uri; server server1.com; server server2.com; }
3、控制层(网关层)优化
限制同一个用户的访问频率,限制访问次数,防止多次恶意请求。
4、服务层优化
① 业务服务器分离:比如,将秒杀业务系统和其他业务分离,单独放在高配服务器上,可以集中资源对访问请求抗压。
② 采用 MQ(消息队列)缓存请求:MQ 具有削峰填谷的作用,可以把客户端的请求先导流到 MQ,程序在从 MQ 中进行消费(执行请求),这样可以避免短时间内大量请求,导致服务器程序无法响应的问题。
③ 利用缓存应对读请求,比如,使用 Redis 等缓存,利用 Redis 可以分担数据库很大一部分压力。
5、数据库层优化
① 合理使用数据库引擎
② 合理设置事务隔离级别,合理使用事务
③ 正确使用数据库索引
- 尽量使用主键查询,而非其他索引,因为主键查询不会触发回表查询。
-
不做列运算,把计算都放入各个业务系统实现
-
查询语句尽可能简单,大语句拆小语句,减少锁时间
-
不使用 select * 查询
-
or 查询改写成 in 查询
-
不用函数和触发器
-
避免 %xx 查询
-
少用 join 查询
-
使用同类型比较,比如 '123' 和 '123'、123 和 123
-
尽量避免在 where 子句中使用 != 或者 <> 操作符,查询引用会放弃索引而进行全表扫描
-
列表数据使用分页查询,每页数据量不要太大
-
用 exists 替代 in 查询
-
避免在索引列上使用 is null 和 is not null
-
尽量使用主键查询
-
避免在 where 子句中对字段进行表达式操作
- 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型
④ 合理分库分表
⑤ 使用数据库中间件实现数据库读写分离
⑥ 设置数据库主从读写分离