如何设计一个高并发系统

news/2024/5/10 20:22:38/文章来源:https://blog.csdn.net/weixin_45721753/article/details/130030091

目录

如何理解高并发系统

1. 分而治之,横向扩展

2. 微服务拆分(系统拆分)

3. 分库分表

4. 池化技术

5. 主从分离

6. 使用缓存

7. CDN——加速静态资源访问

8. 消息队列——削锋

9. ElasticSearch

10. 降级熔断

11. 限流

12. 异步

13. 常规的优化

14. 压力测试确定系统瓶颈

15. 应对突发流量峰值:扩容+切流量


设计高并发系统的15种方法。

如何理解高并发系统

       所谓设计高并发系统,就是设计一个系统,保证它整体可用的同时,能够处理很高的并发用户请求,能够承受很大的流量冲击

我们要设计高并发的系统,那就需要处理好一些常见的系统瓶颈问题,如内存不足、磁盘空间不足,连接数不够,网络宽带不够等等,以应对突发的流量洪峰。

1. 分而治之,横向扩展

       如果你只部署一个应用,只部署一台服务器,那抗住的流量请求是非常有限的。并且,单体的应用,有单点的风险,如果它挂了,那服务就不可用了。

因此,设计一个高并发系统,我们可以分而治之,横向扩展。也就是说,采用分布式部署的方式,部署多台服务器,把流量分流开,让每个服务器都承担一部分的并发和流量,提升整体系统的并发能力

2. 微服务拆分(系统拆分)

       要提高系统的吞吐,提高系统的处理并发请求的能力。除了采用分布式部署的方式外,还可以做微服务拆分,这样就可以达到分摊请求流量的目的,提高了并发能力。

所谓的微服务拆分,其实就是把一个单体的应用,按功能单一性,拆分为多个服务模块。比如一个电商系统,拆分为用户系统、订单系统、商品系统等等

3. 分库分表

       当业务量暴增的话,MySQL单机磁盘容量会撑爆。并且,我们知道数据库连接数是有限的。在高并发的场景下,大量请求访问数据库,MySQL单机是扛不住的!高并发场景下,会出现too many connections报错。

所以高并发的系统,需要考虑拆分为多个数据库,来抗住高并发的毒打。而假如你的单表数据量非常大,存储和查询的性能就会遇到瓶颈了,如果你做了很多优化之后还是无法提升效率的时候,就需要考虑做分表了。一般千万级别数据量,就需要分表,每个表的数据量少一点,提升SQL查询性能。

当面试官问要求你设计一个高并发系统的时候,一般都要说到分库分表这个点。

资料参考:

分库分表经典15连问

4. 池化技术

       在高并发的场景下,数据库连接数可能成为瓶颈,因为连接数是有限的。

我们的请求调用数据库时,都会先获取数据库的连接,然后依靠这个连接来查询数据,搞完收工,最后关闭连接,释放资源。如果我们不用数据库连接池的话,每次执行SQL,都要创建连接和销毁连接,这就会导致每个查询请求都变得更慢了,相应的,系统处理用户请求的能力就降低了。

因此,需要使用池化技术,即数据库连接池、HTTP 连接池、Redis 连接池等等。使用数据库连接池,可以避免每次查询都新建连接,减少不必要的资源开销,通过复用连接池,提高系统处理高并发请求的能力

同理,我们使用线程池,也能让任务并行处理,更高效地完成任务

资料参考:

细数线程池的10个坑

面试必备:Java线程池解析

5. 主从分离

       通常来说,一台单机的MySQL服务器,可以支持500左右的TPS10000左右的QPS,即单机支撑的请求访问是有限的。因此你做了分布式部署,部署了多台机器,部署了主数据库、从数据库。

但是,如果双十一搞活动,流量肯定会猛增的。如果所有的查询请求,都走主库的话,主库肯定扛不住,因为查询请求量是非常非常大的。因此一般都要求做主从分离,然后实时性要求不高的读请求,都去读从库,写的请求或者实时性要求高的请求,才走主库。这样就很好保护了主库,也提高了系统的吞吐。

当然,如果回答了主从分离,面试官可能扩展开问你主从复制原理,问你主从延迟问题等等。

资料参考:

面试必备:聊聊MySQL的主从

