这道面试题涉及的知识点比较多,主要考察的是面试者的综合技术能力。高并发系统的设计手段有很多,主要体现在以下五个方面。

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 子句中对字段进行表达式操作

  • 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型

④ 合理分库分表 ⑤ 使用数据库中间件实现数据库读写分离 ⑥ 设置数据库主从读写分离