[toc]

一、什么是高并发

高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。

  • 响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。
  • 吞吐量:单位时间内处理的请求数量。
  • QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。
  • 并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。

二、如何提升系统的并发能力

加机器的方式就不说了,花钱就完事了

2.0 常见的互联网分层架构

常见互联网分布式架构如上,分为:

(1)客户端层:典型调用方是浏览器browser或者手机应用APP

(2)反向代理层:系统入口,反向代理

(3)站点应用层:实现核心应用逻辑,返回html或者json

(4)服务层:如果实现了服务化,就有这一层

(5)数据-缓存层:缓存加速访问存储

(6)数据-数据库层:数据库固化数据存储

2.1 客户端提升性能

  1. 资源静态化 - 使用服务端渲染
  2. 采用cdn , 加快动态资源加载

一些小点:

  1. 减少http请求
  2. 使用浏览器的缓存
  3. 减少单个请求的数据传输

2.2 代理层的水平扩展

image-20220724111926516

反向代理层的水平扩展,是通过“DNS轮询”实现的:dns-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问dns-server,会轮询返回这些ip。

当nginx成为瓶颈的时候,只要增加服务器数量,新增nginx服务的部署,增加一个外网ip,就能扩展反向代理层的性能,做到理论上的无限高并发。

(有多个NG的情况下)

优化ng的一些小细节,比如:

  1. 启用压缩
  2. 使用长链接
  3. 增加worker数

NG是七层模型中的第七层-应用层 , 所以又称它为七层负载, 因此性能会有一定的损耗

LVS(Linux Virtual Server: Linux虚拟服务器) 是七层模型中的第四层-网络层 , 所以又称它为四层负载, 因此性能会更高

LVS 是在网络栈的四层做请求包的转发,请求包转发之后,由客户端和后端服务直接建立连接,后续的响应包不会再经过 LVS 服务器,所以性能更高, LVS 缺陷是工作在四层,而请求的 URL 是七层的概念,不能针对 URL 做更细致地请求分发,而且 LVS 也没有提供探测后端服务是否存活的机制

如果你的 QPS 在十万以内,那么可以考虑不引入LVS 而直接使用 Nginx 作为唯一的负载均衡服务器

来源: 《阿里亿级高并发系统设计》

主流软件负载均衡器对比(LVS、Nginx、HAproxy) - 知乎 (zhihu.com)

LVS负载均衡(LVS简介、三种工作模式、十种调度算法)_chenhuyang的博客-CSDN博客_lvs负载均衡

详情见 优化秒杀过程

2.3 站点层的水平扩展

image-20220724111529009

站点层的水平扩展,是通过“nginx”实现的。通过修改nginx.conf,可以设置多个web后端

当web后端成为瓶颈的时候,只要增加服务器数量,新增web服务的部署,在nginx配置中配置上新的web后端,就能扩展站点层的性能,做到理论上的无限高并发。

(单个NG或者分发到具体某个NG时)

2.4 服务层

image-20220818152236010

服务层的水平扩展,是通过“服务连接池”实现的。

站点层通过RPC-client调用下游的服务层RPC-server时,RPC-client中的连接池会建立与下游服务多个连接,当服务成为瓶颈的时候,只要增加服务器数量,新增服务部署,在RPC-client处建立新的下游服务连接,就能扩展服务层性能,做到理论上的无限高并发。用上Eruka之类的服务注册发现功能,使用多节点容灾

除了水平扩展还有缓存和异步

缓存:

下个标题会讲解

异步:

  1. 引入消息队列从业务级别 解耦 耗时或并发高的功能
  2. 在代码中使用多线程到达异步能力

还有很多代码细节,比如

  1. 提升gateway的性能, 改用netty容器启动 , 并设定工作线程和 select(选择)线程数
  2. 增加tomcat连接数, 超时时间等
  3. fegin调用采用okhttp的方式,并使用长链接
  4. 优化jvm
  5. 代码中使用异步,线程池等, 代码质量良好
  6. 数据库的链接池
  7. 单sql执行, 不阻塞数据库, 提高据库的qps
  8. 避免数据库的长事务

详情见 优化秒杀过程

2.5 数据层的水平扩展

在数据量很大的情况下,数据层(缓存,数据库)涉及数据的水平扩展,将原本存储在一台服务器上的数据(缓存,数据库)水平拆分到不同服务器上去,以达到扩充系统性能的目的。

2.5.1 缓存

使用redis之类的缓存数据库,减少与数据库的交互

一些优化细节,比如:

  1. 尽量避免大key
  2. 减少redis的访问次数, 使用mget和管道
  3. 使用netty链接池

2.5.2 数据库

  1. 使用读写分离 , 分库分表等操作提高数据库的效率

  2. 引入es, 将复杂查询或者全文类查询通过es来实现

数据库本身的优化,比如:

  1. 数据库自身的连接池
  2. 超时时间
  3. sql要命中索引

https://blog.csdn.net/weixin_42476601/article/details/82220027