6. 使用缓存

       无论是操作系统,浏览器,还是一些复杂的中间件,你都可以看到缓存的影子。我们使用缓存,主要是提升系统接口的性能,这样高并发场景,你的系统就可以支持更多的用户同时访问。

常用的缓存包括:Redis缓存,JVM本地缓存,memcached等等。就拿Redis来说,它单机就能轻轻松松应对几万的并发,你读场景的业务,可以用缓存来抗高并发。

缓存虽然好用,但是要注意缓存使用的一些问题

  • 缓存与数据库的一致性问题
  • 缓存雪崩
  • 缓存穿透
  • 缓存击穿

资料参考:

使用Redis,你必须知道的21个注意要点

7. CDN——加速静态资源访问

       商品图片,icon等等静态资源,可以对页面做静态化处理,减少访问服务端的请求。如果用户分布在全国各地,有的在上海,有的在深圳,地域相差很远,网速也各不相同。为了让用户最快访问到页面,可以使用CDNCDN可以让用户就近获取所需内容。

什么是CDN?

Content Delivery Network/Content Distribution Network,翻译过来就是内容分发网络,它表示将静态资源分发到位于多个地理位置机房的服务器,可以做到数据就近访问,加速了静态资源的访问速度,因此让系统更好处理正常别的动态请求。

8. 消息队列——削锋

       我们搞一些双十一、双十二等运营活动时,需要避免流量暴涨,打垮应用系统的风险。因此一般会引入消息队列,来应对高并发的场景

假设你的应用系统每秒最多可以处理2k个请求,每秒却有5k的请求过来,可以引入消息队列,应用系统每秒从消息队列拉2k请求处理得了。

有些伙伴担心这样可能会出现消息积压的问题:

  • 首先,搞一些运营活动,不会每时每刻都那么多请求过来你的系统(除非有人恶意攻击),高峰期过去后,积压的请求可以慢慢处理;
  • 其次,如果消息队列长度超过最大数量,可以直接抛弃用户请求或跳转到错误页面;

9. ElasticSearch

   Elasticsearch,大家都使用得比较多了吧,一般搜索功能都会用到它。它是一个分布式、高扩展、高实时的搜索与数据分析引擎,简称为ES

我们在聊高并发,为啥聊到ES呢? 因为ES可以扩容方便,天然支撑高并发。当数据量大的时候,不用动不动就加机器扩容,分库等等,可以考虑用ES来支持简单的查询搜索、统计类的操作。

10. 降级熔断

       熔断降级是保护系统的一种手段。当前互联网系统一般都是分布式部署的。而分布式系统中偶尔会出现某个基础服务不可用,最终导致整个系统不可用的情况, 这种现象被称为服务雪崩效应

为了应对服务雪崩, 常见的做法是熔断和降级。最简单是加开关控制,当下游系统出问题时,开关打开降级,不再调用下游系统。还可以选用开源组件Hystrix来支持。

你要保证设计的系统能应对高并发场景,那肯定要考虑熔断降级逻辑进来。

11. 限流

       限流也是我们应对高并发的一种方案。我们当然希望,在高并发大流量过来时,系统能全部请求都正常处理。但是有时候没办法,系统的CPU、网络带宽、内存、线程等资源都是有限的。因此,我们要考虑限流。

如果你的系统每秒扛住的请求是一千,如果一秒钟来了十万请求呢?换个角度就是说,高并发的时候,流量洪峰来了,超过系统的承载能力,怎么办呢?

这时候,我们可以采取限流方案。就是为了保护系统,多余的请求,直接丢弃。

什么是限流:在计算机网络中,限流就是控制网络接口发送或接收请求的速率,它可防止DoS攻击和限制Web爬虫。限流,也称流量控制。是指系统在面临高并发,或者大流量请求的情况下,限制新的请求对系统的访问,从而保证系统的稳定性。

可以使用GuavaRateLimiter单机版限流,也可以使用Redis分布式限流,还可以使用阿里开源组件sentinel限流。

面试的时候,你说到限流这块的话?面试官很大概率会问你限流的算法,所以就需要复习一下这几种经典的限流算法。

12. 异步

