性能调优:思路与方向

一、为什么要进行性能调优?
性能优化就是发挥机器本来的性能。
(说白了就是不要浪费钱,就是用最少的钱,希望满足一个很大批用户量,也就是物美价廉)
衡量的基本术语:
1)QPS:Query Per Second (一秒内可以处理的请求数量称之为服务器的QPS )
2)TPS:每秒钟处理完的事务次数,也就是一个应用系统1S能完成多少事务处 理,一个事务在分布式处理中,可能对应多个请求

      举例:比如  对于一个页面的一次访问,形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入“QPS”之中。访问一个页面会请求服务器3次,对用户来说产生一个T,产生了3个Q
      总结:QPS基本类似于TPS,对于衡量单个接口服务的处理能力,用QPS比较多

二、如何发现性能问题?
1、硬件层面
1)内存占用高
2)CPU占用高
3)网络是否发生拥堵了(带宽)
4)硬盘空间满
5)IO占用高
–从硬盘上读取到本机内存中
–从网络上接收信息到本机内存中
–从本机内存写出到硬盘或者网络
(内存:物理内存和虚拟内存,虚拟内存就是把计算的内存空间扩展到硬盘,如RAM和SWAP之间的交换增加了系统的负担)
2、软件层面
主要是通过查看日志文件(各类组件的日志文件)
nginx日志文件:access.log error.log
tomcat日志文件:

(win)catalina.log (linux)catalina.out:在里面可以看到启动的JVM参数以及操作系统等日志信息。
localhost_access_log.txt : 存放访问tomcat的请求的所有地址以及请求的路径、时间,请求协议以及返回码等信息
tomcat7-stderr.log: 这个是log4j的错误日志
tomcat7-stdout.log: 这个是程序中的system语句打印的日志(包含系统抛出的异常) 注意:系统中不能使用System.out
打印进行调试(debug),这些最后都会保存到日志文件浪费磁盘空间,log4j则可以通过控制level来控制是否打印(trace<debug<info<warn<error<fatal)

Jetty日志文件
Web应用日志文件:自定义的日志文件、gc.log 、dump文件
其他日志文件:mysql慢查询日志、solr日志等等

通过日志可以大致发现如下问题:
1)内存溢出
Java.lang.OutOfMemoryError
JVM分配的内存过小或者程序不严密,产生过多的垃圾
2)内存泄漏,对象未释放
老年代使用率一致持续过高,即使发生了多次full gc也不能降下来
3)线程阻塞、死锁
Blocked and Deadlock
4)线程死循环
一直Runnable
5)网络IO连接超时时间过长
建立连接:java.net.SocketTimeoutException: connect timed out
读取阻塞超时:java.net.SocketTimeoutException: Read timed out
6)磁盘不可写

      分析两个问题:
      1)一个线程发生OOM,其他线程还能运行么?
      2)tomcat的假死现象
            内存溢出
            JVMGC时间过长,导致应用暂停
            load太高,已经超出服务的极限了
            应用程序出现死锁
            大量tcp连接close_wait
                netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
            tomcat线程数不够

三、从什么层面开始你的调优旅行?
1、硬件资源层面
纵向扩展:在单机的情况下,如果有钱可以升级下机器资源!
比如:
如果需要大量的图像计算,把CPU换成GPU
机械硬盘换成固态硬盘
等等
横向扩展:增加机器

