一文教你如何处理高并发

目录

前言 

一、为什么要解决高并发问题

二、性能评估

计算峰值流量方法

本章结论

三、性能测试

测试目的

找到系统最高承受压力的临界点

找出系统中的短板

测试工具

简单测试

1.数据抓包

2.加压测试

3.硬件跟踪

4.JVM跟踪

5.其它组件测试

6.总括

全链路测试(待补充)

其它专项测试(待补充)

四、性能提升的思路

降低峰值带宽

减少客户端即时请求次数

默认数据+延迟更新

接口合并

异步处理+合并请求

负载均衡

缓存的使用

客户端缓存

服务器缓存

CDN缓存

服务端缓存(待补充)

性能提升评估

五、监控报警及扩容

监控报警(待补充)

扩容(待补充)

六、总结


前言 

前言:面试的时候,面试官与你的聊天对话,是不是这样的:

第一种:

        问:怎么解决高并发?

        答:读写分离、分库分表、搜索引擎、分布式集群、消息队列、负载均衡......

        问:技术方案呢?

        答:SpringCloud、Dubbo、Redis Cluster、ES......

        问:还有吗?

        答:阿巴阿巴阿巴

        问:怎么实施?

        答:我......

        问:那么用了你这套技术方案,并发量能到多少呢?

        答:我.....

第二种:

        问:怎么解决高并发?

        答:分布式

        问:用了分布式就能解决高并发?

        答:阿巴阿巴阿巴

        问:你说的分布式是不是就是加机器?

        答:差不多是这样

        问:比如让你做10w用户同时在线,那加多少呢?

        答:我......

        问:加了之后能满足吗?

        答:我......

是不是跟你很像?那么带着这些问题,我们来看一看高并发应该如何处理。

一、为什么要解决高并发问题

1. 保障应用的正常运行

在任何情况下,都要保证用户正常使用。

2.保证资源的合理使用

公司是我们赖以生存的环境,合理爱护公司资源!!!

3.异常情况的应急处理

避免网络、内存、硬盘、CPU异常导致服务宕机;流量激增的情况下,防止服务垮掉。

二、性能评估

计算峰值流量方法

方法一:通过日PV计算

        公式:峰值流量=(日PV*80%)/(60*60*24*20%),即每天80%的访问集中在20%的时间

方法二:通过项目经验给出基本判断

        公式:峰值流量=用户在线数/(60*60*8)*N,N为预估倍数,一般为5到30倍

        比如,我们项目有10w人用户同时在线,因为用户不可能平均分布在每天8个小时内(8个小时为工作时长),所以我们估算出同时在线人数。

方法三:接入第三方统计得出峰值流量和用户数据(推荐)

        统计平台包括:友盟、极光、百度、Google Analytics、FireBase等,接过的同学一看就明白,没接过的自己去了解下吧,这里不多做赘述。

以下统计都以极光为例,数据很惨,哈哈哈。

用户增长趋势(极光统计)

用户增长趋势图

用户活跃统计(极光统计)

用户活跃统计图

用户访问路径统计(极光统计)

用户访问页径统计图

用户访问页面统计(极光统计)

按照用户访问页面,分析用户访问行为,如下图(示例): 

用户访问页面统计图

本章结论

1.我们可以通过以上的几种方法得出峰值的并发数。

2.如果接入统计,我们可以按用户在线人数、页面的访问路径、页面访问频次等做更加细粒度的规划,也就是在峰值流量期间,用户分布在什么功能点

FAQ

1.为什么要定义并发数

为了更趋向于真实用户访问,我们需要给出准确的并发数,以便于后续并发测试、系统优化,这样得出的结论才会有说服力。

2.并发数评估方式的有哪些

你可以按自己的方式评估,也可以百度去搜,方法不限,但最终的目的都是模拟真实的用户访问

3.为什么要接入第三方统计

接入第三方统计分析,可以很好的反映出在线人数、流量峰值、页面访问数等信息,对我们评估并发数有很好的帮助。

三、性能测试

测试目的

找到系统最高承受压力的临界点

测试系统能不能达到我们预期的并发数,并找到临界点。如果可以承载,那么多少的并发量,能把系统压崩;如果不能承载,那么系统可以最高可以承受多少的并发量

找出系统中的短板

根据最短木板原理,找出系统性能最差的地方,对症下药,才能达到更好的效果。

测试工具

测试工具为前要条件,给大家简单介绍一下

  • 任意抓包工具(重要),比如Charles、Burp Suite等
  • 性能测试工具,比如Jmeter、LoadRunner等
  • 数据库测试工具,比如MySQL测试可以使用sysbench
  • 缓存测试工具,比如Redis测试可以使用redis-benchmark
  • 各个厂商浏览器
  • 各种厂商手机