回忆一下什么是同步,什么是异步呢?以方法调用为例,它代表调用方要阻塞等待被调用方法中的逻辑执行完成。这种方式下,当被调用方法响应时间较长时,会造成调用方长久的阻塞,在高并发下会造成整体系统性能下降甚至发生雪崩。异步调用恰恰相反,调用方不需要等待方法逻辑执行完成就可以返回执行其他的逻辑,在被调用方法执行完毕后再通过回调、事件通知等方式将结果反馈给调用方。

因此,设计一个高并发的系统,需要在恰当的场景使用异步。如何使用异步呢?后端可以借用消息队列实现。比如在海量秒杀请求过来时,先放到消息队列中,快速相应用户,告诉用户请求正在处理中,这样就可以释放资源来处理更多的请求。秒杀请求处理完后,通知用户秒杀抢购成功或者失败。

13. 常规的优化

       设计一个高并发的系统,需要设计接口的性能足够好,这样系统在相同时间,就可以处理更多的请求。当说到这里的话,大家就可以跟面试官说说接口优化的一些方案了。

标接口优化方案

资料参考:

实战总结!18种接口优化方案的总结

14. 压力测试确定系统瓶颈

       设计高并发系统,离不开最重要的一环,就是压力测试。就是在系统上线前,需要对系统进行压力测试,测清楚你的系统支撑的最大并发是多少,确定系统的瓶颈点,让自己心里有底,最好预防措施。

压测完要分析整个调用链路,性能可能出现问题是网络层(如带宽)、Nginx层、服务层、还是数据路缓存等中间件等等。

loadrunner是一款不错的压力测试工具,jmeter则是接口性能测试工具,都可以来做下压测。

15. 应对突发流量峰值:扩容+切流量

       如果是突发的流量高峰,除了降级、限流保证系统不跨,我们可以采用这两种方案,保证系统尽可能服务用户:

  • 扩容:比如增加从库、提升配置的方式,提升系统/组件的流量承载能力。比如增加MySQL、Redis从库来处理查询请求。
  • 切流量:服务多机房部署,如果高并发流量来了,把流量从一个机房切换到另一个机房。



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283637.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【OpenLayers】VUE+OpenLayers+ElementUI加载WMS地图服务

【OpenLayers】VUEOpenLayersElementUI加载WMS地图服务准备工作安装vue创建vue项目安装OpenLayers安装ElementUI加载wms地图服务准备工作 需要安装好nodejs,nodejs下载地址,下载对应的版本向导式安装即可。 安装完成后,控制台输入node -v&a…

【CentOS 7安装MySQL 8的教程指南】

CentOS 7安装MySQL 8 添加MySQL官方源 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm sudo rpm -ivh mysql80-community-release-el7-3.noarch.rpm安装MySQL 8 sudo yum install mysql-community-server安装失败执行下面的命令并再次执行安装…

进程与线程的区别和联系

进程与线程的区别和联系🔎进程🔎线程🔎进程与线程的联系🔎进程与线程的区别🔎总结🔎 结尾🔎进程 进程简单来说就是运行着的程序 如果不太理解可以参考一下这篇文章 进程 🔎线程 …

【MySQL--01】数据库基础

文章目录1.什么是数据库2.主流数据库2.1 MySQLMySQL架构实例3.基本使用3.1 MySQL的安装3.2 连接服务器3.3服务器管理4.服务器,数据库,表之间的关系5.使用数据库6.SQL分类7.存储引擎查看存储引擎存储引擎对比1.什么是数据库 数据库是用来存储数据的。那么…

Java BigDecimal学习

