当前位置: 首页 > news >正文

如何打造一个高并发系统?

今天和大家聊聊作为一个后端开发,在实际工作中,我们如何打造一个高并发的系统?如下图所示,大概有六个层面,我们结合具体的场景直播间签到去一一细说。

一、前端

1、打散请求即把用户的接口分散一点去请求后端,尽量不要集中在某一时刻场景:比如直播间讲师发起了一个签到,用户去点击签到,调用签到请求接口。假设这个直播间的在线人数上百万,那么这个签到接口的请求可能会有近百万的QPS。毫无疑问,这会对后端服务造成瞬时、巨大的流量冲击。解决措施:这种瞬时洪峰流量,我们就可以在前端对用户签到接口做打散处理。比如针对直播间的在线人数,当超过某个阈值时,做3秒内任一毫秒的分散请求。避免这些请求在大流量直播的直播间里,瞬间同时请求过来,冲垮后端服务。

2、防抖防重即在前端加上防止重复点击、重复请求后端的逻辑。比如点击签到按钮后,前端做一些类似3秒的防重复请求处理,避免用户多次点击请求到后端,这样可以减少大量无意义无效的请求。

3、服务降级:在高并发、系统压力较大或部分服务出现故障时,通过暂时减少或关闭某些功能,以保证系统的核心功能仍然能够正常运行,避免整个系统崩溃。场景:比如在签到服务中,用户签到是核心接口,当签到服务受到流量冲击导致压力过大时,可以将除该接口外的其它功能在前端暂时屏蔽掉(可配置),这样用户就不会去请求对应的接口了,优先保证核心接口正常运行。

二、Nginx/网关

1、负载均衡:这个应该大家都比较熟悉,就是尽可能将请求均匀地打在各个服务器上,常见的有轮询策略、hash策略等,就不一一赘述了。

2、网关限流:一般我们C端的服务都会有一个统一的网关系统,实现比如用户信息获取、路由的分发、接口限流等功能。我们对于C端的接口,在上线前会经过接口压测,然后根据压测结果设置接口限流值。在高并发场景下,比如签到接口设置的是10WQPS,我们就会把在同一秒内超过10W的请求直接在网关层丢弃掉,避免将下游的签到服务打挂

三、业务层

1、同步返回:比如前端请求签到接口,我们后端会返回签到成功给前端,但实际是否成功还不确定,因为我们肯定不会实时同步去查询或者写入MySQL。毕竟我们的MySQL还是比较脆弱的,经不住上万QPS同时操作

2、异步处理:跟上面其实意思差不多,同步返回结果,但我们会将实际的数据使用中间件如kafka、RocketMQ、RabbitMQ、Redis等进行削峰,然后推送到下游,最后使用脚本去消费推送的数据进行实际的逻辑处理。

四、数据层

1、本地缓存:可以说本地缓存是服务器上读写性能都最高的介质了,因为本地缓存是直接操作该服务器本身的内存呀。只要内存够大,几十万、几百万的QPS都轻轻松松不在话下

2、Redis缓存:Redis缓存的性能仅此于本地缓存,一般抗10万以下的QPS用Redis就够了。Redis缓存实际上也是操作的Redis服务器的内存,只是Redis服务器和本地服务器还有网络连接。所以Redis性能会比本地缓存稍微差一点,一般同等配置可能都会差一到两个量级。

3、MySQL:这个大家应该都很熟系了,常用的分库分表、读写分离等等这时都排上用场了。

五、底层架构

1、K8s弹性伸缩在高峰期提前扩容、高峰期之后缩容。在流量突刺时快速扩容,在流量下落时缩容。k8s提供了多种灵活的弹性伸缩机制,可以根据不同场景和需求自动调整集群的资源使用,确保系统能够在负载波动时稳定运行。根据实际的应用场景,合理配置这些伸缩机制,能够有效提升系统的弹性和可用性。最重要的是,比之前使用CVM物理机,能极大地降低服务器成本

2、微服务架构:微服务架构通过将单一应用拆分成多个独立的服务,使得每个服务可以独立扩展和维护,从而提高系统的可扩展性和维护性。例如直播间红包是一个服务、直播间签到是一个服务、直播间抽奖又是另一个服务...。这些服务通常是在单独的服务去维护,尽量做到互相隔离,互不影响

六、日志监控和告警

假如现网服务出现了问题,我们如何快速地感知呢?那当然是在各个关键服务都增加日志记录,然后增加监控告警,触发某个阈值时就告警。尽量在用户感知到问题前,我们去发现到并解决。

以上,就是我们在设计高并发系统时,需要考虑的一些问题和一些解决方案。当然,这里只是讲了大的宏观架构层面,落地到具体的业务场景中,还需要结合实际情况去思考一些细节和方案,去解决实际的性能瓶颈点,这是一件非常有意思的事,希望大家都能从解决问题中收获快乐

文章转载自:snail_lie

原文链接:如何打造一个高并发系统? - snail_lie - 博客园

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

http://www.xdnf.cn/news/302347.html

相关文章:

  • linux redis 设置密码以及redis拓展
  • ROS2:话题通信CPP语法速记
  • 从零开始学习人工智能(Python高级教程)Day6-Python3 正则表达式
  • c++学习合集(2025-4-29)
  • setup 函数在 Vue 3 中的作用是什么?什么时候会执行
  • ASP.NET Core 中间件
  • git flow
  • 线性回归有截距
  • 电子电器架构 --- 网关ECU中采用多CPU解决方案来实现网关功能
  • 《算法导论(第4版)》阅读笔记:p9-p9
  • NestJS 的核心构建块有哪些?请简要描述它们的作用(例如,Modules, Controllers, Providers)
  • vue3 computed方法使用详细讲解
  • LeetCode 790 多米诺和托米诺平铺 题解
  • 深入解析 Linux/Unix 通信机制:从原理到观测实践
  • 第四章 Java基础-判断和循环
  • I2C总线驱动开发:MPU6050应用
  • 牛客——暴力、技巧、字符与数组的使用(强强联合、字符数量)
  • [三分钟]性能测试工具JMeter入门: 下载安装JMeter并设置中文;JMeter基本使用流程
  • Linux(十四)进程间通信(IPC),管道
  • leetcode0542. 01 矩阵-medium
  • 第八章,STP(生成树协议)
  • [论文阅读]Deep Cross Network for Ad Click Predictions
  • C# 使用SunnyUI控件 (VS 2019)
  • 上市公司-企业上下游供应链数据(2003-2023年)-社科数据
  • 解释 NestJS 的架构理念(例如,模块化、可扩展性、渐进式框架)
  • 【MongoDB篇】MongoDB的事务操作!
  • VBA ListBox/ComboBox 响应鼠标滚轮操作
  • Java中常见的问题
  • Jupyter Notebook为什么适合数据分析?
  • [监控看板]Grafana+Prometheus+Exporter监控疑难排查