高并发场景以及应对技巧-程序员宅基地

技术标签: 架构  java  运维  自动化运维  数据库  运维基础  


高并发现实生活中的场景

我们总是喜欢从软件开发层面理解高并发,其实高并发是解决大数据量业务的一种思路,源于现实生产生活中的场景。高并发现实生产生活中的场景,包括但不仅限于如下内容:战争、新冠疫情防控、医院看病、完成工作任务、工厂生产、参加庙会、乘坐公共交通等等。如何提高这些现实生产生活中高并发场景的效率、消除弊病,都是我们需要解决的问题。

1 高并发基础

1.1 并发与并行

在这里插入图片描述

Erlang 之父 Joe Armstrong 用一张5岁小孩都能看懂的图解释了并发与并行的区别。

并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机,那么哪怕前面那个人便秘了去厕所待半天,后面的人也只能等着他回来才能去接咖啡,这效率无疑是最低的。

并行(parallelism):

所谓并行,就是同时执行的意思。判断程序是否处于并行的状态,就看同一时刻是否有超过一个“工作单位”在运行。所以,单线程永远无法达到并行状态。要达到并行状态,最简单的就是利用多线程和多进程。

并发(concurrency):

并发指的是程序的“结构”。当我们说这个程序是并发的,实际上,这句话应当表述成“这个程序采用了支持并发的设计”。好,既然并发指的是人为设计的结构,那么怎样的程序结构才是支持并发的设计?正确的并发设计的标准是:使多个操作可以在重叠的时间段内进行。

1.2 什么是高并发

高并发(High Concurrency)一般是指,通过设计保证系统能够同时并行处理很多请求。评价高并发处理能力的一些指标有响应时间(Response Time)、吞吐量(Throughput)、每秒查询率QPS(Query Per Second)、并发用户数等。

响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。

吞吐量:单位时间内处理的请求数量。

QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分不太明显。

并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。

高并发:同时或者在极短时间内,有大量的请求到达服务器,每个请求都需要服务端耗费资源进行处理,并做出相应的反馈。

1.3 从服务端视角看高并发

服务端处理请求需要耗费服务端的资源,比如能同时开启的进程数、能同时运行的线程数、网络连接数、CPU、I/O、内存等等,由于服务端资源是有限的,那么服务端能同时处理的请求也是有限的。

高并发问题的本质就是:资源的有限性。

1.4 高并发带来的问题

高并发问题描述的是客户端请求服务端的问题,并非我们常说的Web浏览器到服务器的请求。高并发问题也不是互联网应用独有的。

客户端同时大量请求服务端,服务端的处理和响应会越来越慢,甚至会丢弃部分请求不予处理,更严重的会导致服务端崩溃。
在这里插入图片描述

1.5 高并发问题层面


从“Web请求”层开始,到“Web应用”层,“Web应用”层可以分为“Web前端”和“Web后端”,再到“业务服务”层,最后到“数据库”层。
分层架构下的客户端、服务端解释如下:

  • “Web请求”层与“Web前端”层互为客户端、服务端;
  • “Web前端”层与“Web后端”层互为客户端、服务端;
  • “Web后端”层与“业务服务”层互为客户端、服务端;
  • “业务服务”层与“数据库”层互为客户端、服务端。

2.高并发应对技巧

2.1应对思路

2.1.1 客户端

在这里插入图片描述
同为客户端的应对思路有:
尽量减少请求数量,比如:依靠客户端自身的缓存或处理能力,过滤非正常请求;
尽量减少对服务端资源的不必要耗费,比如:重复使用某些资源,如连接池;客户端处理的基本原则就是:能不访问服务端就不要访问。

2.1.2 服务端

在这里插入图片描述
同为服务端的应对思路有:
增加资源供给,比如:
(1)更大的网络带宽;
(2)使用更高配置的服务器、高性能的服务器;
(3)使用高性能的数据库服务器。
请求削峰限流,比如:漏斗桶、令牌桶、计数器、消息队列。
请求分流,比如:
(1)使用集群;
(2)分布式的系统架构。
应用优化,比如:
(1)使用更高效的编程语言;
(2)优化处理业务逻辑的算法;
(3)优化访问数据库的SQL。

