性能测试总结
性能优化
性能测试
概念
性能优化的前提和基础
也是性能优化结果的检查和度量标准
不同视角不同手段
主观视角
客观视角
指标衡量
吞吐量
- TPS
- qps
- 体现系统处理能力
响应时间
- 反映了系统的快慢
并发数
- 反映了系统的负载
性能计数器
- 服务器或者操作系统性能的一些数据指标
- systeLoad
- 对象与线程数
- 内存使用
- cpu
- IO
性能测试方法
性能测试
- 以系统设计初期规划的性能指标为预期目标,对系统不断施家压力,验证系统在资源可接受范围内,是否达到性能预期
负载测试
- 对系统不断的增加并发请求以增加系统压力,直到系统的某项或多项性能指标达到安全临街值,如某项资源已经呈现饱和状态,这时候继续对系统施加压力,系统的处理能力不但不能提高反而会下降
压力测试
- 在超过负载的情况下,继续施加压力,直到系统崩溃或不能在处理任何请求,已获得最大压力承受能力
稳定性测试
- 被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,是系统运行一段较长时间,以此检测系统是否稳定
全链路压测
1、概述
(1)、定义
居于线上真实环境和实际业务场景,通过模拟海量的用户请求,对整个系统进行压力测试
(2)、目的
a、验证新上线功能的稳定性
b、验证峰值流量下服务的稳定性和伸缩性
c、对线上服务进行更准确的容量评估
d、找到系统的瓶颈并针对性优化
2、工具与标准
(1)、工具
a、JMeter
支持分布式压测
b、TCPCopy
流量复制工具,配合Tcpdump录制请求,然后使用TCOCopy回放
c、Apache abhttp
(2)、局限标准
a、机器 负载 不超过cpu核数*0.6
b、服务进程cpu占用不超过(cpu核数*0.6 /机器部署的服务进程数
c、网卡流量不超过网卡容量的60%(超过可能延时较大
d、请求超时不超过十万分之一
e、qps不低于预估的85%,否则需要优化,或者给出合理解释
3、条件
(1)、模拟真实环境,压测环境与生产环境同等,同时压测一个机器上的所有服务
(2)、压测数据尽可能使用线上真实数据
4、压测方案
(1)、复用线上环境压测
a、低峰期压测
b、回放只读请求
c、写请求无法压测(数据污染问题)
(2)、构造全套线上环境
a、消息/短信/Push隔离,防止用户骚扰
b、成本高
(3)、基于真实流量调配进行线上压测(推荐)
a、完全使用线上环境和数据
b、把线上请求逐步分配到某一台服务器直到服务处理到极限
c、服务需要 实时调整流量分配能力(服务治理平台)
d、服务运行信息从监控系统准实时获取(立体监控系统)
e、只能达到最大的线上流量,对应流量小的服务不能测试出真实处理能力
注:方案一、二、三都是局部压测,有可能不能暴露基础服务问题
(4)、全链路压测方案
a、数据尽可能真实
b、线上真实环境
c、核心技术
压测标识透传
压测服务隔离
压测数据隔离
注:全链路压测时准确评估整个系统性能水平的必经之路
4、全链路核心技术
(1)、压测标识透传
a、跨线程的透传
ThreadLocal对象 辅助
b、跨进程(服务)的透传
存储在定长header,添加压测标识
(2)、压测服务隔离
a、深夜低峰测试
b、分离 空闲机器 ,分配压测分组
c、将正常流量和测试流量进行物理隔离,降低压测对服务集群带来的影响
(3)、压测数据隔离
a、影子表
使用线上同一个数据库,共享数据库的内存资源。更接近真实环境,写请求进入影子表
b、KV存储
影子存储
c、MQ
生产端带上测试标识,消费端忽略
两个基本原则
不能优化一个没有测试的软件
不能优化一个不了解的软件
一般方法
性能测试:获得性能指标
指标分析,发现性能与资源瓶颈
架构与代码分析,寻找性能与瓶颈管家所在
架构与代码优化,优化关键技术点,平衡资源利用
性能测试,进入优化闭环
分层思想
机房与骨干网网络
异地多活的多机房架构
专线网络与自主CDN建设
服务器与硬件性能优化
更好的cpu、磁盘、内存、网卡,其优化是数量级的
操作统西能优化
虚拟机性能优化
基础组件的性能优化
软件架构性能优化
缓存
- 优化读
异步
- 优化写
集群
软件代码性能优化
并发编程,多线程锁
资源复用,线程池与对象池
异步编程,生产者消费者
数据结构,数组、链表、hash表,树
操作系统
程序运行时架构
运行: 当一个进程在CPU上运行时,则称该进程处于运行状态。处于运行状态的进程的数目小于等于CPU的数目。
就绪: 当一个进程获得了除CPU以外的一切所需资源,只要得到CPU即可运行,则称此进程处于就绪状态,就绪状态有时候也被称为等待运行状态。
阻塞: 也成为等待或者睡眠状态,当一个进程正在等待某一件事情发生(例如等待I/O完成,等待锁)而暂时停止运行,这时即使把CPU分配给进程也无法执行,故称该进程处于阻塞状态。
线程
是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
2.1 线程栈
线程栈存储的信息是指某时刻线程中方法调度的信息,当前调用的方法总是位于栈顶。当某个方法被调用时,此方法的相关信息压入栈顶。
2.2 线程安全
当代码修改进行共享内存里的数据时,如果有多个线程同时在执行时,就可能会出现同时修改的情况,但是这个数据最终只会被修改一次。这个就是人们常说的线程安全问题。
2.3 临界区
多个线程访问共享资源的这段代码被称为临界区,解决线程安全问题的主要方法是使用锁,将临界区的代码加锁,只有获得锁的线程才能执行临界区的代码。
2.4 阻塞导致高并发系统的奔溃
锁会引起线程阻塞,阻塞导致线程既不能继续执行,也不能释放资源。进而导致资源耗尽。最终导致系统奔溃。
2.5 避免阻塞引起的奔溃
限流: 控制进入计算机的请求数,进而减少创建的线程数。
降级: 关闭部分程序的功能,尽早释放程序。
避免阻塞: 异步I/O; 无临界区。
锁
锁原语CAS
CAS(V,E,N)
是一种系统原语,执行是原子的
偏向锁、轻量级锁、重量级锁
这时synchronized锁升级过程
当一个线程拿到对象锁之后,会将threadid写入对象头;线程拿锁时先判断给threadid是不是自己,是直接进入临界区,这部分成为偏向锁,可以理解为重入;不是的则进行自旋,自旋一定时间,并进入自旋+CAS,此为轻量级锁;达到一定阈值则升级为重量级锁,即利用Monitor进行排队。
多CPU下的锁
工作内存、主内存
缓存一致性协议或者总线锁机制
总线锁与缓存所
使用处理器LOCK#信号,当一个处理器在内存总线上输出此信号的时候,其他处理器的请求将被阻塞,该处理器独占内存
缓存所:是指内存区域如果被缓存在处理器的缓存行中,并且在lock操作期间被锁定,那么当他执行锁操作会写到内存时,处理器不再总线上声言LOCK信号,而是修改内部的内存地址,并允许他的缓存一致机制来保证操作的原子性。因为缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据,当其他处理器会写已被锁定的缓存行数据是,会是缓存行无效
公平锁非公平
以ReentrantLock
公平锁是在获取锁之前会先判断等待队列是否为空或者自己是否位于队列头部,该条件通过才能继续获取锁
非公平锁先获取锁,失败后生成一个Node,在放入等待队列前,判断是否满足获取锁条件,满足则再次获取锁,失败才会进入等待队列。有两次取锁的机会,效率更高
可重入锁
独享、互斥、共享、读写
乐观锁、悲观锁
分段锁
LongAdder 可以扩容;高并发时将对单一变量的CAS操作分散为对数组
cells
中多个元素的CAS操作,取值时进行求和;而在并发较低时仅对base
变量进行CAS操作ConcurrentHashMap 1.7. 继承ReentrantLock,默认16个
自旋锁
actor
文件和IO
机械硬盘
固态硬盘
B+树
LSM树
文件控制块
- 文件系统将硬盘空间以块的单位进行划分,每个文件占若干块,然后在通过一个文件控制块FCB记录每个块占据的硬盘数据块
Linux iNode文件控制块
- iNode记录文件权限、所有者、修改时间和文件大小等文件属性信息以及文件数据块硬盘地址索引
- inode是固定结构的,能记录的硬盘地址索引数也是固定的,只有15个
- 每个inode最多可存储12+256+2568256 * 256~3次方个数据块。如果每个块4k,则单个文件最大不超过70G
RAID独立硬盘冗余阵列
分布式文件系统
评论