淘先锋技术网

首页 1 2 3 4 5 6 7

一、线程数量 如何确定?

  1. 通过基准测试获取基准响应时间:
    15ms

  2. 单线程产生的并发量(理论上是tps) = 1000ms/响应时间(ms):
    1000/15🟰66

  3. 线程数量 = 目标并发量 / 单线程产生并发量:
    800 / 66= 12
    目标并发量上浮取15个线程

  4. 实际性能测试过程中 - 线程数往往是过载:
    20个

  5. 还有一种算法
    能接受的最大响应时间 去代入上面的公式:
    1000 / 200 = 5
    800 / 5 = 160个线程

二、如何定义所谓的瓶颈

  • 程序性能指标不达标

    • 吞吐量

    • 响应时间

    • 错误率

    • 资源占用率

三、网络瓶颈分析与调优方向

3.1 检查网络速度 - iperf3

工具 iperf3 测试两个服务器 之间的 带宽速度 测速

3.2 由吞吐量计算网络带宽

计算 -- 520/s 吞吐量 占用多大网络带宽(吞吐量 * 响应大小 * 8bit)

  • 传输内容大小(响应头+响应体)

    • 单词响应内容大小0.33KB

    • http头大小普遍1KB左右,有些响应头还会更大

    • 每次传输响应数据在,1.3KB左右

  • 实测过程中占用网络带宽

    • 520*1.3 = 网络每秒传输676KB

    • 占用带宽 = 676KB * 8 = 5408kbps 约等于5Mbps左右

  • 检查网络带宽

    • 应用服务器带宽 -- 只有 5M兆

    • 推测 -- 性能瓶颈的原因在这

    • 验证 -- 提高性能测试环境的带宽

3.3 网络监控 - iftop

iftop (全称应该是 interface top) 是查看网络实时流量的工具,可以监控各个应用程序的流量

常用命令:iftop -i enp0s8 -n 

3.4 优化建议

 

硬件:升级机器,

软件:优化程序

  • 压缩数据传输的大小

    • 压缩源数据

    • 服务器层面 gzip压缩传输

    • 减少不必要数据传输

四、磁盘瓶颈分析与调优方向

4.1 程序使用场景

  • 日志文件

  • 附件上传存储

  • 数据库系统 - 表数据读写

  • 程序本身的代码,配置文件 都是在磁盘存放起来,需要加载到内存

4.2 磁盘监控 iotop

iotop -- only 查看某进程磁盘读写情况

a1cf814370dd81ae49f01f1bba8ce003.jpeg

 3.3 优化建议

WEB网站 -- 每一张图片 很大

  • 同时也会占用大量的 网络带宽

  • 占用大量的磁盘 I/O

日志 -- 控制详细程度

  • 不同的日志级别

    • 生产 warn/error

    • 开发 info/debug

  • 磁盘空间是有限的, 监控 磁盘空间的占用增长情况

  • 目前的系统里边 - 主要 还是 数据库系统 用磁盘比较多

五、CPU瓶颈分析与调优方向

5.1 top查看CPU运行情况

5.2 性能测试过程:

负载测试下:

  • 如果吞吐量达到了瓶颈,而CPU资源占用不高,当你增加了并发量,而CPU并没有随之变高:就要考虑程序代码或者操作系统配置问题,例如:涉及Jvm 程序 多线程机制

 性能测试过程中,CPU占用已经很高

六、JAVA程序调优实战分析

6.1 JVM 核心知识:

程序计数器(线程私有,记录线程上次执行到哪里,下一步执行什么):下一条需要执行的字节码指令:分支、跳转、循环、异常处理、线程恢复等基础操作都会依赖计数器来完成。每个线程都有独立的程序计数器,用来在线程切换后能恢复到正确的执行位置,各条线程之间的计数器互不影响,独立存储。

栈(线程私有):后进先出,记录当前正在执行的方法

方法区/元数据区(线程共有):存储已被虚拟机加载的类信息、常量、静态变量、JIT(just in time,即时编译技术)编译后的代码等数据

堆(线程共有):存储Java对象实例的内存区域

6.2 JVM 资源监控工具

jmap,jconsole,jvisualvm

JVM集群监控体系-测试过程/结果分析中看grafana(需要开发配合采集)

6.3 优化建议

1. 性能测试过程 - 服务器内存资源够用,但是程序性能达到了瓶颈

可疑原因:内存配置太小,没有榨干服务器内存资源。或者是测试场景中的并发量不够(要监控 测试过程中,JVM自身的内存是否被用完,如果没用完,就加大并发量)

通过查看 JVM的 内存配置 ,是否用到了 机器的大部分内存

验证:

  • 1. 加大并发 -- 排查性能测试并发不够的问题

  • 2. 加大内存 -- 在加大内存之后,性能是否有提升,-Xms(堆内存最小值)-Xmx(堆内存最大值)

2. 性能测试过程 - 服务器CPU资源够用,但是程序性能达到了瓶颈

可疑原因:程序配置的线程数太少,没有榨干服务器硬件资源。或者是测试场景中的并发量不够

请求处理的线程池大小线程参数调整

 

  • WEB服务 --- 处理请求时候,会用到线程池

    • 不限于Tomcat,jetty,netty,weblogic,包括其他语言 也有类似的机制

  • 比如tomcat的3个参数:acceptCount、maxConnections、maxThreads

    • accept队列的长度;当accept队列中连接的个数达到acceptCount时,队列满,进来的请求一律被拒绝。默认值是100

    • Tomcat在任意时刻接收和处理的最大连接数。当Tomcat接收的连接数达到maxConnections时,Acceptor线程不会读取accept队列中的连接;这时accept队列中的线程会一直阻塞着,直到Tomcat接收的连接数小于maxConnections。如果设置为-1,则连接数不受限制。

    • 请求处理线程的最大数量。默认值是200