2.1.3 服务端处理基本原则

服务端处理基本原则是:削峰限流、分而治之,并提高单个请求的处理速度。

2.2 应对手段

后续将按照每个层面来谈谈应对的具体手段,不是高并发应对方案,方案是要结合具体的应用,综合分析,选择合适的手段组合起来的。

同时,以下提到的每个层面的应对手段都是“包含但不限于”。

2.2.1 客户端

在这里插入图片描述

  • 尽量利用浏览器的缓存功能,减少访问服务端,比如:js、css、图片等;
  • 可以考虑利用压缩传输的功能,减少网络流量,也会提高传输速度;
  • 考虑使用异步请求,分批获取数据。

2.2.2 服务端(CDN、Nginx)

在这里插入图片描述

  • 使用CDN服务;
  • 动静分离,部分静态资源可以直接从Nginx返回;
  • 按请求的不同,分发到不同的后端进行处理,比如:负载均衡、业务拆分访问等;
  • 前面再加上一层来做多个Nginx的负载均衡,比如:LVS、F5、Keepalived等;
  • 对动态内容进行缓存,尽量减少访问后端服务(或采用其他中间件)。

2.2.3 服务端(Web Server)

在这里插入图片描述

  • 使用最新的JVM,并进行配置优化,Java优化;
  • 动态内容静态化;
  • 对Web后台服务器进行配置优化,比如:调整内存数量、线程数量等;
  • 对Web后台服务器进行集群,或者提供多个能提供相同服务的Web服务器,以实现负载均衡;
  • 仔细规划Web后台服务器上部署的应用规模;
  • 提供专门的图片、文件、视频等静态资源服务器。

2.2.4 服务端(业务服务)

在这里插入图片描述

  • 使用最新的JVM,并进行配置优化、Java优化;
  • 动态内容静态化;
  • 优化处理业务逻辑的算法;
  • 合理高效的利用缓存;
  • 优化访问数据库的Sql,可以考虑利用存储过程等数据库的能力;
  • 合理使用多线程,加快业务处理;
  • 部分业务可以考虑内存数据库,或者进行纯内存处理;
  • 尽量避免远程调用、大量I/O等耗时的操作;
  • 合理规划事务等较为耗资源的操作;
  • 合理使用异步处理;
  • 对部分业务考虑采用预处理或者预计算的方式,减少实时计算量;
  • 内部系统间的业务尽量直接调用、直接处理,减少WebService、工作流等;
  • 对业务服务器进行集群,或者提供多个能提供相同服务的业务服务器,同样借助Nginx以实现负载均衡。

2.2.5 服务端(数据库)

在这里插入图片描述

  • 合理选择数据库的引擎,比如MySQL的InnoDB与MyISAM引擎;
  • 进行性能配置优化;
  • 可以考虑使用存储过程来处理复杂的数据逻辑;
  • 数据库集群,进行读写分离;
  • 合理设计数据库的表结构、索引等;
  • 分库、分表,降低单库、单表的数据量;
  • 合理使用NoSql。

3. 高并发场景

以下篇幅通过分析秒杀业务场景为例,针对性地采用上面提到的一些知识,提供秒杀业务场景的应对方案,当然同样是包括并不仅限于这些内容。

3. 1 秒杀

秒杀场景一般会在电商网站举行一些活动或者节假日在12306网站上抢票时遇到。对于电商网站中一些稀缺或者特价商品,电商网站一般会在约定时间点对其进行限量销售,因为这些商品的特殊性,会吸引大量用户前来抢购,并且会在约定的时间点同时在秒杀页面进行抢购。

秒杀特点:

  • 秒杀时大量用户会在同一时间同时进行抢购,网站瞬时访问流量激增;
  • 秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功;
  • 秒杀业务流程比较简单,一般就是下订单减库存。

3. 2 秒杀设计理念与思路

限流: 鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。

分流:负载就是问题,高并发问题。均衡就是解决手段。

削峰:对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存和消息中间件等技术。(nginx的漏斗原理)

异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。(可以把数据放入表里面,后台排队处理)

内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大提升。

