精华内容
下载资源
问答
  • 软件开发通常会提到一个名词 “三高”,即并发、性能、高可用。 具体的指标定义,如:并发方面要求QPS 大于 10万;性能方面要求请求延迟小于 100 ms;高可用方面要高于 99.99%。 接下来,我们重点来介绍这...

    软件开发通常会提到一个名词 “三高”,即高并发、高性能、高可用。

    具体的指标定义,如:高并发方面要求QPS 大于 10万;高性能方面要求请求延迟小于 100 ms;高可用方面要高于 99.99%。

    接下来,我们重点来介绍这 三高

     

    高并发

    我们使用 QPS(Queries Per Second,每秒查询率)来衡量系统承载能力。架构策略有哪些?

     

    1、负载均衡

    正所谓双拳难敌四手,高并发撑场面的首选方案就是集群化部署,一台服务器承载的QPS有限,多台服务器叠加效果就不一样了。

    如何将流量转发到服务器集群,这里面就要用到负载均衡,比如:LVS 和 Nginx。

    常用的负载算法有轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小连接数法等

    业务实战:对于千万级流量的秒杀业务,一台LVS扛不住流量洪峰,通常需要 10 台左右,其上面用DDNS(Dynamic DNS)做域名解析负载均衡。搭配高性能网卡,单台LVS能够提供百万以上并发能力。

    注意, LVS 负责网络四层协议转发,无法按 HTTP 协议中的请求路径做负载均衡,所以还需要 Nginx

    2、池化技术

    复用单个连接无法承载高并发,如果每次请求都新建连接、关闭连接,考虑到TCP的三次握手、四次挥手,有时间开销浪费。池化技术的核心是资源的“预分配”和“循环使用”,常用的池化技术有线程池、进程池、对象池、内存池、连接池、协程池。

    连接池的几个重要参数:最小连接数、空闲连接数、最大连接数

    Linux 内核中是以进程为单元来调度资源的,线程也是轻量级进程。所以说,进程、线程都是由内核来创建并调度。协程是由应用程序创建出来的任务执行单元,比如 Go 语言中的协程“goroutine”。协程本身是运行在线程上,由应用程序自己调度,它是比线程更轻量的执行单元。

     

    在 Go 语言中,一个协程初始内存空间是 2KB(Linux 下线程栈大小默认是 8MB),相比线程和进程来说要小很多。协程的创建和销毁完全是在用户态执行的,不涉及用户态和内核态的切换。另外,协程完全由应用程序在用户态下调用,不涉及内核态的上下文切换。协程切换时由于不需要处理线程状态,需要保存的上下文也很少,速度很快。

    Go语言中协程池的实现方法有两种:抢占式和调度式。

    • 抢占式协程池,所有任务存放到一个共享的 channel 中,多个协程同时去消费 channel 中的任务,存在锁竞争。

    • 调度式协程池,每个协程都有自己的 channel,每个协程只消费自己的 channel。下发任务的时候,采用负载均衡算法选择合适的协程来执行任务。比如选择排队中任务最少的协程,或者简单轮询。

    3、流量漏斗

    上面讲的是正向方式提升系统QPS,我们也可以逆向思维,做减法,拦截非法请求,将核心能力留给正常业务!

    互联网高并发流量并不都是纯净的,也有很多恶意流量(比如黑客攻击、恶意爬虫、黄牛、秒杀器等),我们需要设计流量拦截器,将那些非法的、无资格的、优先级低的流量过滤掉,减轻系统的并发压力。

    拦截器分层:

    • 网关和 WAF(Web Application Firewall,Web 应用防火墙)

    采用封禁攻击者来源 IP、拒绝带有非法参数的请求、按来源 IP 限流、按用户 ID 限流等方法

    • 风控分析。借助大数据能力分析订单等历史业务数据,对同ip多个账号下单、或者下单后支付时间过快等行为有效识别,并给账号打标记,提供给业务团队使用。

    • 下游的每个tomcat实例应用本地内存缓存化,将一些库存存储在本地一份,做前置校验。当然,为了尽量保持数据的一致性,有定时任务,从 Redis 中定时拉取最新的库存数据,并更新到本地内存缓存中。

       

       

       

    高性能

    性能直接影响用户的感官体验,访问一个系统,如果超过5秒没有响应,绝大数用户会选择离开。

    那么有哪些因素会影响系统的性能呢?

    • 用户网络环境

    • 请求/响应的数据包大小

    • 业务系统 CPU、内存、磁盘等性能

    • 业务链路的长度

    • 下游系统的性能

    • 算法实现是否高效

    当然,随着并发数的提升,系统压力增大,平均请求延迟也会增大。

    1、高性能缓存

    对一些热点数据每次都从 DB 中读取,会给 DB 带来较大的压力,导致性能大幅下降。所以,我们需要用缓存来提升热点数据的访问性能,比如将活动信息数据在浏览器的缓存中保存一段时间。

    缓存根据性能由高到低分为:寄存器、L1缓存、L2缓存、L3缓存、本地内存、分布式缓存

    上层的寄存器、L1 缓存、L2 缓存是位于 CPU 核内的高速缓存,访问延迟通常在 10 纳秒以下。L3 缓存是位于 CPU 核外部但在芯片内部的共享高速缓存,访问延迟通常在十纳秒左右。高速缓存具有成本高、容量小的特点,容量最大的 L3 缓存通常也只有几十MB。

    本地内存是计算机内的主存储器,相比 CPU 芯片内部的高速缓存,内存的成本要低很多,容量通常是 GB 级别,访问延迟通常在几十到几百纳秒。

    内存和高速缓存都属于掉电易失的存储器,如果机器断电了,这类存储器中的数据就丢失了。

    特别说明:在使用缓存时,要注意缓存穿透、缓存雪崩、缓存热点问题、缓存数据一致性问题。当然为了提升整体性能通常会采用多级缓存组合方案(浏览器缓存+服务端本地内存缓存+服务端网络内存缓存)

    2、日志优化,避免IO瓶颈

    当系统处理大量磁盘 IO 操作的时候,由于 CPU 和内存的速度远高于磁盘,可能导致 CPU 耗费太多时间等待磁盘返回处理的结果。对于这部分 CPU 在 IO 上的开销,我们称为 “iowait”。

    在IO中断过程中,如果此时有其他任务线程可调度,系统会直接调度其他线程,这样 CPU 就相应显示为 Usr 或 Sys;但是如果此时系统较空闲,无其他任务可以调度,CPU 就会显示为 iowait(实际上与 idle 无本质区别)。

    磁盘有个性能指标:IOPS,即每秒读写次数,性能较好的固态硬盘,IOPS 大概在 3 万左右。对于秒杀系统,如果单节点QPS在10万,每次请求产生3条日志,那么日志的写入QPS在 30W/s,磁盘根本扛不住。

    Linux 有一种特殊的文件系统:tmpfs(临时文件系统),它是一种基于内存的文件系统,由操作系统管理。当我们写磁盘的时候实际是写到内存中,当日志文件达到我们的设置阈值,操作系统会将日志写到磁盘中,并将tmpfs中的日志文件删除。

    这种批量化、顺序写,大大提升了磁盘的吞吐性能!

     

    高可用

    高可用指标是指用来衡量一个系统可用性有多高。

    • MTBF(Mean Time Between Failure),系统可用时长

    • MTTR(Mean Time To Repair),系统从故障后到恢复正常所耗费的时间

    • SLA(Service-Level Agreement),服务等级协议,用于评估服务可用性等级。计算公式是 MTBF/(MTBF+MTTR)

    一般我们所说的可用性高于 99.99%,是指 SLA 高于 99.99%。

    技术架构,高可用有哪些策略?

    • 多云架构、异地多活、异地备份

    • 主备切换,如redis缓存、mysql数据库,主备节点会实时数据同步、备份。如果主节点不可用,自动切换到备用节点

    • 微服务,无状态化架构,业务集群化部署,有心跳检测,能最短时间检测到不可用的服务。

    • 通过熔断、限流,解决流量过载问题,提供过载保护

    • 重视web安全,解决攻击和XSS问题

    1、主备切换,缩减故障时间

    当系统出现故障时,首要任务不是立马查找原因,考虑到故障的复杂样,定位排查要花些时间,等问题修复好,SLA也降了好几个档。有没有更快的方式解决这个问题?那就是故障转移。

    当发现故障节点的时候,不是尝试修复它,而是立即把它隔离,同时将流量转移到正常节点上。这样通过故障转移,不仅减少了 MTTR 提升了 SLA,还为修复故障节点赢得了足够的时间。

    主备切换大致分为三步:

    • 第一步故障自动侦测(Auto-detect),采用健康检查、心跳等技术手段自动侦测故障节点;

    • 第二步自动转移(FailOver),当侦测到故障节点后,采用摘除流量、脱离集群等方式隔离故障节点,将流量转移到正常节点;

    • 第三步自动恢复(FailBack),当故障节点恢复正常后,自动将其加入集群中,确保集群资源与故障前一致。

    2、熔断,提供过载保护

    所谓过载保护,是指负载超过系统的承载能力时,系统会自动采取保护措施,确保自身不被压垮。

    熔断就是在系统濒临崩溃的时候,立即中断服务,从而保障系统稳定避免崩溃。它类似于电器中的“保险丝”,当电流过大的时候,“保险丝”会先被烧掉,断开电流,以免电路过热烧毁电器引起火灾。

    例子:熔断触发条件往往跟系统节点的承载能力和服务质量有关,比如 CPU 的使用率超过 90%,请求错误率超过 5%,请求延迟超过 500ms, 它们中的任意一个满足条件就会出现熔断。

    3、限流,提供过载保护

    限流的原理跟熔断有点类似,都是通过判断某个条件来确定是否执行某个策略。但是又有所区别,熔断触发过载保护,该节点会暂停服务,直到恢复。限流,则是只处理自己能力范围之内的请求,超量的请求会被限流。

    限流算法主要有:计数器限流、滑动窗口限流、令牌桶限流、漏桶限流。网上的资料很多,这里就不多赘述。

    4、降级

    比如电商大促,业务在峰值时刻,系统抵挡不住全部的流量时,系统的负载、CPU 的使用率都超过了预警水位,可以对一些非核心的功能进行降级,降低系统压力,比如把商品评价成交记录等功能临时关掉。弃车保帅保证 创建订单、支付 等核心功能的正常使用

    当然不同业务、不同公司处理方式也各不相同,需要结合实际场景,和业务方一块讨论,最后达成一个统一认可的降级方案。

    总结下来:降级是通过暂时关闭某些非核心服务或者组件从而保护核心系统的可用性

    展开全文
  • 软件开发通常会提到一个名词 “三高”,即并发、性能、高可用。 具体的指标定义,如:并发方面要求QPS 大于 10万;性能方面要求请求延迟小于 100 ms;高可用方面要高于 99.99%。 接下来,我们重点来介绍这...

    知识分享,以技会友。大家好,我是Tom哥。阅读本文大约需要 15 分钟。

    软件开发通常会提到一个名词 “三高”,即高并发、高性能、高可用。

    具体的指标定义,如:高并发方面要求QPS 大于 10万;高性能方面要求请求延迟小于 100 ms;高可用方面要高于 99.99%。

    接下来,我们重点来介绍这 三高

     

    高并发

     

    我们使用 QPS(Queries Per Second,每秒查询率)来衡量系统承载能力。架构策略有哪些?

     

    1、负载均衡

    正所谓双拳难敌四手,高并发撑场面的首选方案就是集群化部署,一台服务器承载的QPS有限,多台服务器叠加效果就不一样了。

    如何将流量转发到服务器集群,这里面就要用到负载均衡,比如:LVS 和 Nginx。

    常用的负载算法有轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小连接数法等

    业务实战:对于千万级流量的秒杀业务,一台LVS扛不住流量洪峰,通常需要 10 台左右,其上面用DDNS(Dynamic DNS)做域名解析负载均衡。搭配高性能网卡,单台LVS能够提供百万以上并发能力。

    注意, LVS 负责网络四层协议转发,无法按 HTTP 协议中的请求路径做负载均衡,所以还需要 Nginx

    2、池化技术

    复用单个连接无法承载高并发,如果每次请求都新建连接、关闭连接,考虑到TCP的三次握手、四次挥手,有时间开销浪费。池化技术的核心是资源的“预分配”和“循环使用”,常用的池化技术有线程池、进程池、对象池、内存池、连接池、协程池。

    连接池的几个重要参数:最小连接数、空闲连接数、最大连接数

    Linux 内核中是以进程为单元来调度资源的,线程也是轻量级进程。所以说,进程、线程都是由内核来创建并调度。协程是由应用程序创建出来的任务执行单元,比如 Go 语言中的协程“goroutine”。协程本身是运行在线程上,由应用程序自己调度,它是比线程更轻量的执行单元。

     

    在 Go 语言中,一个协程初始内存空间是 2KB(Linux 下线程栈大小默认是 8MB),相比线程和进程来说要小很多。协程的创建和销毁完全是在用户态执行的,不涉及用户态和内核态的切换。另外,协程完全由应用程序在用户态下调用,不涉及内核态的上下文切换。协程切换时由于不需要处理线程状态,需要保存的上下文也很少,速度很快。

    Go语言中协程池的实现方法有两种:抢占式和调度式。

    • 抢占式协程池,所有任务存放到一个共享的 channel 中,多个协程同时去消费 channel 中的任务,存在锁竞争。

    • 调度式协程池,每个协程都有自己的 channel,每个协程只消费自己的 channel。下发任务的时候,采用负载均衡算法选择合适的协程来执行任务。比如选择排队中任务最少的协程,或者简单轮询。

    3、流量漏斗

    上面讲的是正向方式提升系统QPS,我们也可以逆向思维,做减法,拦截非法请求,将核心能力留给正常业务!

    互联网高并发流量并不都是纯净的,也有很多恶意流量(比如黑客攻击、恶意爬虫、黄牛、秒杀器等),我们需要设计流量拦截器,将那些非法的、无资格的、优先级低的流量过滤掉,减轻系统的并发压力。

    拦截器分层:

    • 网关和 WAF(Web Application Firewall,Web 应用防火墙)

    采用封禁攻击者来源 IP、拒绝带有非法参数的请求、按来源 IP 限流、按用户 ID 限流等方法

    • 风控分析。借助大数据能力分析订单等历史业务数据,对同ip多个账号下单、或者下单后支付时间过快等行为有效识别,并给账号打标记,提供给业务团队使用。

    • 下游的每个tomcat实例应用本地内存缓存化,将一些库存存储在本地一份,做前置校验。当然,为了尽量保持数据的一致性,有定时任务,从 Redis 中定时拉取最新的库存数据,并更新到本地内存缓存中。

       

    高性能

     

    性能直接影响用户的感官体验,访问一个系统,如果超过5秒没有响应,绝大数用户会选择离开。

    那么有哪些因素会影响系统的性能呢?

    • 用户网络环境

    • 请求/响应的数据包大小

    • 业务系统 CPU、内存、磁盘等性能

    • 业务链路的长度

    • 下游系统的性能

    • 算法实现是否高效

    当然,随着并发数的提升,系统压力增大,平均请求延迟也会增大。

    1、高性能缓存

    对一些热点数据每次都从 DB 中读取,会给 DB 带来较大的压力,导致性能大幅下降。所以,我们需要用缓存来提升热点数据的访问性能,比如将活动信息数据在浏览器的缓存中保存一段时间。

    缓存根据性能由高到低分为:寄存器、L1缓存、L2缓存、L3缓存、本地内存、分布式缓存

    上层的寄存器、L1 缓存、L2 缓存是位于 CPU 核内的高速缓存,访问延迟通常在 10 纳秒以下。L3 缓存是位于 CPU 核外部但在芯片内部的共享高速缓存,访问延迟通常在十纳秒左右。高速缓存具有成本高、容量小的特点,容量最大的 L3 缓存通常也只有几十MB。

    本地内存是计算机内的主存储器,相比 CPU 芯片内部的高速缓存,内存的成本要低很多,容量通常是 GB 级别,访问延迟通常在几十到几百纳秒。

    内存和高速缓存都属于掉电易失的存储器,如果机器断电了,这类存储器中的数据就丢失了。

    特别说明:在使用缓存时,要注意缓存穿透、缓存雪崩、缓存热点问题、缓存数据一致性问题。当然为了提升整体性能通常会采用多级缓存组合方案(浏览器缓存+服务端本地内存缓存+服务端网络内存缓存)

    2、日志优化,避免IO瓶颈

    当系统处理大量磁盘 IO 操作的时候,由于 CPU 和内存的速度远高于磁盘,可能导致 CPU 耗费太多时间等待磁盘返回处理的结果。对于这部分 CPU 在 IO 上的开销,我们称为 “iowait”。

    在IO中断过程中,如果此时有其他任务线程可调度,系统会直接调度其他线程,这样 CPU 就相应显示为 Usr 或 Sys;但是如果此时系统较空闲,无其他任务可以调度,CPU 就会显示为 iowait(实际上与 idle 无本质区别)。

    磁盘有个性能指标:IOPS,即每秒读写次数,性能较好的固态硬盘,IOPS 大概在 3 万左右。对于秒杀系统,如果单节点QPS在10万,每次请求产生3条日志,那么日志的写入QPS在 30W/s,磁盘根本扛不住。

    Linux 有一种特殊的文件系统:tmpfs(临时文件系统),它是一种基于内存的文件系统,由操作系统管理。当我们写磁盘的时候实际是写到内存中,当日志文件达到我们的设置阈值,操作系统会将日志写到磁盘中,并将tmpfs中的日志文件删除。

    这种批量化、顺序写,大大提升了磁盘的吞吐性能!

     

    高可用

     

    高可用指标是指用来衡量一个系统可用性有多高。

    • MTBF(Mean Time Between Failure),系统可用时长

    • MTTR(Mean Time To Repair),系统从故障后到恢复正常所耗费的时间

    • SLA(Service-Level Agreement),服务等级协议,用于评估服务可用性等级。计算公式是 MTBF/(MTBF+MTTR)

    一般我们所说的可用性高于 99.99%,是指 SLA 高于 99.99%。

    技术架构,高可用有哪些策略?

    • 多云架构、异地多活、异地备份

    • 主备切换,如redis缓存、mysql数据库,主备节点会实时数据同步、备份。如果主节点不可用,自动切换到备用节点

    • 微服务,无状态化架构,业务集群化部署,有心跳检测,能最短时间检测到不可用的服务。

    • 通过熔断、限流,解决流量过载问题,提供过载保护

    • 重视web安全,解决攻击和XSS问题

    1、主备切换,缩减故障时间

    当系统出现故障时,首要任务不是立马查找原因,考虑到故障的复杂样,定位排查要花些时间,等问题修复好,SLA也降了好几个档。有没有更快的方式解决这个问题?那就是故障转移。

    当发现故障节点的时候,不是尝试修复它,而是立即把它隔离,同时将流量转移到正常节点上。这样通过故障转移,不仅减少了 MTTR 提升了 SLA,还为修复故障节点赢得了足够的时间。

    主备切换大致分为三步:

    • 第一步故障自动侦测(Auto-detect),采用健康检查、心跳等技术手段自动侦测故障节点;

    • 第二步自动转移(FailOver),当侦测到故障节点后,采用摘除流量、脱离集群等方式隔离故障节点,将流量转移到正常节点;

    • 第三步自动恢复(FailBack),当故障节点恢复正常后,自动将其加入集群中,确保集群资源与故障前一致。

    2、熔断,提供过载保护

    所谓过载保护,是指负载超过系统的承载能力时,系统会自动采取保护措施,确保自身不被压垮。

    熔断就是在系统濒临崩溃的时候,立即中断服务,从而保障系统稳定避免崩溃。它类似于电器中的“保险丝”,当电流过大的时候,“保险丝”会先被烧掉,断开电流,以免电路过热烧毁电器引起火灾。

    例子:熔断触发条件往往跟系统节点的承载能力和服务质量有关,比如 CPU 的使用率超过 90%,请求错误率超过 5%,请求延迟超过 500ms, 它们中的任意一个满足条件就会出现熔断。

    3、限流,提供过载保护

    限流的原理跟熔断有点类似,都是通过判断某个条件来确定是否执行某个策略。但是又有所区别,熔断触发过载保护,该节点会暂停服务,直到恢复。限流,则是只处理自己能力范围之内的请求,超量的请求会被限流。

    限流算法主要有:计数器限流、滑动窗口限流、令牌桶限流、漏桶限流。网上的资料很多,这里就不多赘述。

    4、降级

    比如电商大促,业务在峰值时刻,系统抵挡不住全部的流量时,系统的负载、CPU 的使用率都超过了预警水位,可以对一些非核心的功能进行降级,降低系统压力,比如把商品评价成交记录等功能临时关掉。弃车保帅保证 创建订单、支付 等核心功能的正常使用

    当然不同业务、不同公司处理方式也各不相同,需要结合实际场景,和业务方一块讨论,最后达成一个统一认可的降级方案。

    总结下来:降级是通过暂时关闭某些非核心服务或者组件从而保护核心系统的可用性。

     


     

    关于我:前阿里架构师,出过专利,竞赛拿过奖,CSDN博客专家,负责过电商交易、社区生鲜、营销、金融等业务,多年团队管理经验,爱思考,喜欢结交朋友

    关注公众号 — 微观技术 ,查阅更多文章

    在这里插入图片描述

    欢迎大家扫描 ↓↓↓ 二维码,加个微信好友,多多交流
    在这里插入图片描述

     

     

    推荐阅读

    面试题:mysql 一棵 B+ 树能存多少条数据?

    学会这10个设计原则,离架构师又进了一步!!!

    亿级系统的Redis缓存如何设计???

    【高并发、高性能、高可用】系统设计经验

    人人都是架构师???谈何容易!!

    【万级并发】电商库存扣减如何设计?不超卖!

    展开全文
  • 知识分享,以技会友。大家好,我是Tom哥。阅读本文大约需要 15 分钟。软件开发通常会提到一个名词 “三高”,即并发、性能、高可用。具体的指标定义,如:并发方面要求QPS 大于 10...

    知识分享,以技会友。大家好,我是Tom哥。阅读本文大约需要 15 分钟。

    软件开发通常会提到一个名词 “三高”,即高并发、高性能、高可用。

    具体的指标定义,如:高并发方面要求QPS 大于 10万;高性能方面要求请求延迟小于 100 ms;高可用方面要高于 99.99%。

    接下来,我们重点来介绍这 三高


    高并发

    我们使用 QPS(Queries Per Second,每秒查询率)来衡量系统承载能力。架构策略有哪些?

    1、负载均衡

    正所谓双拳难敌四手,高并发撑场面的首选方案就是集群化部署,一台服务器承载的QPS有限,多台服务器叠加效果就不一样了。

    如何将流量转发到服务器集群,这里面就要用到负载均衡,比如:LVS 和 Nginx。

    常用的负载算法有轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小连接数法等

    业务实战:对于千万级流量的秒杀业务,一台LVS扛不住流量洪峰,通常需要 10 台左右,其上面用DDNS(Dynamic DNS)做域名解析负载均衡。搭配高性能网卡,单台LVS能够提供百万以上并发能力。

    注意, LVS 负责网络四层协议转发,无法按 HTTP 协议中的请求路径做负载均衡,所以还需要 Nginx

    2、池化技术

    复用单个连接无法承载高并发,如果每次请求都新建连接、关闭连接,考虑到TCP的三次握手、四次挥手,有时间开销浪费。池化技术的核心是资源的“预分配”和“循环使用”,常用的池化技术有线程池、进程池、对象池、内存池、连接池、协程池。

    连接池的几个重要参数:最小连接数、空闲连接数、最大连接数

    Linux 内核中是以进程为单元来调度资源的,线程也是轻量级进程。所以说,进程、线程都是由内核来创建并调度。协程是由应用程序创建出来的任务执行单元,比如 Go 语言中的协程“goroutine”。协程本身是运行在线程上,由应用程序自己调度,它是比线程更轻量的执行单元。

    在 Go 语言中,一个协程初始内存空间是 2KB(Linux 下线程栈大小默认是 8MB),相比线程和进程来说要小很多。协程的创建和销毁完全是在用户态执行的,不涉及用户态和内核态的切换。另外,协程完全由应用程序在用户态下调用,不涉及内核态的上下文切换。协程切换时由于不需要处理线程状态,需要保存的上下文也很少,速度很快。

    Go语言中协程池的实现方法有两种:抢占式和调度式。

    • 抢占式协程池,所有任务存放到一个共享的 channel 中,多个协程同时去消费 channel 中的任务,存在锁竞争。

    • 调度式协程池,每个协程都有自己的 channel,每个协程只消费自己的 channel。下发任务的时候,采用负载均衡算法选择合适的协程来执行任务。比如选择排队中任务最少的协程,或者简单轮询。

    3、流量漏斗

    上面讲的是正向方式提升系统QPS,我们也可以逆向思维,做减法,拦截非法请求,将核心能力留给正常业务!

    互联网高并发流量并不都是纯净的,也有很多恶意流量(比如黑客攻击、恶意爬虫、黄牛、秒杀器等),我们需要设计流量拦截器,将那些非法的、无资格的、优先级低的流量过滤掉,减轻系统的并发压力。

    拦截器分层:

    • 网关和 WAF(Web Application Firewall,Web 应用防火墙)

    采用封禁攻击者来源 IP、拒绝带有非法参数的请求、按来源 IP 限流、按用户 ID 限流等方法

    • 风控分析。借助大数据能力分析订单等历史业务数据,对同ip多个账号下单、或者下单后支付时间过快等行为有效识别,并给账号打标记,提供给业务团队使用。

    • 下游的每个tomcat实例应用本地内存缓存化,将一些库存存储在本地一份,做前置校验。当然,为了尽量保持数据的一致性,有定时任务,从 Redis 中定时拉取最新的库存数据,并更新到本地内存缓存中。

    高性能

    性能直接影响用户的感官体验,访问一个系统,如果超过5秒没有响应,绝大数用户会选择离开。

    那么有哪些因素会影响系统的性能呢?

    • 用户网络环境

    • 请求/响应的数据包大小

    • 业务系统 CPU、内存、磁盘等性能

    • 业务链路的长度

    • 下游系统的性能

    • 算法实现是否高效

    当然,随着并发数的提升,系统压力增大,平均请求延迟也会增大。

    1、高性能缓存

    对一些热点数据每次都从 DB 中读取,会给 DB 带来较大的压力,导致性能大幅下降。所以,我们需要用缓存来提升热点数据的访问性能,比如将活动信息数据在浏览器的缓存中保存一段时间。

    缓存根据性能由高到低分为:寄存器、L1缓存、L2缓存、L3缓存、本地内存、分布式缓存

    上层的寄存器、L1 缓存、L2 缓存是位于 CPU 核内的高速缓存,访问延迟通常在 10 纳秒以下。L3 缓存是位于 CPU 核外部但在芯片内部的共享高速缓存,访问延迟通常在十纳秒左右。高速缓存具有成本高、容量小的特点,容量最大的 L3 缓存通常也只有几十MB。

    本地内存是计算机内的主存储器,相比 CPU 芯片内部的高速缓存,内存的成本要低很多,容量通常是 GB 级别,访问延迟通常在几十到几百纳秒。

    内存和高速缓存都属于掉电易失的存储器,如果机器断电了,这类存储器中的数据就丢失了。

    特别说明:在使用缓存时,要注意缓存穿透、缓存雪崩、缓存热点问题、缓存数据一致性问题。当然为了提升整体性能通常会采用多级缓存组合方案(浏览器缓存+服务端本地内存缓存+服务端网络内存缓存)

    2、日志优化,避免IO瓶颈

    当系统处理大量磁盘 IO 操作的时候,由于 CPU 和内存的速度远高于磁盘,可能导致 CPU 耗费太多时间等待磁盘返回处理的结果。对于这部分 CPU 在 IO 上的开销,我们称为 “iowait”。

    在IO中断过程中,如果此时有其他任务线程可调度,系统会直接调度其他线程,这样 CPU 就相应显示为 Usr 或 Sys;但是如果此时系统较空闲,无其他任务可以调度,CPU 就会显示为 iowait(实际上与 idle 无本质区别)。

    磁盘有个性能指标:IOPS,即每秒读写次数,性能较好的固态硬盘,IOPS 大概在 3 万左右。对于秒杀系统,如果单节点QPS在10万,每次请求产生3条日志,那么日志的写入QPS在 30W/s,磁盘根本扛不住。

    Linux 有一种特殊的文件系统:tmpfs(临时文件系统),它是一种基于内存的文件系统,由操作系统管理。当我们写磁盘的时候实际是写到内存中,当日志文件达到我们的设置阈值,操作系统会将日志写到磁盘中,并将tmpfs中的日志文件删除。

    这种批量化、顺序写,大大提升了磁盘的吞吐性能!

    高可用

    高可用指标是指用来衡量一个系统可用性有多高。

    • MTBF(Mean Time Between Failure),系统可用时长

    • MTTR(Mean Time To Repair),系统从故障后到恢复正常所耗费的时间

    • SLA(Service-Level Agreement),服务等级协议,用于评估服务可用性等级。计算公式是 MTBF/(MTBF+MTTR)

    一般我们所说的可用性高于 99.99%,是指 SLA 高于 99.99%。

    技术架构,高可用有哪些策略?

    • 多云架构、异地多活、异地备份

    • 主备切换,如redis缓存、mysql数据库,主备节点会实时数据同步、备份。如果主节点不可用,自动切换到备用节点

    • 微服务,无状态化架构,业务集群化部署,有心跳检测,能最短时间检测到不可用的服务。

    • 通过熔断、限流,解决流量过载问题,提供过载保护

    • 重视web安全,解决攻击和XSS问题

    1、主备切换,缩减故障时间

    当系统出现故障时,首要任务不是立马查找原因,考虑到故障的复杂样,定位排查要花些时间,等问题修复好,SLA也降了好几个档。有没有更快的方式解决这个问题?那就是故障转移。

    当发现故障节点的时候,不是尝试修复它,而是立即把它隔离,同时将流量转移到正常节点上。这样通过故障转移,不仅减少了 MTTR 提升了 SLA,还为修复故障节点赢得了足够的时间。

    主备切换大致分为三步:

    • 第一步故障自动侦测(Auto-detect),采用健康检查、心跳等技术手段自动侦测故障节点;

    • 第二步自动转移(FailOver),当侦测到故障节点后,采用摘除流量、脱离集群等方式隔离故障节点,将流量转移到正常节点;

    • 第三步自动恢复(FailBack),当故障节点恢复正常后,自动将其加入集群中,确保集群资源与故障前一致。

    2、熔断,提供过载保护

    所谓过载保护,是指负载超过系统的承载能力时,系统会自动采取保护措施,确保自身不被压垮。

    熔断就是在系统濒临崩溃的时候,立即中断服务,从而保障系统稳定避免崩溃。它类似于电器中的“保险丝”,当电流过大的时候,“保险丝”会先被烧掉,断开电流,以免电路过热烧毁电器引起火灾。

    例子:熔断触发条件往往跟系统节点的承载能力和服务质量有关,比如 CPU 的使用率超过 90%,请求错误率超过 5%,请求延迟超过 500ms, 它们中的任意一个满足条件就会出现熔断。

    3、限流,提供过载保护

    限流的原理跟熔断有点类似,都是通过判断某个条件来确定是否执行某个策略。但是又有所区别,熔断触发过载保护,该节点会暂停服务,直到恢复。限流,则是只处理自己能力范围之内的请求,超量的请求会被限流。

    限流算法主要有:计数器限流、滑动窗口限流、令牌桶限流、漏桶限流。网上的资料很多,这里就不多赘述。

    4、降级

    比如电商大促,业务在峰值时刻,系统抵挡不住全部的流量时,系统的负载、CPU 的使用率都超过了预警水位,可以对一些非核心的功能进行降级,降低系统压力,比如把商品评价成交记录等功能临时关掉。弃车保帅保证 创建订单、支付 等核心功能的正常使用

    当然不同业务、不同公司处理方式也各不相同,需要结合实际场景,和业务方一块讨论,最后达成一个统一认可的降级方案。

    总结下来:降级是通过暂时关闭某些非核心服务或者组件从而保护核心系统的可用性。

    展开全文
  • 秒杀系统的难点友好的用户体验用户不能接受破窗的体验,例如:系统超时、系统错误的提示,或者直接 404 页面瞬时并发流量的挑战木桶短板理论,整个系统的瓶颈往往都在 DB,如何设计并发、高可用系统?如何设计...

    如今的互联网已经在海量服务领域有了很成熟的理论,因此自己也很庆幸,能够从 0 到 1 完整践行海量服务。微视春节项目中的集卡瓜分活动,是一个典型的秒杀场景,自己参与其中,分享一些心得和总结。秒杀系统的难点

    友好的用户体验

    用户不能接受破窗的体验,例如:系统超时、系统错误的提示,或者直接 404 页面

    瞬时高并发流量的挑战

    木桶短板理论,整个系统的瓶颈往往都在 DB,如何设计出高并发、高可用系统?

    如何设计

    上图是一个典型的互联网业务,用户完成一个写操作,一般会通过接入层和逻辑层,这里的服务都是无状态,可以通过平行拓展去解决高并发的问题;到了 db 层,必须要落到介质中,可以是磁盘/ssd/内存,如果出现 key 的冲突,会有一些并发控制技术,例如 cas/加锁/串行排队等。

    直筒型

    直筒型业务,指的是用户请求 1:1 的洞穿到 db 层,如下图所示。在比较简单的业务中,才会采用这个模型。随着业务规模复杂度上来,一定会有 db 和逻辑层分离、逻辑层和接入层分离。

    漏斗型

    漏斗型业务,指的是,用户的请求,从客户端到 db 层,层层递减,递减的程度视业务而定。例如当 10w 人去抢 1 个物品时,db 层的请求在个位数量级,这就是比较理想的模型。如下图所示

    这个模型,是高并发的基础,翻译一下就是下面这些:及早发现,及早拒绝

    Fast Fail

    前端保护后端

    如何实现漏斗型系统

    漏斗型系统需要从产品策略/客户端/接入层/逻辑层/DB 层全方位立体的设计。

    产品策略轻重逻辑分离,以秒杀为例,将抢到和到账分开;

    抢到,是比较轻的操作,库存扣成功后,就可以成功了

    到账,是比较重的操作,需要涉及到到事务操作

    用户分流,以整点秒杀活动为例,在 1 分钟内,陆续对用户放开入口,将所有用户请求打散在 60s 内,请求就可以降一个数量级

    页面简化,在秒杀开始的时候,需要简化页面展示,该时刻只保留和秒杀相关的功能。例如,秒杀开始的时候,页面可以不展示推荐的商品。

    客户端重试策略非常关键,如果用户秒杀失败了,频繁重试,会加剧后端的雪崩。如何重试呢?根据后端返回码的约定,有两种方法:

    不允许重试错误,此时 ui 和文案都需要有一个提示。同时不允许重试

    可重试错误,需要策略重试,例如二进制退避法。同时文案和 ui 需要提示。

    ui 和文案,秒杀开始前后,用户的所有异常都需要有精心设计的 ui 和文案提示。例如:【当前活动太火爆,请稍后再重试】【你的货物堵在路上,请稍后查看】等

    前端随机丢弃请求可以作为降级方案,当用户流量远远大于系统容量时,人工下发随机丢弃标记,用户本地客户端开始随机丢弃请求。

    接入层所有请求需要鉴权,校验合法身份

    果是长链接的服务,鉴权粒度可以在 session 级别;如果是短链接业务,需要应对这种高并发流量,例如 cache 等

    根据后端系统容量,需要一个全局的限流功能,通常有两种做法:

    设置好 N 后,动态获取机器部署情况 M,然后下发单机限流值 N/M。要求请求均匀访问,部署机器统一。

    维护全局 key,以时间戳建 key。有热 key 问题,可以通过增加更细粒度的 key 或者定时更新 key 的方法。

    对于单用户/单 ip 需要频控,主要是防黑产和恶意用户。如果秒杀是有条件的,例如需要完成 xxx 任务,解锁资格,对于获得资格的步骤,可以进行安全扫描,识别出黑产和恶意用户。

    逻辑层逻辑层首先应该进入校验逻辑,例如参数的合法性,是否有资格,如果失败的用户,快速返回,避免请求洞穿到 db。

    异步补单,对于已经扣除秒杀资格的用户,如果发货失败后,通常的两种做法是:

    事务回滚,回滚本次行为,提示用户重试。这个代价特别大,而且用户重试和前面的重试策略结合的话,用户体验也不大流畅。

    异步重做,记录本次用户的 log,提示用户【稍后查看,正在发货中】,后台在峰值过后,启动异步补单。需要服务支持幂等

    对于发货的库存,需要处理热 key。通常的做法是,维护多个 key,每个用户固定去某个查询库存。对于大量人抢红包的场景,可以提前分配。

    存储层对于业务模型而言,对于 db 的要求需要保证几个原则:

    可靠性

    主备:主备能互相切换,一般要求在同城跨机房

    异地容灾:当一地异常,数据能恢复,异地能选主

    数据需要持久化到磁盘,或者更冷的设备

    一致性

    对于秒杀而言,需要严格的一致性,一般要求主备严格的一致。

    实践——微视集卡瓜分系统

    微视集卡瓜分项目属于微视春节项目之一。用户的体验流程如下:

    架构图

    客户端主要是微视主 app 和 h5 页面,主 app 是入口,h5 页面是集卡活动页面和瓜分页面。

    逻辑部分为分:发卡来源、集卡模块、奖品模块,发卡来源主要是任务模块;集卡模块主要由活动模块和集卡模块组成。瓜分部分主要在活动控制层。

    奖品模块主要是发钱和其他奖品。

    瓜分降级预案

    为了做好瓜分时刻的高并发,对整个系统需要保证两个重要的事情:全链路梳理,包括调用链的合理性和时延设置

    降级服务预案分析,提升系统的鲁棒性

    如下图所示,是针对瓜分全链路调用分析如下图,需要特别说明的几点:

    时延很重要,需要全链路分析。不但可以提高吞吐量,而且可以快速暴露系统的瓶颈。

    峰值时刻,补单逻辑需要关闭,避免加剧雪崩。

    我们的降级预案大概如下:一级预案,瓜分时刻前后 5 分钟自动进入:

    入口处 1 分钟内陆续放开入口倒计时,未登录用户不弹入口

    主会场排队,进入主会场以 100wqps 为例,超过了进入排队,由接入层频控控制

    拉取资格接口排队,拉取资格接口 100wqps,超过了进入排队,由接入层频控控制

    抢红包排队,抢红包 100wqps,超过了进入排队,由接入层频控控制

    红包到账排队,如果资格扣除成功,现金发放失败,进入排队,24 小时内到账。异步补单

    入口处调用后端非关键 rpc:ParticipateStatus,手动关闭

    异步补单逻辑关闭。

    二级预案,后端随机丢请求,接入层频控失效或者下游服务过载,手动开启进入

    三级预案,前端随机丢请求,后端服务过载或者宕机进入。手动开启

    综上,整个瓜分时刻体验如下所示:

    回顾下漏斗模型,总结下整个实践:

    展开全文
  • 并发业务架构设计可用业务架构设计实践系统设计的一些原则海恩法则墨菲定律警示软件架构中的高可用设计什么是可用?可用性度量和考核如何保障系统的可用?负载均衡DNS&nginx负载均衡upstream配置负载...
  • 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~...下面开始我们今天的主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。首先介绍一下什么是高可用?在我看来就是业务在...
  • 如果多看下薪资的技术人员招聘要求时,就会发现对三高都有一定的要求,比如下面一家公司的要求就对并发、负载和高可用性系统设计要有开发经验。 现实是我们大部分的公司都很少会遇到三高的场景,即很少有这...
  • 推荐由前58技术委员会主席孙玄,联手 58 快狗打车 CTO 沈剑老师,结合10多年一线大厂实践经验,打造的《百万年薪大数据架构师必备能力—PB级企业高可用高可靠性能大数据中台架构设计与实践》精品在线专栏课,马上...
  • 三高好像离我很远,我好像根本用不到它,整天做着集中式的开发...可能一想到Java 的 并发 ,高可用性能 ,大家都会想到 分布式、微服务、等等的吧。好像只有分布式、微服务 的电商项目才可以用到这些东西。但...
  • 摘要:高可用性对于我们来说应该属于经常提到的名词,本文我们将介绍在分布式系统中保证高可用性的一些常用经验。 系统可用性指标 系统可用性指标简单来将就是系统可用时间与总运行时间之比 Availability=MTTF/...
  • 高可用性(High Availability,HA)是你在系统设计时经常会听到的一个名词,它指的是系统具备较的无故障运行的能力。 我们在很多开源组件的文档中看到的 HA 方案就是提升组件可用性,让系统免于宕机无法服务的方案...
  • 1、什么是主机高可用 2、主机高可用主流解决方案 3、主机HA能做什么 4、主机HA高可用定义和切换流程 5、HA三种经典工作方式 6、主机HA的核心组件和实现原理 7、哪些场景不适合主机HA 8、主机HA高可用选择参考 9、...
  • 点击上方“民工哥技术之路”,选择“设为星标”回复“1024”获取独家整理的学习资料!关于Redis高可用方案,看到较多的是keepalived、zookeeper方案。keepalive...
  • 孙玄,前58集团技术委员会主席,前转转二手交易平台首席架构师。今天想跟你聊聊企业里那些年薪百万的架构师,他们的架构设计思维是如何升级的。话不多说,咱们直接来聊点儿干的!01、百万年薪的核...
  • 简介:阿里巴巴在多年双11并发、高可用客户体验要求背景下积累了相应的技术体系,本文将依据并发用户、突发流量场景下的真实案例,分享阿里在高可用架构建设过程中的经验总结,以期待帮助更多企业做好业务...
  • 分布式高可用CTDB方案

    2021-03-05 17:11:29
    好久没有更新博客以及技术文档了,关于 strom 集群配置这一块,我写到使用 zk 进行配置服务的设计,众位有兴趣的道友可以去尝试下。不过接触到分布式集群这一块之后,我发现集群配置成型的组件还是比较多的,比如...
  • 再来一个性能对比表 特性ActiveMQRabbitMQRocketMQkafka 开发语言 java erlang java scala 单机吞吐量 万级 万级 10万级 10万级 时效性 ms级 us级 ms级 ms级以内 可用(主从架构) (主从架构) 非常(分布式...
  • ORACLE高可用容灾

    2021-05-01 02:57:19
    正群欣世可以帮助用户设计与实施数据库高可用容灾架构,并以专业的运维服务持续支持用户的业务高可用需求。我们将根据客户当前系统的实际情况,结合我们丰富的项目实施经验,为客户选择最合适的技术手段,可以是一种...
  • 并发系统—高可用

    2021-01-24 14:36:35
    高可用系统设计思路:系统设计、系统运维 系统设计:故障转移、超时控制、降级、限流 系统运维:灰度发布、故障演练 故障转移:随机转移、心跳机制 超时控制:组件之间调用最怕的就是延迟而非失败 降级:暂停非核心...
  • 很多人面试的时候被问到一个让人特别手足无措的问题:你的系统如何支撑并发?对于一个公司而言,“为什么要高可用”关于负载均衡架构设计你了解多少?大多数同学被问到这个问题压根儿没什么思路去回答...
  • 术语可扩展性、高可用性、性能和关键任务对于不同的组织或组织内的不同部门来说可能意味着不同的事情。它们经常互换,造成混乱,导致管理不善的期望、实现延迟或不切实际的指标。 这里的快速参考为您提供了定义这些...
  • 摘要:随着网络的快速发展,网络已经渗透到国民经济的各个领域,银行对网络的依赖越来越紧密,网络高可用性研究越来越重要。... 论文从网络高可用技术探讨入手,借鉴国内外先进的管理经验,结合工作经历,探讨...
  • 顺序写盘,随机读 底层通信框架采用Netty NIO NameServer代替Zookeeper,实现服务寻址和服务协调 消息失败重试机制、消息可查询 强调集群无单点,可扩展,任意一点高可用,水平可扩展 经过多次双十一的考验 高可用...
  • 随着业务量的增加,目前的系统都朝着并发、高可用的方向发展,同时带来了分布式数据的一致性问题。例如: 数据库主从架构、读写分离,存在访问时的数据一致性问题 为了进一步提高并发量,在数据库上层又引入一层...
  • 并发,几乎是每个程序员都想拥有的经验。原因很简单:随着流量变大,会遇到各种各样的技术问题,比如:接口响应超时、CPU load升高、GC频繁、死锁、大数据量存储等等,这些问题能推动我们在技术深度上不断精进。这...
  • PostgreSQL高可用:多主复制解决方案

    千次阅读 热门讨论 2020-12-18 10:21:42
    Ibrar拥有18年的软件开发经验。Ibrar在PostgreSQL上写了多本书。 译者:魏波,中国PG分会培训认证执行总监、资深数据库工程师,十多年的数据库运维管理及培训经验,掌握PostgreSQL架构部署、性能优化等,致力于推动...
  • Java 并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 免费赠送 经典图书 : 极致经典 + 社群大片好评 《 Java 并发 三部曲 》 面试必备 + 大厂必备 + 涨薪必备 免费赠送 经典图书 : ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 174,289
精华内容 69,715
关键字:

高可用设计的经验