響應時間=網絡傳輸時間+服務器響應時間+網絡傳輸時間+前端渲染時間前端
TPS:是指每秒經過事務數,直接反應系統性能的指標,該值越大時,系統性能會比較好,固然每一個系統都會有它的上線java
每秒點擊數:每秒點擊數表明用戶每秒向WEB服務器提交的HTTP請求書。linux
吞吐量:單位時間內系統處理的請求數。web
資源利用率:cpu:系統CPU 用戶CPU數據庫
Load Average:指一段時間內cpu正在處理和等待cpu處理的任務,也就是cpu使用隊列的長度的統計信息apache
Memroy:短期內可用內存愈來愈少,不表明必定有內存泄露或溢出。centos
IO:與磁盤的交互,重點關注交互頻率,磁盤隊列長度。瀏覽器
併發測試:併發數=pv/pv Time * 頁面連接次數 * HTTP響應時間 * 因數 /web 服務器數量。tomcat
Tomcat 與 JVM優化服務器
<!--
tomcat/conf/server.xml
系統日誌:如今日誌分析是愈來愈重要的性能測試需求獲取手段,大型公司愈來愈多重視日誌分析,數據挖掘中,很重要的一點是對日誌進行分析,而後分析用戶使用行爲,經過日誌分析,能夠幫助性能測試人員快速獲取系統性能參數,如併發量,響應時間,業務分部狀況等,日誌分析也能用於測試人員進行性能預警和容量規劃工做,通常的WEB Server 有兩部分日誌:一是運行 中日誌,它主要紀錄的一些信息,尤爲是一些異常錯誤日誌信息;二是訪問日誌信息,他記錄訪問的時間、ip地址、訪問的資料等相關信息。爲了獲取系統性能測試的需求,能夠分析WEB Server的訪問日誌以瞭解更多真實負載和主要的業務場景,將下面的日誌打開,去掉註釋便可,其中directory試生產目錄,tomcat的安裝目錄catalina做爲當前目錄,pattern表示日誌生產的格式,common是tomcat提供的一個標準設置格式,期具體表達式%h %l %u %t %r %s %b
-->
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
-->
Tomcat的運行是基於JAVA的虛擬機。SUN的JVM動態庫有client和Server兩個版本,分別對桌面應用和服務器應用作了相應的優化,client版本加載速度比較快,server版本加載速度比較慢但運行起來比較快。
在命令行輸入java -version 能夠看到jvm目前配置的那個版本。若是要修改jvm的版本可更改默認java.exe調用的jvm.dll,這個由jvm.cfg決定。編輯%JAVA_HOME%jre/leb/i386/jvm.cfg文件,裏面第一行寫的是-client(默認就是client版本),把第二行的-server KNOWN放到第一行,重啓tomcat,命令java -version.
代表Tomcat修改使用Server版本的jvm,讀者可進行比對測試,對比一下client版本的JVM和Server版本性能差別,從而決定採用哪一個版本的JVM。
tomcat與內存泄露
tomcat默認內存可使用的內存爲128MB(不一樣的版本有所區別),在較大型的應用項目中,這點內存是不夠的,須要調大,不然很容易出現"out of memery"的問題。
在Linux下,修改配置文件{tomcat_home}/bin/catalina.sh , 增長以下設置。
JAVA_OPTS='-Xms【初始化內存大小】 -Xmx【可使用內存大小】'
須要根據服務器可用的內存把這
另外,對於SUN的JVM,MaxpermSize 參數的調整比較重要。PermSize的大小決定了保持對象(類、方法)的大小,若是碰到"OutOfMemoryError:PermGen"的錯誤提示,應該考慮到調整這個參數的大小,SUM JVM默認保留64MB做爲PermSize大小
maxThreads:連接線程數監控與調整
能夠經過修改Tomcat安裝目錄的conf文件夾中的配置文件server.xml文件來調整tomcat最大連接線程數。maxThreads是最大併發線程數,若是同時的併發請求量超過這個值,tomcat也不會再增長線程,這是併發請求進入隊列,增長maxThreads的值能夠加大tomcat的併發處理能力,可是設置太高的maxThreads值也會對性能帶來影響,佔用過多的系統資源,甚至形成tomcat崩潰。
當maxThreads設置比較小時,tomcat處理請求的速度有所降低,同時也須要設置最大併發請求數
**通常web服務器容許的最大連接數還受限制於操做系統內核參數設置,一般linux是1000個左右,在centos中能夠用一下命令查看Socket最大鏈接數: ulimit -a
其中的open files是容許打開的最大文件數,centos默認是1024
修改vi /etc/security/limits.conf 配置文件 ,將文件數設置爲32768,在配置文件中添加:
* soft nofile 32768
* hard nofile 32768
重啓系統
acceptCount:最大排隊的設置
acceptCount是指當全部線程都已經被用於處理請求時,容許多少新的鏈接請求進入排隊隊列等候處理,當隊列滿時,任何新的請求都將被拒絕,默認設置爲1000
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
acceptCount="2000"
maxThreads="800"
redirectPort="8443" URIEncoding="UTF-8"/>
應用代碼性能診斷分析
一、內存泄露診斷分析
程序代碼中,與內存有關的問題能夠分爲兩大類:內存訪問錯誤和內存使用錯誤
內存訪問錯誤包含讀內存錯誤和寫內存錯誤,讀內存錯誤可能讓程序模塊返回意想不到的結果,從而致使後續的程序模塊運行異常。
內存使用錯誤主要指程序模塊申請的內存沒有正確釋放,系統可用內存逐漸減小,是程序運行逐漸減慢,直至中止。
二、代碼書寫問題致使內存泄露
通常咱們常說內存泄露指的是堆內存的泄露,堆內存是指程序從堆中分配的,大小任意的(內存塊的大小能夠再程序運行期決定)使用完後必須顯示釋放的內存。
通常使用:malloc , calloc ,realloc , new ,等函數從堆中分配到一塊內存,使用完後,城西南 必須負責相應的調用free和delete釋放內存塊,不然,這塊內存就不能被內存再次使用,咱們就說這塊內存泄露了。
形成內存泄露的緣由不少,最多見的有如下幾種。
分配完內存忘記回收,
程序寫法有問題,形成沒有辦法回收
某些API函數的使用不正確,形成內存泄露
沒有及時釋放
JVM內存泄露診斷分析--JVM原理與監控
PermGen是JVM自用的區域,是內存的永久保護區,用於存放反射代理和Class,在Class被裝載時會被放到PermGen中
JVM啓動參數介紹
JVM啓動時容許加載指定的參數,若是參數指定不恰當,可能會對JVM性能形成較大的影響
Xmn:Eden Generation的Heap大小,通常設置爲Xmx的1/3 或 1/4
Xmx:設置JVM Heap大小最大值,這裏的heap= NEW Generation+Old Generation,但不包括PermGen。
Xms:設置JVM Heap大小初始值
XX:NewRatio :New/Old 的大小比率
XX:NewSize : New Generation Heap的大小
XX:MaxNewSize :能夠經過NewRatio 和 -Xmx計算獲得
XX:SurvivorRatio : Eden/Survivor Space大小比率
XX:PermSize : PermGen的初始值
XX:MaxpermSize: PermGen最大值
Xss:設置每一個線程的Stack大小
XX:+UseParNewGc:表示多CPU下縮短Minor Gc的時間
XX:+UseParallelGc :設置後可使用並行清除收集器(多CPU)
XX:+ParallelGcThreads:可用來增長並行度(多CPU)
XX:+AggressiveOpts :是否容許激活最近的實驗性性能調整
XX:-Xnoclassgc:是否容許類垃圾收集,默認設置時容許類GC
Servlet 常見性能問題分析與優化
Servlet是J2EE架構中重要的組成部分,Servlet能夠生成動態的WEB頁面,它是客戶端請求(web瀏覽器或其餘HTTP客戶端程序)與服務器響應(HTTP服務器上的數據庫或應用程序)的中間層
Servlet壓縮輸出
http壓縮能夠大大提升瀏覽器的速度,它的原理是:在客戶端請求網頁後,從服務器端將網頁文件壓縮,再下載到客戶端,由客戶端的瀏覽器負載壓縮後在解析呈現,HTTP壓縮大概能夠節省40%左右的流量。
public void doGet(HttpServletRequest request ,HttpServletResponse response) throws IOException , ServletException{
String c = request.getParameter("c");
if("c".equals(c)){
response.setHeader("Content-Encoding","gzip");
compressionResponse cResponse = new CompressionResponse(response);
response.setContentTyPe("text/plain");
final OutputStream out = cResponse.getOutputStream();
for(int i=0;i<1000;i++){
out.write(UUID.randomUUID().toString().getBytes());
out.flush();
}
out.close();
}
else{
response.setContentTyPe("text/plain");
PrintWriter out = response.getWrite();
for(int i=0;i<1000;i++){
out.print(UUID.randomUUID().toString().getBytes());
out.flush();
}
out.close();
}
}