隨筆-23  評論-6  文章-1  trackbacks-0

                   影響性能的測試報告(數據庫版)

          引言

          如需轉載,請與筆者聯系

           

          前提:項目組里無用到SPRING進行事務的管理。項目里以功能劃分到每個人手里,

          形成了BO,DAO,ACTION,VIEW都是單人負責。在DAO中每個動作都以

                封閉式的形式存在。

          問題:造成事務的不連貫性。功能是做出來了,性能問題遲早暴露。

          測試:主要針對程序頻繁請求數據庫連接對WEB應用所造成影響做一個測試。

           

           

          先做必要的說明,一步步引入正題,先從性能瓶頸開始:

          性能瓶頸

          所有的應用程序都存在性能瓶頸,為了提高應用程序的性能,就要盡可能的減少程序的瓶頸。以下是在JAVA程序中經常存在的性能瓶頸。

          pingjing.jpg
          了解了這些瓶頸后,就可以有針對性的減少這些瓶頸,從而提高JAVA應用程序的性能

           

          數據庫連接池工作原理

          關于連接池的實現原理測試方案:

          經過資料的收集與APACHE DBCP里連接池的查閱,對現有的連接池工作

          原理有兩種方式:

          1.        數據庫預先設置配置好的連接數。待得到用戶請求連接,傳出一個連接,而后為了保持供應數再提前創建連接,即提前預備連接數供請求。比如:

          5個通行道代表最大激活的連接數,最小2個閑置連接數。也就是說連接池里始終預備了2個可隨時提供的連接,連接的創建開銷是比較大的,連接池的存在就是了能夠最小化的解決創建所等待的時間。

            1            O

            2            O

            3            *

            4            *

            5            *

            如上圖,當1分配出去時由于池中連接數剩一個,為保持最小閑置,會自動創建一個新的連接以防止再次請求等待創建的時間。這樣確實減少了等待的時間,但是數據庫創建的開銷方面并未得到解決。如果把1-5比喻成汽車,那么這種情況下每量車都是一次性使用。1被請求后下一個連接將是6來接替。那么如何能夠重復利用1減少數據庫開銷。于是引出第二種方式。

           

          2.        回收使用完后的連接,放回到池中進行循環利用。這么做必須能保證2

             .  使連接能夠保持有效的回收。

             .  約束使用者使用釋放的動作,而不是直接把連接close.

           

          本人使用的是APACHE DBCPBasicDataSource的連接池基本實現,

          經過代碼與測試結果顯示,其工作方式是基于二的。

           

          BasicDataSource測試用例

          請看測試用例

          測試結果:


          2組數據:

          并發應用數:100 模擬連接數:6

          運行平均耗時:2956

          共使用51個連接

          運行平均耗時:3391

          2共使用52個連接

          運行平均耗時:2616

          共使用47個連接

          運行平均耗時:3377

          共使用41個連接

          運行平均耗時:3673

          共使用46個連接

          2組數據共執行5;平均耗時為:3229毫秒

          平均使用47個連接

           

          3組數據:

          并發應用數:85 模擬連接數:9

          運行平均耗時:4830

          共使用53個連接

          運行平均耗時:3247

          共使用49個連接

          運行平均耗時:4116

          共使用40個連接

          運行平均耗時:4070

          共使用43個連接

          運行平均耗時:4053

          共使用54個連接

          3組數據共執行5;平均耗時為:4063毫秒

          平均使用47個連接

           

          4組數據:

          并發應用數:140 模擬連接數:3

          運行平均耗時:2076

          共使用47個連接

          運行平均耗時:3104

          共使用51個連接

          運行平均耗時:2048

          共使用43個連接

          運行平均耗時:2421

          共使用50個連接

          運行平均耗時:2751

          共使用50個連接

          4組數據共執行5;平均耗時為:2480毫秒

          平均使用48個連接

           

          每次測試的結果都可能不同,但是所得到的結論是一致的。數據顯示不合理的請求使用連接嚴重的影響應用所能承受的并發數量,響應的時間也因此受到影響。

           

          目前普遍存在的問題

          沒有把事務控制好,一般會出現以下的情況:

          事務(){

            流程1();

            流程2();

          }

          可以看出流程12里都是單獨創建連接,并在自己的流程里完成操作。

          如果在流程2里出現異常,那么流程1所做的操作是不可恢復的。

          如果能控制在事務范圍內,如:

          事務(){

            Connection con;

            流程1(con);

            流程2(con);

            con.close();

          }

          那么數據庫少提供一個連接,事務的完成性也得到體現。在并發數量大的時候,

          效率上就有非常明顯的區別。

          解決方案

          1.  盡量保持少的請求

          DAO中有update()方法,則應再擴展一個方法update(Connection conn)

          在業務邏輯事務里調用update(Connection conn),一般情況下調用update()

          2.  對于數據不變的情況采用緩存技術,或部分緩存技術。

                可參照一些相關的開源的項目(JIVE)。

          posted on 2005-09-25 17:21 ceaboat 閱讀(1667) 評論(4)  編輯  收藏 所屬分類: JAVA小結

          評論:
          # re: 影響性能的測試報告(數據庫版) 2005-09-25 19:40 | martin xus

          討論一下:)

          一:
          事務(){
          流程1();
          流程2();
          }

          這樣的事務完全可以控制的,例如:采用command的模式

          Transactable tx = null;
          try{
          tx.begin();
          command = cmd.execute();
          tx.commit();
          } catch (Throwable e) {
          if (tx != null) {
          try {
          tx.rollback();
          } catch (Exception he) {
          throw new GeneralFailureException("事務回滾出錯", he);
          }
          }
          }

          這完全沒有問題的.


          二:
          個人認為connection沒有必要擴大到外面來,
          Connection con;
          流程1(con);
          流程2(con);
          con.close();
          connection應該是透明的,不應該出現在你的業務代碼中,再說,你的一個application不是有connection pool嗎?應該把connection交給容器去管理.

          再者:
          如果出現以下任一種情況怎么辦或者被別人誤用:
          (1):你的connection 被聲明為static
          (2):代碼沒有執行完畢,拋出異常,而又沒有合理處理connection
          那么這樣你的連接就可能被占著不放.做gc同樣也釋放不了.你的server肯定會菪機!


          你說呢?
            回復  更多評論
            
          # re: 影響性能的測試報告(數據庫版) 2005-09-25 20:24 | ceaboat
          我這里只做最普通的例子說明,并不是重在一定使用這種方式,重點是在于事務進行統一,雖然大家都知道這個,但是出呼意料,在項目中我看到更多的是使用
          事務(){
          流程1();
          流程2();
          }
          對于我來說難以理解,于是有必要做這個測試報告,在會議上進行討論。
          當然在正常使用中,異常的處理是必須的,但不是這個測試的重點所在。
          重點在于不合理的使用連接,頻繁的進行網絡交互所給系統帶來的負擔。  回復  更多評論
            
          # re: 影響性能的測試報告(數據庫版) 2005-09-25 20:32 | InPractice
          在同一個事務中,流程1和流程2共用一個連接應該效率較高。實踐中大家可能都沒有注意這個。因為一般是DAO和SERVICE兩層。每個DAO是獨立的,組合到Service中時也沒有特意讓兩個DAO共享同一個連接,就會出現上面的情況。  回復  更多評論
            
          # re: 影響性能的測試報告(數據庫版) 2005-09-26 09:04 | martin xus
          在一個項目中,非不得以,事務不應該交給組員去做的,對他們來說,這是不允許的.
          在他們的模塊中只是簡單的業務處理.普通的代碼,調用相應的service..

          開發前,先給組員開 “項目規范動員大會” :)  回復  更多評論
            
          主站蜘蛛池模板: 永安市| 广丰县| 揭阳市| 东港市| 新巴尔虎左旗| 当涂县| 张家界市| 新竹县| 松滋市| 通城县| 南阳市| 梁山县| 恩施市| 清流县| 乌拉特中旗| 万载县| 益阳市| 长寿区| 平湖市| 军事| 那曲县| 通城县| 土默特右旗| 清徐县| 宣武区| 奉节县| 平泉县| 德江县| 泽州县| 凤山县| 峨山| 象山县| 南溪县| 阿勒泰市| 华容县| 洪雅县| 仲巴县| 门源| 海伦市| 濮阳市| 汝州市|