性能测试和性能优化以及操作系统概述(训练营第七课)
性能测试
性能根据视角的不同,标准不一样,体验也不一样
主观视觉
用户感受到的性能
客观视觉
性能指标衡量的性能
同样的客观网站性能,网站处理方式不同,客户体验的性能也是不相同的。
同样一个请求是 1s;一个提前渲染一部分,另一个等全部加载完成;用户体验到的性能是不一样的
一个转账需要 5s;一个提供倒计时并提示正在进行中状态,另一个直接空白页最后再提示成功信息;用户体验也是完全不一样的
网站性能指标
响应时间
从发出第一个请求数据到收到最后一个响应数据
并发数- 并发用户数
系统能够同时处理(同一个时刻)请求的数目 -系统的负载特性
吞吐量 (TPS, QPS, HPS)
单位时间内处理的请求数量 - 系统的处理能力
请求数/秒, 处理业务熟/小时,TPS 每秒事务数,QPS 每秒查询数,HPS 每秒 HTTP 请求数
吞吐量= (1000 / 平均响应时间 ms) * 并发数
性能计数器
服务器或操作系统性能的一些数据指标: System load、对象与进程线程数、CPU、内存、网络、磁盘 I/O
性能测试方法
性能测试
设计预期压力范围的系统负载测试
负载测试
测试系统的最大负载或临界值,直到系统达到最大处理能力
压力测试
超过最大负载后,继续增加负载直到系统崩溃,得到系统的压力承受情况
稳定性测试
特定软硬件配置,一定的业务压力、系统运行一段较长时间,监测系统是否稳定
模拟实际生产环境的业务情况,使得测试结果更加有用
![](https://static001.geekbang.org/infoq/9a/9a79a1390f25aa1008f36014f48a5347.png)
性能优化 (分布式系统 7 层优化思想)
性能优化的 2 个基本原则
你不能优化一个没有测试的软件
你不能优化一个你不了解的软件
性能优化的一般方法
性能测试,获得性能指标
指标分析,发现瓶颈点
架构与代码分析,寻找瓶颈关键所在
架构与代码优化,优化关键技术点
性能测试,进入性能优化闭环
系统性能优化的分层实现
机房与骨干网络性能优化
异地多活
专线网络与自主 CDN
服务器与硬件性能优化
CPU,磁盘、内存、网卡
操作系统性能优化
虚拟机性能优化
基础组件性能优化
不同的 3rd Lib
不同版本的 3rd Lib
软件架构性能优化(三板斧)
缓存 - 优化读操作
异步(消息队列) - 优化写操作
集群 - 让多台服务器看起来像一台服务器一样向使用者提供服务
软件代码性能优化
设计原则与设计模式
并发编程 - 多线程与锁
资源复用 - 线程池与对象池
异步编程
数据结构
操作系统
程序和进程
程序是静态的,是磁盘上的一个或多个文件
进程是动态地,一般包括
可执行代码
堆内存空间
栈内存空间
进程数据结构
进程运行
进程分时执行 - 多任务
进程主要的 3 个状态: 运行 - 就绪 - 阻塞
线程
轻量级进程 - 共享进程的内存地址控件
每个线程拥有自己私有的地址空间和堆栈数据
线程通过 控制进出栈 来执行方法调用
Tomcat 多线程运行时
![](https://static001.geekbang.org/infoq/38/388c8ae2c8fc40af31d5e5fc9d6fe82a.png)
临界区
多个线程访问共享资源的代码段 (需要加锁来解决并发问题)
阻塞 + 高并发-> 系统崩溃
限流
降级 - 关闭部分功能
异步I/O 或 无临界区(Actor 模型)
文件与硬盘 IO
B+ 树 - 文件组织和查找
![](https://static001.geekbang.org/infoq/0f/0faec4c28a2ffb707b5fb488b4ef843a.png)
LSM 树 - 适用只追加 不修改 文件(HDFS)
![](https://static001.geekbang.org/infoq/b4/b4d297c5565e250a1f46e632d2c65dd5.png)
RAID - 常用 RAID 10,RAID5, RAID6
![](https://static001.geekbang.org/infoq/5f/5f4eaea829d68a83e1150193ae473ebe.png)
HDFS 分布式文件系统
NameNode + DataNode
文件大小无限制
文件默认自动保存为 3 个副本,且支持 机架感知
同机架 2 个副本 + 异机架 1 个副本
![](https://static001.geekbang.org/infoq/0a/0aff321a4031864febf460d3944cd2fd.png)
Java 并发和锁
CAS -CAS(V, E, N)
系统原语 - 系统(通过硬件层面)来确保 数据更新是原子的;不需要加锁
V 是待更新变量;E 表示预期值;N 表示新值
If V == E; then V = N; else skip;
自选锁、偏向锁、轻量级锁、重量级锁
Java 通过 锁膨胀升级 来实现 加锁,减少重量级锁带来的效率影响
无锁 -> 偏向锁 -> 轻量级锁(+自选锁) ->重量级锁
通过 CAS 改变 锁对象 MarkWord 来实现锁升级
![](https://static001.geekbang.org/infoq/08/084ee3b99ff52a8c03d34cf3ff33f571.png)
![](https://static001.geekbang.org/infoq/90/906e15d6981969a47ba912ebe00a39c1.png)
默认锁对象是 无锁 状态,此时 锁标志位 -> 001
第一个线程 synchronized (lock) 时,会升级 锁对象为 偏向锁,设置标志位 -> 101
当另一个线程来竞争 通过一个锁 lock 时,该锁对象就会升级为 轻量级锁,设置标志位为 -> 00;然后未抢到锁的线程会通过 自旋 的方式尝试获取该 轻量级锁,不会阻塞(称:自旋锁,其实不是锁)
当 自旋 达到一定次数仍然未能获得该 锁,则 锁对象会升级 锁为 重量级锁;其他所有正在自旋等待锁 的线程都进入等待队列并阻塞,性能降低。
多 CPU 情况下的锁
锁总线机制 -> 一个 CPU 独占内存,其他 CPU 被阻塞;效率低
缓存一致性协议 -> 阻止同时修改 同一个内存区域数据对应的 缓存;效率高
锁分类
乐观锁 和 悲观锁
公平锁和非公平锁
可重入锁
独享锁(互斥锁)、共享锁、读写锁
分段锁 - ConcurrentHashMap
评论