简单测试

服务器硬件环境:硬盘60G,内存4G,带宽2M,CPU2个

使用主流品牌手机,在网络较好的情况下,打开今日某条

1.数据抓包

测试并记录步骤如下:

序号步骤接口数量接口内容占用总耗时
1打开应用,进入引导页2个0.1k

0.8s

2从引导页进入首页4个0.74k1.5s
3点击某一条新闻,进入详情页1个1.4k1.4s
4打开搜索框,进入搜索页2个0.3k1.2s
5输入内容,进行搜索1个0.8k1.3s

注:数据为凭空捏造的,只是为了说明都需要干什么

名词解释

接口内容占用:指的是[请求体+返回体]内容占用的总字节数

总耗时:从用户点击到页面内容渲染完成的总耗时

2.加压测试

1.把上述所有接口,按照接口请求顺序,生成Jmeter脚本

2.Jmeter启动参数设置:线程数:20,循环次数:永久

3.此时会有20个线程在一直请求这些接口,即模拟20个用户同时在线。

4.此时我们再来使用APP,即:

序号步骤接口数量接口内容占用总耗时
1打开应用,进入引导页2个0.1k

1.7s

2从引导页进入首页4个0.74k5.3s
3点击某一条新闻,进入详情页1个1.4k2.1s
4打开搜索框,进入搜索页2个0.3k2.5s
5输入内容,进行搜索1个0.8k2.2s

我们可以看到总耗时对比之前有所增加。

我们可以持续增加线程数,一直压到接口无响应,即为临界点。

3.硬件跟踪

我们观测服务器硬件使用情况为(示例):

CPU内存硬盘带宽
15%75%20%0.9M

服务器硬件使用情况,可以借助第三方云厂商DashBoard进行查看,如下为阿里云:

4.JVM跟踪

跟踪JVM使用情况为(可以使用阿里的arthas查看,官网在这里:https://arthas.gitee.io/):

关于JVM的简单分析

        元空间:元空间包含:类的信息、方法数据、方法编码、常量池。如果元空间内存占用过大,需要看一下是不是有很多反射、代理等。

        年老代:如果年老代内存占用过高,或者gc次数过多,就需要我们去调优,或增加硬件资源

        年轻代:emmm,一般来说前面两个没问题,这个就不需要看,前面两个有问题,那就调前面两个。

5.其它组件测试

Web服务器测试:测试Nginx、Apache等Web服务器的吞吐量,可以使用Jemeter测试。

缓存测试:测试缓存的吞吐量,比如只读、只写、读写的情况下每秒可以处理的并发数。工具:redis-benchmark可以用来测试Redis

数据库测试:测试数据库的吞吐量,跟缓存的测试方法差不多。工具:sysbench可以用来测试mysql

服务端组件测试:其它组件像消息队列、搜索引擎、注册中心等都有自己的测试工具就不一一列举了,自己去百度搜吧。

6.总括

1.我们需要按照产品功能的使用步骤进行访问,并记录下访问过程中的各项数值

2.递增式的对接口进行加压测试,直到接口无响应。

3.在测试期间,我们观察并记录硬件和GC的使用情况,并记录各项数值。

4.我们可以再把数据库、缓存、消息队列等也进行递增式的压力测试,得到各个组件的临界点。

5.最后我们得到了:

        1)系统中所有接口的吞吐量

        2)各项服务组件的吞吐量

然后,我们就可以根据我们性能评估的并发数,来测试我们的系统是否可以承载

如果不能,则根据测试的数据报告,找出性能最弱的项,对其进行优化

全链路测试(待补充)

其它专项测试(待补充)

白屏测试:用户从浏览器输入网址,到浏览器开始显示内容的时间。

首屏测试:用户从浏览器输入网址,到首屏内容渲染完成时间,此时整个网页不一定要全部渲染完成,但在当前视窗的内容需要

资源加载测试:统计页面中图片、js、字体等,从页面打开到资源加载完成时间。

RAIL指标:参照:03 RAIL 评估模型介绍 · 前端性能监控与体验优化实战 · 看云

FAQ

1.有人会问,我又不是测试工程师,为什么要我知道这些测试东西?

1)测试是评估系统吞吐量最直观的方法,也是最重要的一环之一;

2)身为团队的Leader,我们也应该知道让测试给出什么样的结果

3)我们应该知道什么样的测试的方法是正确的,如果测试的同学达不到预期,我们可以指导并协助他做好测试工作。

四、性能提升的思路

