Mysql Tomcat C3p0 系統性能調優個人總結
系統資訊
應用邏輯 就是用c3p0 到資料庫查詢資料並http返回Json資料
1 調優前的最初的測試結果 JMeter test result
No. |
Type |
Original |
1000 data bigger |
1 |
500Connection |
250 query/S |
63q/S |
2 |
1000 connections |
255q/S |
57q/S 65 q/S |
這個資料是從程式的log 中打印出的 資料庫select語句 中得出的結果(正確與否後面會有討論)。
2 經過IOD系統列印 SQL query 的執行時間 和 tomcat 每個request 的 響應時間,找出 系統瓶頸 是因為一個 select語句 使用了 in:
SELECT* FROM infoobject_table where category = 'advertisement' and deleteflag=falseand (id in (select info_object_fk from timespan_table where vod_id = ? and deleteflag=false))Order By Rand() Limit
在 原來的小資料庫中 資料較少 查詢 時間 100ms 左右
在 1000個 video 的資料庫中 查詢的時間 達到 超過 1S
先註釋掉 這個語句 ,想辦法用優化的辦法實現這個功能。
註釋掉 這個 select 語句後得到的測試資料(還是計算從程式的log中打印出的 資料庫select語句)Jmeter testresult
No. |
Type |
Original |
1000 bigger |
1 |
500Connection |
250 query/S |
CPU 100% |
2 |
1000 connections |
255q/S |
160q/S 160q/S |
現在 的問題 是碰到 tomcat request 160q/S 再怎麼調優 增加不了了,tomcat的記憶體 配置了4G 實際使用了不到 1個G ,CPU 8核心 利用率 只有10%。
3 發現前面的統計系統響應 效能有問題,很多時候sql 語句打印出來了,但是並沒有執行完成, 因為c3p0 連線數只有15個,都在等待資料庫連線,後來改變統計方式。
還有就是打印出 c3p0 的連線池的工作狀態
private void printDataConnections() {
ComboPooledDataSource ds = (ComboPooledDataSource) DBConn.getDataSource();
StringBuffer connectionBuffer = new StringBuffer();
try {
connectionBuffer.append("getMaxPoolSize=" + ds.getMaxPoolSize());// 最大連線數
connectionBuffer.append("getMinPoolSize=" + ds.getMinPoolSize());// 最小連線數
connectionBuffer.append("getNumBusyConnections=" + ds.getNumBusyConnections());// // 正在使用連線數
connectionBuffer.append("getNumIdleConnections=" + ds.getNumIdleConnections());// 空閒連線數
connectionBuffer.append("getNumConnections=" + ds.getNumConnections());//總連線數
logger.info(" connectionBuffer=" + connectionBuffer.toString());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
後來進行mysql(預設100最大連結), tomcat(連線數default)tomcat 記憶體配置, c3p0(最大15個連結) 連結池優化。
Mysql: 在win7 c:/programdata/mysql/mysql server5.6/my.ini中配置
max_connections=1000
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections |1000 |
+-----------------+-------+
Tomcat: 配置連線數
<Connector port="8080"protocol="HTTP/1.1"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
disableUploadTimeout="true"
connectionTimeout="20000"
acceptCount="200"
maxThreads="800"
minThreads="600"
maxProcessors="1000"
minProcessors="1000"
useURIValidationHack="false"
redirectPort="8443"
/>
配置 tomcat 執行jvm 配置
set JAVA_OPTS=-server -Xms4400M-Xmx4400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M-XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection-XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly-Djava.awt.headless=true
應用 c3p0 連線池配置:
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close">
<propertyname="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl"value="jdbc:mysql://192.168.4.112:3306/iod1000?useUnicode=true&characterEncoding=utf-8"/>
<propertyname="checkoutTimeout" value="60000"/>
<propertyname="idleConnectionTestPeriod" value="30"/>
<propertyname="initialPoolSize" value="50"/>
<property name="maxPoolSize"value="800"/>
<property name="minPoolSize"value="50"/>
<propertyname="maxStatements" value="100"/>
<propertyname="properties">
<props>
<propkey="preferredTestQuery">SELECT 1</prop>
<propkey="c3p0.maxIdleTime">25000</prop>
<propkey="c3p0.testConnectionOnCheckout">true</prop>
<propkey="user">root</prop>
<prop key="password">iptv4Um8</prop>
</props>
</property>
</bean>
查詢配置了mysql 最大連線數 1000, 配置 c3p0 連線池 800 配置 tomcat 連結 800 測試結果:
CPU 8Core 12% usage
Memmory900M/2.4G 120q/S
這個時候碰到的問題就是 cpu 和 記憶體 都沒有達到上限,但是查詢的 效能卻提升不上去了。
5 試用jconsole 檢視tomcat 中的 執行緒狀態,好多執行緒都是 blocked on java.util.logging.console 原來是執行緒一直在等待寫日誌被block住了。
把寫log的語句 全部註釋掉。OK 系統終於飛起來了。
現在 能達到 250q/S。
需要檢查的地方:
CPU
記憶體
mysql最大連線數
tomcat 連線數配置
tomcat JVM 配置 重要的是記憶體大小
資料庫連線池配置:
程式內部的瓶頸。