可拓展:当然如果我们想支持更多用户、更大的并发,最好将系统设计成弹性可拓展,如果流量来了,拓展机器就行。像淘宝、京东等,双十一活动时会增加大量机器应对交易高峰。(上云容器化,高度可扩展性)

3. 3 秒杀应对方案

  • 准备工作:
    – 系统最好独立部署;
    – 做好系统性能容量规划(一般7折计算),系统优化,容灾过载保护;
    – 做好系统拆分,比如:按功能模块、按实时/非实时、按动态/静态等等;
    – 设置定时上架的时间;
    – 服务器时钟同步;
    – 动态生成下单页面的URL。
    在这里插入图片描述

  • Web应用层:
    – F5/LVS + Nginx来接收高并发的请求,并做负载均衡;
    – Nginx + Lua + Redis 来做请求队列,并实现一些基本控制,比如:限流、账号参加次数检查、同一IP请求数检查等;
    – Nginx、Varnish或者其他中间件来缓存静态页面和静态资源;
    – 进入Tomcat集群,先做一个预处理,就是判断这些账户是否能参与活动,比如:账号等级是否足够、账号行为是否正常、是否在黑名单上等。
    在这里插入图片描述

  • 业务服务层:
    按照Redis的请求队列进行先后处理;
    纯内存操作 + 异步;
    控制超卖;
    Redis里面存放着SKU的库存数据;
    处理成功的信息也存放在Redis里面。

  • 其他全局考虑:
    合理设计接口;
    应当时告知用户结果;
    考虑业务规则,比如减库存的时机;
    服务器尽量集群,并做HA,避免雪崩;
    库存预热,秒杀前,通过定时任务或者运维人员提前把商品的库存加载到Redis中,让整个流程都在Redis里面;缓存服务器如果要重启,也要做预热;
    对抗作弊,比如:同一账户同时发多个请求、同一IP同时发大量请求、秒杀器采用多账户多IP发送请求等;
    服务单一原则,秒杀就是秒杀服务,商品就是商品服务,一个服务挂了,不至于把其他服务搞崩溃;
    削峰填谷MQ,你可以把它放入消息队列,然后一点点消费去改库存就好,不过单个商品其实一次修改就够了,这里说的是某个点多个商品一起秒杀的场景。

总结

提示:在想想

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44800629/article/details/127628486

智能推荐

一、Jquery入门(超详)-程序员宅基地

文章浏览阅读4.3k次,点赞21次,收藏48次。本文将带领大家了解 jQuery 的定义,它有什么作用,我们为什么要学它,以及如何使用它,它的语法是什么,最后对比了 jQuery 对象和 DOM 对象的区别。_jquery

【SassError: expected selector报错 用::v-deep 替换 /deep/的真实写法】_unexpected unknown pseudo-element selector "::v-de-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏2次。关于SassError: expected selector报错 ::v-deep 替换 /deep/的正确替换方式_unexpected unknown pseudo-element selector "::v-deep

Linux学习笔记 第0章:计算机概论_字长 位宽-程序员宅基地

