记得很久之前,去面试过 字节跳动 。被三面的面试官问了一道场景设计题目: 如何设计一个高并发零碎。过后我答复得比拟毛糙,最近回想起来,所以整顿了设计高并发零碎的 15 个锦囊,置信大家看完会有帮忙的。
如何了解高并发零碎
所谓设计 高并发 零碎,就是设计一个零碎,保障它 整体可用 的同时,可能 解决很高的并发用户申请 ,可能接受 很大的流量冲击。
咱们要设计高并发的零碎,那就须要解决好一些常见的零碎瓶颈问题,如 内存不足、磁盘空间有余,连接数不够,网络宽带不够 等等,以应答突发的流量洪峰。
1. 分而治之,横向扩大
如果你 只部署一个利用,只部署一台服务器,那抗住的流量申请是十分无限的。并且,单体的利用,有单点的危险,如果它挂了,那服务就不可用了。
因而,设计一个高并发零碎,咱们能够 分而治之,横向扩大 。也就是说,采纳分布式部署的形式,部署多台服务器,把流量分流开,让每个服务器都承当一部分的并发和流量,晋升 整体零碎的并发能力。
2. 微服务拆分(零碎拆分)
要进步零碎的吞吐,进步零碎的解决并发申请的能力。除了采纳 分布式部署的形式 外,还能够做 微服务拆分,这样就能够达到摊派申请流量的目标,进步了并发能力。
所谓的 微服务拆分 ,其实就是把一个单体的利用,按性能单一性,拆分为多个服务模块。 比方一个电商零碎,拆分为用户零碎、订单零碎、商品零碎等等。
3. 分库分表
当业务量暴增的话,MySQL 单机 磁盘容量会撑爆 。并且,咱们晓得数据库连接数是无限的。 在高并发的场景下 ,大量申请拜访数据库,MySQL
单机是扛不住的!高并发场景下,会呈现 too many connections
报错。
所以高并发的零碎,须要思考拆分为多个数据库,来抗住高并发的毒打 。而如果你的单表数据量十分大,存储和查问的性能就会遇到瓶颈了,如果你做了很多优化之后还是无奈晋升效率的时候,就须要思考做 分表 了。个别千万级别数据量,就须要 分表,每个表的数据量少一点,晋升 SQL 查问性能。
当面试官问要求你设计一个高并发零碎的时候,个别都要说到 分库分表 这个点。
4. 池化技术
在高并发的场景下,数据库连接数 可能成为瓶颈,因为连接数是无限的。
咱们的申请调用数据库时,都会先获取数据库的连贯,而后依附这个连贯来查问数据,搞完出工,最初敞开连贯,开释资源。如果咱们不必数据库连接池的话,每次执行SQL
,都要创立连贯和销毁连贯,这就会导致每个查问申请都变得更慢了,相应的,零碎解决用户申请的能力就升高了。
因而,须要应用池化技术,即 数据库连接池、HTTP 连接池、Redis 连接池 等等。应用数据库连接池,能够防止每次查问都新建连贯,缩小不必要的资源开销,通过复用连接池,进步零碎解决高并发申请的能力。
同理,咱们应用线程池,也能 让工作并行处理,更高效地实现工作。
5. 主从拆散
通常来说,一台单机的 MySQL 服务器,能够反对 500
左右的 TPS
和10000
左右的 QPS
,即单机撑持的 申请拜访是无限 的。因而你做了分布式部署,部署了多台机器,部署了主数据库、从数据库。
然而,如果双十一搞流动,流量必定会猛增的。如果所有的查问申请,都走主库的话,主库必定扛不住,因为查问申请量是十分十分大的。因而个别都要求做 主从拆散 ,而后实时性要求不高的读申请,都去读从库, 写的申请或者实时性要求高的申请,才走主库。这样就很好爱护了主库,也进步了零碎的吞吐。
当然,如果答复了主从拆散,面试官可能扩大开问你 主从复制原理,问你主从提早问题 等等,这块大家须要 全方位温习好 哈。
6. 应用缓存
无论是操作系统,浏览器,还是一些简单的中间件,你都能够看到缓存的影子。咱们应用缓存,次要是晋升零碎接口的性能,这样高并发场景,你的零碎就能够反对更多的用户同时拜访。
罕用的缓存包含:Redis
缓存,JVM
本地缓存,memcached
等等。就拿 Redis
来说,它单机就能轻轻松松应答几万的并发,你读场景的业务,能够用缓存来抗高并发。
缓存尽管用得爽,然而要 留神缓存应用的一些问题:
- 缓存与数据库的一致性问题
- 缓存雪崩
- 缓存穿透
- 缓存击穿
7. CDN,减速动态资源拜访
商品图片,icon
等等动态资源,能够对页面做 动态化解决,缩小拜访服务端的申请 。如果用户散布在全国各地,有的在上海,有的在深圳,地区相差很远,网速也各不相同。为了让用户最快拜访到页面,能够应用CDN
。CDN
能够让用户就近获取所需内容。
什么是 CDN?
Content Delivery Network/Content Distribution Network, 翻译过去就是内容散发网络,它示意将动态资源散发到位于多个地理位置机房的服务器,能够做到数据就近拜访,减速了动态资源的访问速度,因而让零碎更好解决失常别的动静申请。
8. 音讯队列,削锋
咱们搞一些双十一、双十二等经营流动时,须要 防止流量暴涨,打垮利用零碎的危险 。因而个别会引入音讯队列,来应答 高并发的场景。
假如你的利用零碎每秒最多能够解决 2k
个申请,每秒却有 5k
的申请过去,能够引入音讯队列,利用零碎每秒从音讯队列拉 2k
申请解决得了。
有些搭档放心这样可能会呈现 音讯积压 的问题:
- 首先,搞一些经营流动,不会每时每刻都那么多申请过去你的零碎(除非有人歹意攻打),高峰期过来后,积压的申请能够缓缓解决;
- 其次,如果音讯队列长度超过最大数量,能够间接摈弃用户申请或跳转到谬误页面;
9. ElasticSearch
Elasticsearch
,大家都应用得比拟多了吧,个别搜寻性能都会用到它。它是一个分布式、高扩大、高实时的搜寻与数据分析引擎,简称为ES
。
咱们在聊高并发,为啥聊到 ES
呢?因为 ES
能够扩容不便,人造撑持高并发。当数据量大的时候,不必动不动就加机器扩容,分库等等 ,能够思考用ES
来反对简略的查问搜寻、统计类的操作。
10. 降级熔断
熔断降级 是爱护零碎的一种伎俩。以后互联网零碎个别都是分布式部署的。而分布式系统中偶然会呈现某个根底服务不可用,最终导致整个零碎不可用的状况, 这种景象被称为 服务雪崩效应。
比方分布式调用链路A->B->C....
,下图所示:
如果服务
C
呈现问题,比方是因为慢SQL
导致调用迟缓,那将导致B
也会提早,从而A
也会提早。堵住的A
申请会耗费占用零碎的线程、IO、CPU 等资源。当申请A
的服务越来越多,占用计算机的资源也越来越多,最终会导致系统瓶颈呈现,造成其余的申请同样不可用,最初导致业务零碎解体。
为了应答服务雪崩, 常见的做法是 熔断和降级 。最简略是加开关管制,当上游零碎出问题时,开关关上降级,不再调用上游零碎。还能够选用开源组件Hystrix
来反对。
你要保障设计的零碎能应答 高并发场景 ,那必定要思考 熔断降级 逻辑进来。
11. 限流
限流也是咱们应答高并发的一种计划。咱们当然心愿,在高并发大流量过去时,零碎能全副申请都失常解决。然而有时候没方法,零碎的 CPU、网络带宽、内存、线程等资源都是无限的。因而,咱们要思考限流。
如果你的零碎每秒扛住的申请是一千,如果一秒钟来了十万申请呢?换个角度就是说,高并发的时候,流量洪峰来了,超过零碎的承载能力,怎么办呢?
这时候,咱们能够采取限流计划。就是为了爱护零碎,多余的申请,间接抛弃。
什么是限流:在计算机网络中,限流就是管制网络接口发送或接管申请的速率,它可避免 DoS 攻打和限度 Web 爬虫。限流,也称流量管制。是指零碎在面临高并发,或者大流量申请的状况下,限度新的申请对系统的拜访,从而保证系统的稳定性。
能够应用 Guava
的RateLimiter
单机版限流,也能够应用 Redis
分布式限流,还能够应用阿里开源组件 sentinel
限流。
面试的时候,你说到限流这块的话?面试官很大概率会问你限流的算法,因而,大家在筹备面试的时候,须要温习一下这几种经典的限流算法哈
12. 异步
回顾一下什么是同步,什么是异步呢?以 办法调用 为例,它代表 调用方要阻塞期待被调用办法中的逻辑执行实现。这种形式下,当被调用办法响应工夫较长时,会造成调用方短暂的阻塞,在高并发下会造成整体零碎性能降落甚至产生雪崩。异步调用恰恰相反,调用方不须要期待办法逻辑执行实现就能够返回执行其余的逻辑,在被调用办法执行结束后再通过回调、事件告诉等形式将后果反馈给调用方。
因而,设计一个高并发的零碎,须要在失当的场景应用异步。如何应用异步呢?后端能够借用音讯队列实现。比方在海量秒杀申请过去时,先放到音讯队列中,疾速响应用户,通知用户申请正在解决中,这样就能够开释资源来解决更多的申请。秒杀申请解决完后,告诉用户秒杀抢购胜利或者失败。
13. 接口的惯例优化
设计一个高并发的零碎,须要设计接口的性能足够好,这样零碎在雷同工夫,就能够解决更多的申请。当说到这里的话,能够跟面试官说说接口优化的一些计划了。
14. 压力测试确定零碎瓶颈
设计高并发零碎,离不开最重要的一环,就是压力测试。就是在零碎上线前,须要对系统进行压力测试,测分明你的零碎撑持的最大并发是多少,确定零碎的瓶颈点,让本人心里有底,最好预防措施。
压测完要剖析整个调用链路,性能可能呈现问题是网络层(如带宽)、Nginx 层、服务层、还是数据路缓存等中间件等等。
loadrunner
是一款不错的压力测试工具,jmeter
则是接口性能测试工具,都能够来做下压测。
15. 应答突发流量峰值:扩容 + 切流量
如果是突发的流量顶峰,除了降级、限流保证系统不跨,咱们能够采纳这两种计划,保证系统尽可能服务用户申请:
- 扩容:比方减少从库、晋升配置的形式 ,晋升零碎 / 组件的流量承载能力。比方减少
MySQL、Redis
从库来解决查问申请。 - 切流量:服务多机房部署,如果高并发流量来了,把流量从一个机房切换到另一个机房。