2、软件层面

  • Linux系统

  • 各种用户进程限制
    ulimit -a 打印信息
    重点关注:open files
    修改命令:ulimit -n 4096,其默认值是1024
    其他修改方式:/etc/security/limits.conf 或者 /etc/profile source /etc/profile等
    (注意:系统级别的硬限制的查看命令 sysctl -a|grep file-max)

    例子: 由于solr中每次索引提交都会重新创建一个文件用于索引写入,如果你的索引提交频繁很频繁,那么你可能遇到“Too many open files”异常

  • socket最大的连接数
    client最大tcp连接数
    # sysctl -a | grep ipv4.ip_conntrack_max
    net.ipv4.ip_conntrack_max = 20000
    这表明系统将对最大跟踪的TCP连接数限制默认为20000。
    # sysctl -a | grep ipv4.ip_local_port_range
    net.ipv4.ip_local_port_range = 1024 30000

    server本地监听队列
    net.core.somaxconn = 65535 #定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数 (默认是128)
    net.ipv4.tcp_max_syn_backlog = 262144 #对于还未获得对方确认的连接请求,可保存在队列中的最大数目
    net.core.netdev_max_backlog = 30000 #在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目

    PS:最大的连接数也是受机器资源的限制,不可能无限大。还有每一个tcp连接
     都要占一个文件描述符,一旦这个文件描述符使用完了,
     新的连接到来返回给我们的错误是”Socket/File:Can't open so many files”。
    这时你需要明白操作系统对可以打开的最大文件数的限制。
    最后也是需要运营商带宽的支持!!!
    
  • tcp缓冲区大小 (读和写)
    例如:
    读缓冲区保存了远程主机发送过的数据,如果缓冲区已满,则数据会被放弃,写缓冲期保存了要发送到远程主机的数据,如果写缓冲区溢满,则系统的应用程序在写入数据时会阻塞

sysctl -w net.core.rmem max=l6777216
sysctl -w net.core .wmem max=l6777216
sysctl -w net.ipv4.tcp_rmem=“4096 87380 167772 16”
sysctl -w net.ipv4.tcp_wmem=“ 4096 16384 16777216 ”

  • tcp拥塞控制算法
    算法对TCP传输速率的影响很大。丢包使的TCP传输速度大幅下降的主要原因是丢包重传机制,控制这一机制的就是TCP拥塞控制算法。
    查看当前系统内核中可用的TCP拥塞控制算法有哪些:
      sysctl net.ipv4.tcp_available_congestion_control
    修改命令:sysctl -w net.ipv4.tcp_congestion_control = cubic

    到了这里,你是不是终于清楚为什么面试的时候,
    有人会问你了不了解TCP/IP 协议?

  • nginx

  • 不记录不需要的日志
    如:
    location ~ .*.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ {
    access_log off;
    }

  • nginx 缓存时间设置

  • worker_processes 8
    nginx进程数,建议按照cpu数目制定

  • worker_rlimit_nofile 65535
    这个指令时指当一个nginx进程打开的最多文件描述符数目,设置值为ulimit -n 与nginx进程数相除

  • worker_connections 65535
    每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections。
    等等。。。。。。。。。。。。。。。。。。

  • tomcat

  • JVM 参数设置
    (tomcat解压版)修改“%TOMCAT_HOME%\bin\catalina.bat”文件,在文件开头增加如下设置:(一定加在catalina.bat最前面)
    set JAVA_OPTS=-Xms512m -Xmx512m
    -XX:PermSize=128M -XX:MaxNewSize=256m
    -XX:MaxPermSize=512m

  • tomcat让其支持NIO
    修改前:
    protocol=“HTTP/1.1”
    connectionTimeout=“20000” redirectPort=“8443”/>
    修改成支持NIO的类型,配置如下 :
    protocol="org.apache.coyote.http11.Http11NioProtocol
    " connectionTimeout=“20000” redirectPort=“8443” />

  • 并发数设置
    maxThreads=“600” //最大线程数
    minSpareThreads=“100” //初始化时创建的线程数
    maxSpareThreads=“500” //一旦线程超过这个值,Tomcat会关闭不需要的socket线程
    acceptCount=“700”//指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
    connectionTimeout=“20000”
    redirectPort=“8443” />

  • maxConnections
    这个值表示最多可以有多少个socket连接到tomcat上。NIO模式下默认是10000.

  • 禁用DNS查询

  • 移除静态资源访问配置、移除defaultservlet、移除jspservlet 、移除session、 移除welcome-file-list、移除valve、移除accesslogvalve,可以通过nginx的access.log替代

2)下游软件(程序):如web应用、数据库(mysql\redis)、solr等

  • mysql
    缓存配置
  • solr
    JVM参数配置(堆外内存)、查询缓存大小配置
  • web应用
    JAVA代码优化:如IO资源使用完要关闭、sql查询使用索引、sql大数据排序时使用索引、调整业务逻辑等等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值