文章浏览阅读301次。0.1.0计算机本质计算机:接受用户输入的命令与数据,经由中央处理器的算术与逻辑单元运算处理后产生储存成有用的信息算术逻辑单元(Arithmetic&logical Unit:是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分,由与门 和或门构成的算术逻辑单元,主要功能是进行二位元的算术运算,如加减乘(不包括整数除法)。基本上,在所有现代CPU体系结构中,二进制都以补码的..._字长 位宽

Curve25519 Field域2^255-19内的快速运算_curve25519标量乘-程序员宅基地

文章浏览阅读1.2k次,点赞3次,收藏3次。1. 引言对于Curve25519,其Field域内的module Fp = 2255-19。若采用常规的Montgomery reduce算法,其运算性能并不是最优的。如要求某整数 u mod (2^255-19),可将m整数用多项式做如下表示:u=∑iuixi,其中,ui=n∗2⌈25.5i⌉,n∈Nu=\sum_{i}^{}u_ix^i,其中,u_i=n*2^{\left \lce..._curve25519标量乘

超全golang面试题合集和答案+golang学习指南+golang知识图谱_goland面试题-程序员宅基地

文章浏览阅读6.8k次,点赞3次,收藏68次。https://blog.51cto.com/u_15102959/2637222_goland面试题

Python实现自动挂机脚本(基础篇)_我是农场主自动挂机脚本-程序员宅基地

文章浏览阅读8.4w次,点赞67次,收藏608次。不知不觉肝阴阳师也快一年了,对这游戏真是又爱又恨,最近刚刚发布了PC版,突然很想尝试着写个脚本挂机,话不多说进入正题。简单的鼠标操作游戏挂机脚本,无非就是自动移动鼠标,自动点击,进行重复操作,所以,第一步就是如何控制鼠标_我是农场主自动挂机脚本

随便推点

假设你们的社团要精选社长,有两名候选人分别是A和B,社团每名同学必须并且只能投一票,最终的票多的人为社长。-程序员宅基地

文章浏览阅读33次。输出描述:一行,一个字符,A或B或E,输出A表示A得票数多,输出B表示B得票数多,输出E表示二人得票数相等。输入描述:一行,字符序列,包含A或B,输入以字符0结束。

BeanFactory和ApplicationContext有什么区别?_beanfactory和applicationcontext是干什么的-程序员宅基地

文章浏览阅读2.2k次,点赞2次,收藏2次。BeanFactory和ApplicationContext有什么区别? BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。(1)BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理..._beanfactory和applicationcontext是干什么的

java 项目管理 maven2.0学习笔记 _apt fml fr-程序员宅基地

文章浏览阅读4.5k次。转贴:http://blog.csdn.net/shiqiang1234/archive/2006/10/12/1331725.aspxMaven简介Maven最初的目的是在Jakarta Turbine项目中使构建处理简单化。几个项目之间使用到的Ant build文件差异很小,各个JAR都存入CVS。因此希望有一个标准的方法构建各个工程,清晰的定义一个工程的组成,一个容易的方法去发布项目_apt fml fr

【linux之进程间通信】——管道_管道read-程序员宅基地

文章浏览阅读2.6k次,点赞9次,收藏11次。进程间是怎么通信的之前我们说过,进程与进程之间是相互独立的,它们的数据也是绝对独立的,那么如果一个进程要向另一个进程发送数据,发送消息等通信,那么这时怎么做到的呢?管道所谓的管道,是内存中的一个缓存文件,进程A在管道写入数据,实际是写入到内核中的缓存文件中,进程B从管道中读取数据,实际是从内核的缓存文件中读取数据。管道的传输数据是单向的,只能由一个进程写入,一个进程读出。匿名管道概念匿名管道是没有名字的,它是特殊文件,它只存在内存中,不存在我们文件系统中,即用完就销._管道read

DermoSegDiff: A Boundary-aware Segmentation Diffusion Model for Skin Lesion Delineation-程序员宅基地

文章浏览阅读445次,点赞5次,收藏10次。DermoSegDiff:用于皮肤病变描绘的边界感知分割扩散模型摘要:皮肤病变分割对皮肤病的早期发现和准确诊断起着至关重要的作用。消噪扩散概率模型(ddpm)最近因其出色的图像生成能力而受到关注。在这些进展的基础上,我们提出了DermoSegDiff,这是一个在学习过程中包含边界信息的皮肤病变分割的新框架。我们的方法引入了一种新的损失函数,在训练过程中对边界进行优先排序,逐渐降低其他区域的重要性。我们还介绍了一种新的基于u - net的去噪网络,该网络可以熟练地将网络内的噪声和语义信息集成在一起。在多个_dermosegdiff

常用集函数,count(),sum(),avg(),max(),min()_python round(avg_score, 2)-程序员宅基地

文章浏览阅读1.3w次。1. count()返回匹配制定条件的行数 count(*)返回在给定的选择中被选的行数。2.sum()返回组中所有值的和。sum只能用于数字列,空值会被忽略!3.avg()返回组中值的平均值,空值回避忽略!4.max()返回组中值的最大值5.min()返回组中值的最小值6.过滤掉最低分小于60的学生select snum,sum(scor_python round(avg_score, 2)

推荐文章

热门文章

相关标签