浅谈web性能优化(一)

压力测试

        在浅谈性能优化之前呢,先介绍一下压力测试。项目在上生产环境之前呢,需要先进行压力测试,模拟并发,看看系统的吞吐量大概是多少,告知运维人员的系统吞吐量瓶颈,与实际业务场景对比,再决定是否继续优化业务逻辑,升级硬件环境。

概念

        压力测试考察当前软硬件系统的最大负荷以及瓶颈所在,是为了系统在线上的处理能力稳定性维持在一个合理范围内,做到心中有数。

错误类型

内存泄漏

        比如一个接口我们写好,在一个循环内大量创建对象,没有复用对象,当并发量一上来,我们的对象就会不断的进行创建,以至于导致我们的内存泄漏。

并发和同步

        当我们单线程跑起来没有问题,当我们的并发量一上来,就会出现各种线程不安全的情况。

压力测试的性能指标

当我们单线程跑起来没有问题,当我们的并发量一上来,就会出现各种线程不安全的情况。

压力测试的性能指标

  1. 响应时间(response time: RT)

  2. HPS(hits per Second):每秒的点击数;

  3. TPS(transaction per second):系统每秒处理的交易数(一个完整接口下的业务链条)

  4. QPS(query per second):系统每秒处理的查询次数

金融行业 :1000TPS-50000TPS:不包括互联网化的活动,5万

保险行业:100TPS-100000TPS:不包括互联网化的活动,10万

制造行业:10TPS-5000TPS,5K

互联网电子商务:10000TPS-1000000TPS,100w

互联网中型网站:1000-5wTPS

互联网小型网站:500-1wTPS

最大响应时间:我们测试了100w的请求,其中有个请求响应时间为90s;

从外部看,性能测试主要关注如下三个指标

  1. 吞吐量:每秒系统能处理的请求数和任务数(qps和tps)

  2. 响应时间:服务处理一个请求或者是一个任务的耗时

  3. 错误率:一批请求中结果出错的请求所占的比例

 压力测试工具-JMeter

压力测试吞吐量比较小,我们可以调整JVM内存

windows端口占用报错及其解决方式:

影响web性能的主要因素

数据库

应用程序

中间件(tomcat、nginx、gateway网关)

网络IO(当前网速慢,或是服务器压力大,或是当前带宽只有1M--10000请求,每个请求1KB的数据=10MB,会受带宽影响)

操作系统(不同系统,内核不同,处理方式不同)等方面。

影响性能的因素分类

首先考虑自己的应用属于CPU密集型(大量计算排序)还是IO密集型(网络IO和磁盘读写IO);

看监控:cpu和io和内存和网络流量的占用情况;

如果是CPU密集型:升级服务器硬件| 增加服务器台数

如果是IO密集型:换固态硬盘+内存条+使用缓存技术+提高网卡传输效率,单纯加cpu无法解决问题。

性能的监控与分析

java的内存模型分析

程序计数器:Program Counter Register

·记录的是正在执行虚拟机字节码指令地址

·此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemeoryError的区域。

虚拟机栈:VM Stack

·描述的是JAVA方法执行的内存模型,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法接口等信息。

·局部变量表存储了编译器可知的各种基本数据类型,对象引用。

·线程请求的栈深度不够会报StackOverFlowError异常。

·栈动态扩展的容量不够会报OutOfMemeoryError异常。

·虚拟机栈是线程隔离的,即每个线程都有自己独立的虚拟机栈。

本地方法栈:Native Stack

本地方法栈类似于虚拟机栈,只不过本地方法栈使用的是本地方法。

堆:Heap

几乎所有的对象实例及数组都在堆上分配内存;堆是垃圾收集器管理的主要区域,也被成为“GC”堆,也是我们优化最多考虑的地方。

关于堆内存回收流程

        所有对象实例以及数组都要在堆上分配。堆是垃圾回收器的主要区域,也被成为GC堆,也是我们优化最多的地方。JVM使用C语言写的,可以开辟空间,释放内存很麻烦。基于C再封装,写了个执行引擎,去来翻译写的java代码。

堆可以细分为

  1. 新生代

    1. Eden空间:新分配的对象到了eden区,先看看内存够不够,如果够呢,就直接分配内存;如果不够,就要进行一次GC,(进行一次young GC,也叫MinorGC,主要进行清理新生代的空间,eden里边存了10个对象,一个对象在用,其余9个对象不再用了,就把这9个踢出来,这一个对象呢我们还会把它放到幸存者区域里边。如果minorGC之后还放不下呢,我们呢就认为这个对象就是个大对象,我们尝试呢把它放到老年代-->老年代就是我们新生代无法进行处理的情况下才进入老年代的。如果老年代还是放不下呢,那么我们就要进行一次fullGC,大屠杀,把新生代和老年代所有区域的数据,如果没有用处了,全部都踢出去,踢出去以后呢,如果还放不下,那么就报错内存溢出了。oom-outofmemory内存溢出 )如果幸存者区域的的对象存活时间超过了阈值(小屠杀了十几次都还活着),就把他搬家到老年区。

    2. from suivivor空间【s0】

    3. to sruvivor空间【s1】

  2. 老年代

  3. 永久代/元空间

java8以前永久代,受jvm管理,java8以后改为了元空间,直接使用物理内存。因此,默认情况下,元空间的大小仅仅受本地内存限制。

利用java内存监控工具进行调优

jconsole与jvisualvm

e4a04c4202f17c8015e19e751bbe1bf8.png

jvisualvm能干什么

监控内存泄漏,跟踪垃圾回收,执行时内存,cpu分析,线程分析等。

线程的状态

运行:正在运行的;

休眠:sleep

等待:wait

驻留:线程池里边的空闲线程

监视:阻塞的线程,正在等待锁

 监控所有docker容器的cpu使用率 docker stats

由上图可以看出,nginx比较浪费cpu;

JMeter模拟分析并发请求

 c228219105fd0b42e4e71fb3db4a112f.png

中间件越多,性能损耗越大,大多都损失在中间件之间的网络交互了。

  1. 先让中间件本身的吞吐量进行提高

  2. 中间件之间的传输效率进行提高(网线,网卡,传输协议)

业务:

db:MYSQL优化

模板的渲染速度(thymeleaf的缓存开启,CPU,内存)

Nginx的动静分离

8346d53bd972a7adfd65db367208bdc1.png

总结下提高性能的方法:

  1. 开启thymeleaf的缓存(开发时要关闭,运行时要开启)

  2. 关闭服务器日志(不建议用)

  3. nginx进行动静分离

  4. 数据库加索引

  5. 减少数据库交互(把数据全部请求过来再用java进行处理)【优化业务】

  6. 提高内存,jvm的新生代调大等

  7. 加缓存

下一篇:

引入redis缓存出现的问题以及解决方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值