降低峰值带宽

        解释:减少单次请求的数据量,按需拿取数据。即:客户端从服务端获取数据时,先拿首屏展示的数据,再预加载后续的数据。这样分段式的请求会降低峰值带宽

        例[1]:[今日某条]的[推荐列表],每屏展示信息不超过4条,那就每次拿4条。

        例[2]:[某宝]的[购物车列表],每屏展示信息不超过5条,那就每次拿5条。   

假如:

        每条数据为1KB

        当前在线人数为1000人

        每个用户平均每人看看30条信息

        把之前每页10条的改成每页5条后,假设用户每屏信息看1秒,得到如下表格

改版前带宽改版后带宽
第一秒1K*10条*1000=10M1K*5条*1000=5M
第二秒01K*5条*1000=5M
第三秒1K*10条*1000=10M1K*5条*1000=5M
第四秒01K*5条*1000=5M
第五秒1K*10条*1000=10M1K*5条*1000=5M
第六秒01K*5条*1000=5M

思路:服务端拼装数据量变小,客户端渲染的更快,且峰值带宽占用减少,可以节省硬件成本。

FAQ

问:这样虽然峰值带宽降了,但是用户体验比以前差了呀

:可以用其他策略来规避,方法不限,示例:

        方法[1]:先加载首屏数据条数(比如5条),等数据渲染后,再加载后续数据

        方法[2]:先加载首屏数据条数,根据用户手势滑动行为,预加载后面数据(参考今日头条)

        方法[3]:首屏加载数据条数和预加载数据条数,根据产品差异化加载。比如:首次加载10条,后续按照滑动手势每次递增5条。

问:那每次拿几条是适合的呢?

:如果你不确定,那你就先定一个默认值,后续跟踪用户行为进行调整,比如:用户每屏可以看到多少数据;点击了多少次下一页;每次手势滑动距离有多大,涵盖多少数据;平均每个用户看多少条数据等,毕竟合适才是最好的。

问:那么怎么跟踪用户行为和跟踪调整后的用户反馈呢?

:接第三方统计可以跟踪用户行为,但是需要客户端的同学对用户操作行为进行埋点。跟踪用户反馈的话使用A/B Testing,不懂的自行百度。

减少客户端即时请求次数

        解释:页面渲染数据时,即时请求的接口越少,渲染速度越快。

以[今日某条]为例:

进入首页时,需要渲染[频道/label]+[置顶]+[信息流]三个类目的数据。

一般来说我们会把三个类目的数据做成三个不同的接口。

下面给大家列举几种策略:

默认数据+延迟更新

以[今日某条]中的[频道]为例(label栏)

        1.先把[频道]的数据给几个默认值,比如[推荐]、[热榜]、[发现]、[视频]、[问答]、[音乐]等

        2.我们拿[频道]数据的时候,从缓存里拿。如果缓存没有,就创建子线程发起异步延迟请求

        3.异步延迟请求从服务端获取最新数据后,写入缓存,再通知主线程

        4.主线程从缓存中获取最新的[频道]数据,并进行渲染,或下次打开渲染

        5.客户端做好更新策略,比如[定时更新],[按用户点击频道次数更新]等

        6.另外,如果首页渲染完成之后,用户直接滑动[频道]栏,那么就[缓存]+[请求接口]进行渲染

接口合并

以[今日某条]中的[置顶]+[信息流]为例

        1.现有[置顶]的[接口A],[信息流]的[接口B]

        2.服务端再创建一个[接口C],且C=A+B

        3.如果客户端请求第一页的数据,那么服务端会把[置顶]和[信息流]的数据一并返回

异步处理+合并请求

以[今日某条]中的[点赞]、[收藏]为例

        1.用户在客户端对文章[点赞/收藏]时,先把[文章]的数据存储到本地,不发送网络请求

        2.把用户当前的文章状态改为[已点赞/已收藏]

        3.当用户查看[点赞/收藏]列表时,从本地加载数据

        4.制订数据上报策略,比如[按时间间隔上报]、[按点赞次数上报]等

        5.制订数据更新策略,即按时间间隔,从服务端拿数据

        6.其它问题:

                6.1.数据上报,信息有可能被篡改,需要做安全加密处理

                6.2.数据更新,如果有多端登录,比如PC+手机,需要考虑多端同步问题

优势:

        默认数据+延迟更新:在不影响主要业务的情况下,加快渲染速度

        接口合并:减少网络开销

        异步处理+合并请求:从缓存中获取数据,效率更高

FAQ

问:把点赞、收藏等这些数据存到本地,如果数据未上报就丢失了怎么办

