第七周总结
本周以及接下来的两周的主题是性能优化,关于性能优化有两句话“任何脱离场景的优化都是耍流氓”和“过早优化是万恶之源”值得借鉴。
性能测试
性能测试是性能优化的前提和基础,同时也是性能优化的度量和指标。常用的性能指标:
响应时间
客户端(用户)从发出请求到接收到响应的时间间隔。
并发数
系统能够同时处理的并发请求数,其与系统的在线用户数以及系统用户数的区别。
吞吐量
吞吐量即单位时间内系统处理的请求数量,如 TPS、QPS、HPS 等。
性能计数器
指服务器的各项数据指标,如 CPU、内存、磁盘、网络等。
性能测试通常分为负载测试、压力测试、稳定性测试。一般压力压测居多,主要得到并发数和响应时间以及并发数和吞吐量之间关系图。最终得出系统的性能瓶颈点。
全链路压测
全链路压测是指在特定情况,将系统全部请求链路串联起来进行压力测试,尽可能的模拟用户的真实行为,探测出系统的整体处理能力,便于后续容量规划以及性能优化。其主要面临三大挑战:
压测数据构造
压测结果确保对真实环境无影响
压测流量模拟
性能优化
性能优化有两个原则;一为不能优化一个没有测试的软件系统,二为不能优化一个不熟悉的软件系统。
性能优化的方法为:性能测试 ==> 指标分析 ==> 架构以及代码分析 ==> 架构与代码以及其他优化 ==> 性能测试。
性能优化分层思想:
机房与骨干网络性能优化
服务器以及硬件性能优化
操作系统层面优化
JVM 层面性能优化
中间件层面性能优化
框架设计性能优化
软件代码性能优化
操作系统
运行时:程序是静态的,但当程序通过入口启动后,其就进入运行态,被称为进程。
1、进程 vs 线程
进程是操作系统层面的,进程启动后,操作系统为其分配内存等服务器资源。线程是 CPU 调度最小的单位,其共享进程的内存资源;一个进程内部有多个线程,它们各自竞争 CPU 等资源执行任务。
2、线程安全 & 临界区 & 阻塞
线程安全:由于进程内部多个线程共享内存堆,那么程序运行时会出现多个线程同时修改堆内存的数据,从而程序执行的结果与用户期待的结果不一致。
临界区:多个线程访问共同资源的代码片段。所以为了防止多个线程同时修改临界区资源,需要对访问临界区的代码加锁,确保其同一时刻只会有一个线程访问,该并发为串行。
阻塞:对临界区代码加锁会起来线程阻塞。如果系统出现大量线程阻塞,会导致线程既不能继续执行,又不能释放资源,进而导致系统资源耗尽而奔溃。
锁
1、锁原语
CAS(V, E, N) 其中 V 待更新变量值,E 是期望值,N 是修改后的新值;CAS 是系统层面的原语,会确保其操作的原子性。
2、对象锁
JAVA 是面向对象编程语言,其概念里万物皆对象。对象由对象头、对象体、对其字节构成,对象头有一个 64 位的区域存储对象加锁的情况(Mark Word)。
由此可见对象锁的层级:无锁 ==> 偏向锁 ==> 轻量级锁(CAS) ==> 重量级锁
3、多 CPU 锁原语
总线锁:某个处理器发出 LOCK# 信号独占内存,此信号会将其他处理器请求阻塞。
缓存锁:类似 CAS,每次对比缓存行与主内存的数据,基于缓存一致性来判断缓存行的有效性。
4、公平锁 vs 非公平锁
5、可重入锁
6、互斥锁 & 共享锁 & 读写锁
7、悲观锁 & 乐观锁
8、分段锁
9、自旋锁
版权声明: 本文为 InfoQ 作者【睁眼看世界】的原创文章。
原文链接:【http://xie.infoq.cn/article/c926b3352c718b0208c4e0085】。文章转载请联系作者。
评论