今天對之前寫的servlet程式做了個簡單的效能測試發現了一些問題,經過解決這些問題沒有再重現,有些問題自己確切知道原因,有的則不太確定。
1、設定檔讀取問題
項目中使用.properties作為設定檔,剛開始讀取方法如下,使用的是Properties:
public class ConfigHelper { private static Properties properties = new Properties(); /*** * * @param propertyName:屬性的key * @param defaultVal:預設值 * @return 返回設定檔名值,若找不到配置的key,返回預設值 * @throws IOException */ public static String getPropertyByKey(String propertyName, String defaultVal) throws IOException { String fileName = ("/config.properties"); InputStream fin = null; String value = null; try { fin = ConfigHelper.class.getResourceAsStream(fileName); properties.load(fin); value = properties.get(propertyName).toString(); } catch (FileNotFoundException e) { return defaultVal; } catch (IOException e) { return defaultVal; } finally { fin.close(); } return value; }}
在沒有壓力的情況下這種方法是沒問題的,但一旦有點並發發現這樣使用Properties是有問題的,壓力測試下出現的問題:
剛開始嘗試使用synchronized:
public static synchronized String getPropertyByKey(String propertyName, String defaultVal)
當時問題並沒有解決,此處省去N個字,最後解決方案如下,聲明一個類SafeProperties繼承自Properties,該類為單例:
/*** 讀取Properties屬性檔案* @author jdzhan*/public class SafeProperties extends Properties { /** * */ private static final long serialVersionUID = 1L; private static SafeProperties instance; public static SafeProperties getInstance(String path){ if (instance != null){ return instance; }else { makeInstance(path); return instance; } } private static synchronized void makeInstance(String path){ if (instance == null){ instance = new SafeProperties(path); } } private SafeProperties(String path){ InputStream is = getClass().getResourceAsStream(path); try { load(is); } catch (IOException ex) { System.err.println("錯誤資訊: 讀取屬性檔案失敗!"); System.err.println("請確認 【"+ path +"】 檔案是否存在。"); } }}
然後在修改ConfigHelper如下:
public class ConfigHelper { private static Properties properties = null; static{ String fileName = ("/config.properties"); properties=SafeProperties.getInstance(fileName); } /*** * * @param propertyName * :屬性的key * @param defaultVal * :預設值 * @return 返回設定檔名值,若找不到配置的key,返回預設值 * @throws IOException */ public static synchronized String getPropertyByKey(String propertyName, String defaultVal) throws IOException { InputStream fin = null; String value = null; try { value = properties.get(propertyName).toString(); } catch (Exception e) { LogHelper.writeLog("讀取設定檔出錯:"+ExceptionUtils.getFullStackTrace(e)); return defaultVal; } finally { if (fin != null) { fin.close(); } } return value; }}
2、Mysql:Communications link failure
在壓力測試下Mysql也報了一大堆問題,其中有一個問題如下:
這個問題我找到一個比較有參考意義的串連:
http://stackoverflow.com/questions/2121829/mysql-jdbc-communications-link-failure
但是我最後解決這個問題(可能根本沒解決)方法是將Mysql的max_connections從1000增加到10000。
3、Mysql:No operations allowed after statement closed.
這個問題折騰我時間最長,結果發現原來是自己代碼的問題,因為靜態變數的原因,細節不說了。最後得出結論是:這個問題“顧名思義”,一般是因為你後面使用了前面已經關閉的資料庫連接造成的。