答:

        1.比如[应用卸载/换手机]这些操作肯定会导致数据丢失,但这些情况毕竟占少数。

        2.站在用户的角度,用户只在乎自己是否点赞成功,可能不在乎别人是否收到了赞;

        3.用户点击收藏之后,就能在收藏列表看到已收藏文章,至于有没有上传到服务器,用户是无感知的。

        4.就算数据丢失,用户也不一定记得对哪个文章点过赞;或者记得对哪个文章点过赞,发现没点赞成功,可能是因为自己网不好。

        5.如果这类数据的价值可以覆盖成本,那么就不要这么做了。把数据提交到服务端,服务端写入到缓存,然后再定时把数据同步到数据库。

负载均衡

把任务拆分到多个单元进行执行,共同完成工作任务。

例1:把商城系统分成订单、商品、库存、商铺等多个模块,如需扩容就把相应模块进行横向扩容,也就是大家经常说的分布式+微服务。

例2:把一些服务中间件(如消息队列、搜索引擎)的各个节点,根据所需进行横向扩容。

说白了,就是把服务拆分成多个子模块或子节点,便于精准扩容。

缓存的使用

客户端缓存

打开应用,把请求到的数据都缓存起来,下次进入相同的页面后尽量不请求接口。(前端我会的不多)

需要增量更新的数据可以异步更新,或者引导用户去刷新

服务器缓存

Web服务器可以缓存js、图片、静态网页等一系列信息。

值得一提的是对于静态文件,客户端多次发起请求时资源未改动,http状态码会返回304即页面无改动,表示客户端可以从本地缓存拿相应资源。

CDN缓存

图片、视频、静态资源、大文件等可以使用第三方的CDN服务,加快访问速度,节省服务器带宽

服务端缓存(待补充)

服务端缓存都是以服务器内容为主。以Redis为例,官方表示单线程Redis吞吐量达到10w/每秒。

如果使用得当,可以解决大部分中小公司的性能问题

间隔性数据更新

首次查询后,把数据从数据库放入放入缓存;数据更新时,计算要统计的各项数值,以数据驱动的方式写入缓存。

以考试报名统计为例

活动名称姓名活动开始时间活动结束时间所在城市订单号订单创建时间订单状态.....等几十个字段

相信有的朋友做过这种类型的报表吧,从多张表中获取数据,无论怎么优化,效率都特别低。

改进建议:

        数据查询:只从缓存中拿数据,如果未获取到数据,则通知[数据更新任务]

        数据更新任务:异步从数据库的各个表中拿数据,然后拼装,最后写入缓存

        增量更新:如果数据有[新增/修改],去缓存中找到相应的key,进行增量更新操作

改进后缺点:数据更新可能会延迟,延迟取决于数据查询的速度

改进后优点:极快!!!

后续我会专门写一篇[如果使用Redis做缓存]的博客主题

性能提升评估

当你真正去做的时候,你照着网上抄来的技术方案,给领导看或同事们看,他们有没有不认同你的方案,或对你的方案不屑一顾?那么问题的出在哪里呢?

其实很简单:

        1.我们可先去做性能测试得到一份性能报告

        2.根据性能报告找出系统的性能最差的地方,再制定相应的优化方案

        3.制定优化方案后,再把提升的性能指标量化出来

当你拿出[性能报告+优化方案+提升结果]再去汇报的时候,想必成功率就很高了。

五、监控报警及扩容

上线后,我们要对服务进行监控,避免服务有异常情况发生。

监控报警(待补充)

一般来说,我们会对CPU,内存,硬盘、网络四个要素进行监控。

我们用的阿里云自带免费的报警,示例:

也可以使用脚本的方式,对报警的信息,发邮件处理。

扩容(待补充)

监控报警后,对于报警的相关项进行扩容。

六、总结

本文介绍了解决高并发的的通用的思路,包括性能评估、性能测试、性能优化、性能优化数据报告、监控以及扩容。这些都是我在项目里遇到的,我把这些总结了一下,分享给大家。以上是我对高并发的理解,望不足之处大家能够指正。

对我来讲,高并发的核心只有一个,就是你要明白问题出在哪?

比如说:

  • 项目中哪里的效率低,要不要去优化(比如功能用的少不一定要去优化) ?影响项目的短板在哪里?
  • 是应该优化还是应该加机器?优化的话需要优化哪里?是由前端负责还是由后端负责?加机器应该加多少?
  • 在现有项目中,影响项目并发的哪个硬件是短板?CPU、内存、硬盘、带宽、GPU?
  • 在现有项目中,多少量级的用户,需要多少的硬件来支撑?用户达到多长量级的时候需要扩容?