文章目录Java BigDecimal不损失精度的方法Java BigDecimal的几种舍入模式1、UP(BigDecimal.ROUND_UP)2、DOWN(BigDecimal.ROUND_DOWN)3、CEILING(BigDecimal.ROUND_CEILING)4、FLOOR(BigDecimal.ROUND_FLOOR)5、HALF_UP(BigDecimal.ROUND_HALF_UP)6、HALF_DOWN(BigDecimal.ROUN…

QMake宏定义常量和字符串或带空格的字符串(在代码中使用)

答案 宏定义常量 DEFINES EXPIR_TIME123宏定义字符串(不带空格) DEFINES NIHAO\\\"nihao\\\"宏定义字符串(带空格也适用于不带空格的情况) 推荐 DEFINES NIHAO\"\\\"ni" "hao\\\"\"QMAKE宏定义常量 环境: visual studio 2018 …

Java基础之List

文章目录一、List介绍二、List常用方法 List应知应会2.1 调用add()方法增添数据(可指定位置添加)2.2 调用remove()方法删除指定位置元素并返回被删除元素2.3 调用set()方法修改指定位置元素并返回初始数据2.4 调用get()方法返回指定位置元素三、List可重…

SQL注入写入文件方法(获取webshell)

数据库写入文件条件 1、当前数据库用户为 root 权限2、知道当前网站的绝对路径3、secure_file_priv 的参数必须为空或目录地址4、PHP的 GPC 为 off状态;(魔术引号,GET,POST,Cookie)用 sqli-labs 测试查看当前用户权限Python sqlma…

本机连接Vmware虚拟机中win7的SQLServer数据库

在开发中,可能遇到不同数据库或不同版本的问题,为了避免在本机安装卸载造成后续无法再次安装的情况,我们在虚拟机中安装需要的版本进行测试。 本篇介绍如何在本机连接到虚拟机中的数据库。 解决流程如下: 一:进入虚…

学Vue3这一篇就够了!

目录学习Vue的前提是掌握 HTML,CSS,Js中级知识vue介绍声明式渲染条件与循环处理用户输入组件化应用构建Vue与自定义元素的关系应用和组件实例Vue实例根组件组件实例 property生命周期钩子实例的生命周期图模板语法插值文本原始 HTMLAttribute使用 JavaScript 表达式指令参数动态…

Linux驱动开发——字符设备

目录 Linux设备分类 字符设备驱动基础 字符设备驱动框架 虚拟串口设备 Linux设备分类 Linux系统根据驱动程序实现的模型框架将设备驱动分为下面三种。 (1)字符设备驱动:设备对数据的处理是按照字节流的形式进行的,可以支持随机访问,也可以不支持随…

抽象类,接口

抽象类:当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类。 package com.hspedu.abstract_;public class Abstract01 {public static void main(String[] args) {} } a…

Linux 操作系统原理 — PCIe 总线标准

目录 文章目录目录总线系统PCIe 总线PCIe 总线的传输速率PCIe 总线的架构PCIe 外设PCIe 设备的枚举过程PCIe 设备的编址方式BDF(Bus-Device-Function)编号BAR(Base Address Register)地址Linux 上的 PCIe 设备查看 PCIe 设备的 BD…

算法强化--两数之和

hi,大家好,今天为大家带来一道题目,求两数之和 题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一…

Python 进阶指南(编程轻松进阶):三、使用 Black 工具来格式化代码

原文:http://inventwithpython.com/beyond/chapter3.html 代码格式化是将一组规则应用于源代码,从而使得代码风格能够简洁统一。虽然代码格式对解析程序的计算机来说不重要,但代码格式对于可读性是至关重要的,这是维护代码所必需的…

【剑指offer|4.从尾到头打印单链表】

0.从尾到头打印单链表 单链表:一般给的都是无头节点的 另外:在面试中,如果我们打算修改输入的数据,则最好问一下面试官是不是允许修改 下面这种先把链表节点的值按链表序放到数组中,然后来一个算法库中的reverse属实有…

一文懂KL散度KL Divergence

本文翻译自https://naokishibuya.medium.com/demystifying-kl-divergence-7ebe4317ee68 KL散度中的KL全称是Kullback-Leibler,分别表示Solomon Kullback和Richard A.Leibler这两个人。 一、KL散度的定义 KL散度表明概率分布Q和概率分布P之间的相似性,由…

ARM Linux 内核启动1 —— 汇编阶段

一、Makefile分析 1、Makefile 分析 (1) kernel 的 Makefile 写法和规则等,和 uboot 的 Makefile 是一样的,甚至 Makefile 中的很多内容都是一样的。 (2) kernel 的 Makefile 比 uboot 的 Makefile 要复杂,这里我们并不会一行一行的详细分析…

【20】核心易中期刊推荐——计算机科学电子通信(EI索引)

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

进阶C语言:文件操作

文件操作不仅仅是我们使用鼠标用来操作文件的各项功能,还可以使用C语言来操作文件的内容,可以使用C语言来对文件的读、写、拷贝...等等,话不多说,直接开始: 目录 1.为什么要使用文件 2.什么是文件 2.1程序文件 2.…