目 录

  • 1. 高并发
  • 1.1 负载均衡
  • 1.2 池化技术
  • 1.3 流量过滤
  • 2. 高性能
  • 2.1 使用缓存
  • 2.2 磁盘问题处理
  • 3. 高可用
  • 3.1 采用微服务架构
  • 3.2 采用分布式+集群部署
  • 3.3 同城双活、异地多活
  • 3.4 主从切换
  • 3.5 熔断限流



首先要明确的一个概念是:

高并发是根因,而高性能和高可用是结果

通俗点来说,就是指为了解决高并发这一现象,怎么做,才能保证系统的高性能和高可用?

系统在巨大的流量洪峰(即指高并发场景)冲击下,依然能高效、稳定、正常地(即指高性能、高可用)对外提供服务,这是系统设计的主要目标之一。

具体的指标定义,如:高并发方面要求 QPS(Queries Per Second,每秒查询率) 大于 10 万,高性能方面要求请求延迟小于 100 ms,高可用方面要高于 99.99%。

1. 高并发

高并发问题:如果百万级别、千万级别甚至上亿级别的访问请求同时到来,系统怎么快速处理这些请求且能保证系统不崩溃?

基于上面的问题,从请求入口开始分析处理一个请求要用到哪些策略或者技术、方式。

1.1 负载均衡

当请求到来时,给到哪个服务去处理?这里涉及到请求的分发问题,采用负载均衡的方式处理,那么其对应的应用部署方式就得是集群化部署了。

1.2 池化技术

处理请求,由于请求多,做阻塞式处理肯定不行,因此采用多线程处理。

而多线程处理时如果涉及顺序问题或者一致性问题,要考虑对资源加锁处理。

线程的创建,需要消耗时间、消耗内存、消耗 CPU ,总结就是有开销,特别是大量创建线程时,开销更大;因此为了解决这个问题,用到池化技术

池化技术包括:线程池、连接池、内存池、对象池、协程池、进程池等

1.3 流量过滤

做好前置校验,对于非法的、不符合要求的请求,设计好过滤器进行过滤,在进行真正的业务逻辑处理之前,先对流量过滤一轮,减少并发压力。

过滤器:设计一套自己的规则,对过来的请求进行校验(如校验IP、校验请求参数是否合法等),如果不符合要求,直接拒绝,不进行后面的处理。

2. 高性能

系统性能不好,直接导致的问题就是处理请求耗时长,用户等待时间长,用户体验差。

系统性能影响的因素:

  • 用户网络环境
  • 请求/响应的数据包大小
  • 业务系统 CPU、内存、磁盘等性能
  • 业务链路的长度
  • 关系方系统的性能
  • 处理逻辑的代码实现是否高效… 等等

怎么提高系统的性能?

2.1 使用缓存

高并发场景下,对于查询操作,每次都去查数据库,会给数据库造成很大压力,导致性能下降,严重的直接就宕机了,所以这是要避免的,需要引入缓存,比如用 Redis 、MemCache去做缓存处理。

查询的时候,先去缓存中读,如果有结果就直接返回,没有再去数据库查,减少直接访问数据库的次数,并且读缓存的效率是比读数据库要高的。

2.2 磁盘问题处理

实际开发中,我们经常会在一些关键的地方,写上日志的打印语句,方便定位并排查问题。

不打日志的人,不是好人,绝非善类,十有八九是个坑爹的货,机智的你要知道速速远离。

我们打印出来的日志,最终还是会写到磁盘上保存起来,这里就涉及到了磁盘的 IO 读写问题。

不仅仅是写日志,包括其它涉及直接读或者写磁盘上文件的操作,都会有相同的问题。

磁盘读写的效率肯定是低于 CPU 或者 内存的处理效率的,而且磁盘本身也是有性能的问题存在。

所以可以这么处理:

  1. 磁盘升级,选用读写性能更好的磁盘,这里是硬件层次的处理
  2. 在写文件到磁盘上时,可以考虑先写到内存上,给内存设定一个阈值,当达到阈值时再批量将内存上的文件,写到磁盘上

3. 高可用

系统的高可用,更多的是从架构和部署方式去着手解决。

例如一个单体系统,所有业务模块都放到同一个系统中,当某一个模块坏掉,会导致整个系统坏掉,无法对外提供正常的服务,这就是不可用。

如果是微服务系统,每个模块都是独立的小系统,所有小系统共同组成一个微服务系统对外提供服务,一个小系统坏掉,并不会影响到其它小系统正常运行,而整体依旧可以对外提供服务,可用性比单体的更高。

保证系统可用性的策略或者方式,大致有下面这么些:

3.1 采用微服务架构

利用微服务架构,分散能力,使得各个模块独立成为一个小系统,降低系统间的耦合性,提高系统对外提供正常服务的能力。

3.2 采用分布式+集群部署

在高并发场景下,一个服务的部署,不应该只部署在一台服务器上,起码 3 台以上,这样,一台服务器宕机了,还有另外的服务器能正常使用并对外服务,这样就用到了集群的部署方式。

而采用微服务架构,也不应该把每个独立的小系统都部署在同一台服务器上,一个小系统就是一台服务器,这就使用了分布式部署。

将上面的两种部署方式结合起来用,先做分布式部署再为每个小系统拓展成为一个集群,就产生了分布式+集群部署。

3.3 同城双活、异地多活

这里是做灾备考虑,例如当前放置服务器的机房,由于温度过高,着火了,所有服务器都被烧掉,面对这样的情况,前面的架构设计得再好也无济于事。

基于上面可能存在的情况,就要考虑做同城双活或者异地多活了。

简单来说,就是多建几个同样的机房,并且这些机房分布在不同的地理位置,这样一个机房被烧掉了,另外的还能用,依旧保证了可用性。

3.4 主从切换

对于需要存储数据的应用,例如 Redis 、Mysql 等,做好主从复制,做好一主多从的设计和考虑,当主节点出问题时,从节点自动升级为新的主节点,对外服务。

3.5 熔断限流

熔断与限流,二者的目的都是提供过载保护,保证系统不至于崩溃,无法使用。

这里的过载保护,是指负载超过系统的承载能力时,系统需要自动采取保护措施,确保自身不被压垮、崩溃。

熔断:在系统濒临崩溃时,立即中断服务,停止所有请求的处理,保障系统稳定避免崩溃。类似于电器中的“保险丝”,当电流过大的时候,“保险丝”会先被烧掉,断开电流,以免电路过热烧毁电器引起火灾。

限流:原理跟熔断有点类似,都是通过判断某个条件来确定是否执行某个策略。

熔断与限流的区别:熔断,触发过载保护,该节点会暂停服务,直到恢复;限流,只处理自己能力范围之内的请求,超出范围的请求会被限流,并不会暂停服务。