对于高并发来说,没有最好的方案,只有最合适的方案。

再回答一下开头的问题

1.怎么解决高并发

首先我们需要进行性能测试,然后逐步的找到性能瓶颈产生的地方,再对症下药。

2.高并发要用什么技术来解决

解决高并发跟技术和开发语言没关系,理论上来说:你机器的硬件越好,能承受的并发越高。比如说:一个要住500人的楼盘和要住3000人的楼盘,基建设施肯定会差很多的;往500人的楼盘塞3000人,无论怎么优化,效果可能都没那么好,所以合理的资源使用对我们有着至关重要的作用。

3.解决高并发的技术方案

其实也就是文章的主要内容:先性能评估,再性能测试,然后优化,最后给出优化后的结论。

4.分布式可以用来解决高并发吗

分布式可以用来解决高并发,思路就是把整个项目拆分成微服务,然后按需进行扩容。但是关键点是我们要知道:在什么时候应该扩容什么硬件。

4.SpringCloud、Dubbo、Redis Cluster、ES这些是怎么解决高并发的?

SpringCloud:把服务按模块拆分开,按照每个模块评估性能,按需扩容。

Dubbo:把服务按模块拆分开,按照每个模块评估性能,按需扩容。

Elastic Search:简单来说,就是把数据库的数据放到内存里,再建立索引,达到快速搜索的目的

Redis Cluster:

        1.先说Redis,Redis使用内存当存储空间,在1CPU 1G的服务器上QPS大概在10w左右。

        2.那如果超过10w怎么办?Redis Cluster给出了哈希槽的概念,简单理解就是Redis增加了Node(节点),Client写入的时候,会根据算法算出插入哪个Node,达到负载均衡的效果。一个Node的QPS是10w,最优的情况下10个节点QPS就是100w了。

自我评价

文章的前半部分写的还可以,有条理性,也比较直观一点。后半部分的话,我太想把我的想法和我对产品的看法表露出来,然后条理性变得很差,一堆一堆的字儿,搞的我自己都不太想去读。但是总体来说的话,我还是把我心中的那个高并发的认知给写出来了。后面有时间的话,肯定会把这篇文章重新梳理一下。

  • 16
    点赞
  • 150
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Eclipse是一个开放源代码的集成开发环境(IDE),可用于Java开发,但也可以用于其他编程语言的开发。在本文中,我将向你展示如何使用Eclipse进行Java开发。 1. 下载Eclipse 首先,你需要从Eclipse官方网站下载Eclipse IDE。下载页面上将提供几个不同的版本,包括Eclipse IDE for Java Developers、Eclipse IDE for JavaScript and Web Developers,以及Eclipse IDE for C/C++ Developers等。选择适合你的版本,然后按照安装向导进行安装。 2. 创建Java项目 一旦你安装了Eclipse,你可以启动它并创建一个新的Java项目。选择“File”->“New”->“Java Project”,然后按照向导创建一个新的Java项目。在创建项目时,你需要指定项目名称、项目类型以及JRE版本等信息。 3. 创建Java类 一旦你创建了一个Java项目,你就可以创建一个Java类。选择你的Java项目,在“src”文件夹上右键单击,然后选择“New”->“Class”。输入类名和选择要继承的类(如果有的话),然后点击“Finish”。 4. 编写Java代码 现在你已经创建了一个Java类,可以开始编写Java代码了。在Eclipse的编辑器中,你可以输入Java代码并保存它。当你保存Java文件时,Eclipse会自动编译你的代码,并在Problems视图中显示任何编译错误。 5. 运行Java程序 一旦你编写了Java代码并保存了它,你可以运行Java程序。右键单击Java文件,然后选择“Run As”->“Java Application”。如果一切顺利,你的Java程序将在控制台中输出结果。 6. 调试Java程序 如果你的Java程序出现了错误或不按预期运行,你可以使用Eclipse的调试器来调试它。在Eclipse的编辑器中,你可以设置断点并启动调试器。当程序执行到断点时,调试器会暂停程序并允许你检查变量、运行代码等。 7. 导入外部JAR包 有时,你可能需要使用外部JAR包来完成你的Java项目。在Eclipse中,你可以简单地将外部JAR包导入到你的项目中。右键单击Java项目,然后选择“Build Path”->“Configure Build Path”。在“Libraries”选项卡上,你可以添加外部JAR包。 总结 在本文中,我们介绍了如何使用Eclipse进行Java开发。我们学习了如何创建Java项目、创建Java类、编写Java代码、运行Java程序、调试Java程序以及导入外部JAR包。Eclipse具有强大的功能,可以大大提高Java开发的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值