3. 并发量少,但是CPU资源占用量大

可疑原因:少量线程占用了大量的系统资源例如: 1. 单线程占用CPU 100% (死循环、数据太多循环N多次处理)2. 1个请求会导致大量的线程被创建 (开发人员写业务逻辑代码也用到多线程)

排查方式:

  1. top+jstack寻找最耗CPU的进程和线程
  2. 基于arthas阿里提供的,dashboard 整体仪表盘,thread -n 5 展示最忙的前5个线程

七、JAVA程序GC机制及性能稳定性调优分析

format,png

 

1. 分代

  • 新生代 - ede,(8:1:1)

    • 新生代-survivor 1

    • 新生代-survivor 2

  • 老年代(新:老= 1:2)

    • 老年代 - 超级大的对象 和 经历多次新生代GC依然存在的对象。

  • 特殊 - 永久代【元数据空间】

2. STW概念(stop the world)

  • 和性能有关,GC时程序停止

  • 一个请求 -- 处理时间业务代码 执行时间 + GC垃圾回收时间

3.GC

  • minor gc 小范围GC

    • 新生代

    • 时间一般比较短

  • full gc 大范围GC

    • 所有的堆空间、元数据空间

    • 导致 程序中断的时间比较长

7.1 StackOverflowError-栈内存溢出

可疑原因:递归调用

方法:尝试修改配置增加JVM每个线程栈内存的大小

7.2 实战:OutOfMemoryError

可疑原因:持久性压力测试,程序内存占用逐步增高,最终挂掉突然大量并发,内存不够用

  • java.lang.OutOfMemoryError: unable to create new native thread

    • Java应用程序已经达到了它可以启动的线程数的限制

  • java.lang.OutOfMemoryError: Metaspace1.8+ java.lang.OutOfMemoryError: PermGen space

    • -XX:MaxPermSize=512m

    • 加大元数据空间的内存,或者检查元数据空间占用是否合理

    • class 类加载的太多,动态创建了很多class类

  • java.lang.OutOfMemoryError: Java heap spacejava.lang.OutOfMemoryError:GC overhead limit exceeded

    • 加大堆内存,或者检查内存占用是否合理

    • 程序调优 - 获取内存快照 - 找到内存占用比较大的对象,让开发去修改

7.3 性能测试中,吞吐量呈现出波浪状。性能稳定性调优

可疑原因: JVM 垃圾回收 导致STW,产生时间停顿

调整GC参数

八、Mysql数据库性能测试及瓶颈分析调优思路

8.1 Mysql 独立的监控指标

        grafana + prometheus + mysql

8.2 数据库调优思路汇总

瓶颈:

  • 资源不够用CPU,网络资源,磁盘资源,内存

  • 响应时间  - 慢查询日志

  • 数据库连接池线程数量

  • 查询-调优分析:

    • 使用索引

    • 减少表关联join

    • 搜索场景严禁左模糊或者全模糊

    • 大量更新可以用批处理,及时关闭事务,非必要不要主动锁数据

九、Nginx负载均衡集群架构性能测试及瓶颈分析调优思路

Nginx 性能监控

        grafana + prometheus + nginx

可疑原因:

  • Nginx 瓶颈分析

    • 资源占用:磁盘网络内存CPU

    • 请求是否堆积:write,wait,read,active

Nginx 调优方向:

  • Nginx运行工作进程数量
  • Nginx运行CPU绑定
  • 三种方式:轮询,权重,ip_hash

十、Redis高并发缓存架构性能测试及瓶颈分析调优思路

10.1 Redis 监控体系

        grafana + prometheus + redis

10.2 Redis 调优建议

缓存预热,缓存击穿,缓存雪崩

Redis本身的性能足够逆天,大部分的问题在于 开发人员没有用好Redis

十一、MQ高并发异步消息架构性能测试及瓶颈分析调优思路

activemq,rabbitmq,kafka

监控体系:官方

不同的消息模式:

  • sync同步模式

    • 发送消息采用同步模式,这种方式只有在消息完全发送完成之后才返回结果,此方式存在需要同步等待发送结果的时间代价

    • 具有内部重试机制

  • async异步模式

    • 发送消息采用异步发送模式,消息发送后立刻返回,当消息完全完成发送后,会调用回调函数sendCallback来告知发送者本次发送是成功或者失败。异步模式通常用于响应时间敏感业务场景,即承受不了同步发送消息时等待返回的耗时代价

    • 同步发送一样,异步模式也在内部实现了重试机制,默认次数为2

    • 测试的时候:要注意, 如果发送完毕之后,程序就挂掉了, 那么对于数据处理是否存在问题

      • 程序在收到 MQ 处理失败的callback回调消息之后,要进行相对应重试设计

  • one-way生产者单向发送

    • 采用one-way发送模式发送消息的时候,发送端发送完消息后会立即返回,不会等待来自broker的ack来告知本次消息发送是否完全完成发送。这种方式吞吐量很大,但是存在消息丢失的风险,所以其适用于不重要的消息发送,比如日志收集

    • MQ 出问题的情况还是比较少的