posts - 193,  comments - 520,  trackbacks - 0
          項目情況:是一個大型公司的內部辦公系統,該系統有兩個和一般企業應用不太一樣的特點:一是用戶量非常多,人員數達到2W左右,另一個是采用分級管理的形式,各個分公司數據分開管理。

          我們的定位:我們是作為業務平臺的提供商參與這個項目的,我們提供底層的開發平臺,系統集成商在此基礎上進行二次開發。

          在項目從開發到部署的過程中遇到了很多的問題,也反映出很多問題。

          一、怎么回事,跑得比貓還慢
          項目開發完畢后部署在Ibm aix 小型機上,32G內存,16個cpu。應用服務器采用的是weblogic9.2,數據庫是oracle10.0.2。上線后發現系統運行的非常緩慢,甚 至比開發環境下的tomcat還要慢。于是開始排查原因,最開始是對SQL進行監控,優先考慮是數據庫訪問性能產生瓶頸。通過監控,發現很多業務需要執行 大量的SQL語句,查看客戶編寫的相關代碼,發現在查詢數據時循環執行了大量SQL。主要原因在于他們在代碼中循環調用了我們相關API,一個最典型的例 子是通過用戶ID查找用戶NAME,他們在業務表格里沒有保存用戶name,而是在查詢的時候通過用戶ID查找用戶name填充到頁面,幾乎每一個查詢都 是n+1。
           
          另外由于平臺使用了hibernate,使得oo編程得非常爽快,導致開發人員完全忽略了相應的數據庫操作所帶來的壓力。很多業務邏輯直接通過PO疊加完成,把一些可以通過很少SQL完成的邏輯全部分散放置到PO里,導致了大量PO的交互和SQL語句。

          開始優化SQL,優化的同時增加大量業務緩存。但優化完畢后運行緩慢的現象依舊存在,性能有了一定的提升但是不是非常明顯。繼續優化,其中考慮過 多頻繁訪問的數據使用內存數據庫的方式。但是優化過后在tomcat上效果明顯,部署到生產環境就問題依舊。于是考慮weblogic的配置問題,作為開 發平臺提供商,我們只是提供系統開發相關方面的支持,對于應用服務器和數據庫服務器只是做基本的配置系統可運行即可。但是在這個問題上系統集成商咬定是我 們平臺的問題不放,并且存在一個很嚴重的問題:他們使用的是盜版的weblogic,這樣根本就沒有相應的技術支持。

          問題的解決:最后是找了一個BEA曾經的開發人員,問題實際非常的簡單,現場部署的weblogic默認是運行在32位機器上,與64位機器存 在一定的不兼容。通過替換相應的jar包,問題得到了解決,主要是IO方面。替換完畢后,速度提升了進30% 。該開發人員說,如果沒有lisence,根本就不會得到這些替換的jar包。

          二、內存耗盡了
          訪問速度的問題解決了,系統的使用量很快上來,馬上遇到新的問題:內存耗盡了。嚴重到幾乎每天都要out of memory一次。這種問題在客戶現場頻繁出現。

          本地測試,tomcat,sun jdk 通過Jprofiler監測內存使用情況。在并發訪問門戶的情況下,內存確實存在暴漲的情況,100并發,內存使用立刻上升了150m左右,繼續并發 100,再增長150m。但是很快在抵達高峰時會有一次gc發生,內存使用穩定在200m,內存里大量char[]數組對象。疲勞測試,內存使用曲線并沒 有出現逐漸上升泄露的情況。換weblogic和jrocket測試,gc發生的更加頻繁,內存使用穩定。
           
          但是現場依舊頻繁當機,內存根本釋放不了,一直逐漸增長,典型的內存泄露。對系統緩存、單態對象包括spring管理的對象、IO流進行了統一 排查,依舊沒有找到內存泄露的原因。使用IBM 工具分析heapdump文件,結果還是大量的char[]數組對象占據內存,查找應用,找不到相關業務對象引用。
           
          問題解決:問題解決是一篇偶爾搜到的oracle論壇的帖子,這里http://forums.oracle.com/forums/message.jspa?messageID=1040570 。原因在于oracle10的數據庫驅動對statement最后執行的結果集有著引用,并且不會釋放,目的在于通過內存而換取更好的性能。數據庫連接采 用的是weblogic的連接池,關于connection有個相關的statement cache設定,設定一個connection能夠被緩存的statement個數,最大是1024,而現場就被設定為了1024!connection pool的connection個數被設置為了500 。真是個恐怖的設置。在將1024改為10后,內存使用量轟然倒地,穩定在1g左右。這個設置是在前面系統訪問速度存在問題時由系統集成商的開發人員設置 上去的,他們將所有和優化相關的參數全部開到了最大。這個問題要是用戶購買的是正版的weblogic和oracle的話,相信也會很快得到解決。

          三、線程阻塞
          內存泄露的問題解決后,線程阻塞的問題浮出水面。系統集成商報告是線程死鎖,通過分析工具其實是線程阻塞,主要問題在于系統用到了 synchronized關鍵字,對工作流相關API全部使用了synchronized,原因在這里:http: //ronghao.javaeye.com/blog/205731 。分析發現一個工作項提交的操作在連接數據庫時被掛起了20分鐘!造成了大量線程的排隊阻塞。被掛起的原因有很多種。我們采用的方法是將接口拆分和設置事 務timeout時間。但是這顯然不是一個好方法。最后是去掉所有的synchronized關鍵字,將同步的問題交由數據庫解決,問題解決。

          四、反思
          1、系統集成商為什么不購買正版?
          2、開發平臺提供商究竟在項目開發中處于一種什么樣的位置?開發平臺是否對所有軟件開發問題都要負責?
          3、開發平臺是越封裝越快樂嗎?還是越封裝越丑陋?

          更具體的細節在這里:

           AIX+weblogic性能診斷記錄



          http://www.aygfsteel.com/ronghao 榮浩原創,轉載請注明出處:)
          posted on 2008-09-01 13:49 ronghao 閱讀(4116) 評論(10)  編輯  收藏 所屬分類: 工作日志

          FeedBack:
          # re: 一次性能調優的實戰
          2008-09-01 14:26 | 隔葉黃鶯
          我也碰過這種性能問題,費盡周折才穩定下來

          我們用的 WAS,連接池默認的被緩存的statement個數是10,但是用了 hibernate 的應用必須把這個值設置為0

          其他就一些線程池,JVM 的參數調整,Tomcat 就簡單,沒多少要調優的,不過就是多用戶并發的時候直接就會死掉。  回復  更多評論
            
          # re: 一次性能調優的實戰
          2008-09-01 15:11 | 特斯通
          這個問題主要是沒有用正版引起的。jar包引起的問題最好在創建DOMAIN時不使用weblogic自帶的jdk的JAR。  回復  更多評論
            
          # re: 一次性能調優的實戰
          2008-09-01 20:42 | Robin's Java World
          @隔葉黃鶯
          為什么Hibernate不能使用被緩存的statement了?能解釋一下嗎?  回復  更多評論
            
          # re: 一次性能調優的實戰
          2008-09-01 22:36 | leekiang
          一方面大家認為做業務系統沒有技術含量,另一方面做的業務系統卻奇爛無比,很多做出來的系統連企業的業務數據的完整性都保證不了,更不用提別的了。
          很多做業務的公司基本是能騙就騙,因為要把業務系統做好是需要投入的,還不如招些便宜的新人,做些表面上好像能用的增刪改查,把客戶忽悠過去了事。
          所以說做企業應用注定就是忽悠,但不排除有個別有錢的甲方自己養人開發這種情況。
            回復  更多評論
            
          # re: 一次性能調優的實戰[未登錄]
          2008-09-02 11:58 | letitbe
          一個最典型的例子是通過用戶ID查找用戶NAME,他們在業務表格里沒有保存用戶name,而是在查詢的時候通過用戶ID查找用戶name填充到頁面,幾乎每一個查詢都是n+1。
          -----------------------------------
          業務表里存用戶的name,我覺得這是一種不好的設計:一是本身就冗余了;二是如果用戶的name改變了,那么多的業務表也要跟著改,太麻煩;另外用戶同名時容易讓人產生誤解,以為是同一個人。
          這個問題可以用數據庫分頁+外連接解決啊  回復  更多評論
            
          # re: 一次性能調優的實戰[未登錄]
          2008-09-02 12:16 | ronghao
          @letitbe
          yes.我要表達的意思是用戶這樣寫代碼造成了n+1的查詢問題。解決問題的方法可以是外連接,也可以是冗余字段。但是在平臺封裝提供API的情況下,用戶選擇了最簡單的直接調用API,這種方式是我反對的。由此我也在想平臺的封裝問題。所以對所有的業務操作我們都提供出直接的connection。  回復  更多評論
            
          # re: 一次性能調優的實戰
          2008-09-03 19:25 | bf1977
          怎么能查看 部署的weblogic是運行在32位機器上,還是64位機器?  回復  更多評論
            
          # re: 一次性能調優的實戰
          2008-09-05 11:09 | zbl400
          我就在想:
          系統集成商為什么不購買正版,并且 那個大型公司,存在2w以上員工的大公司居然也會同意不購買正版,難道真的是一點也不顧忌法律嗎?每個使用者出幾元錢,就能買到正版了吧。
          還想問一下:
          如果抓盜版的話,這個責任應該是在系統集成商上,還是在大型公司上呢?  回復  更多評論
            
          # re: 一次性能調優的實戰
          2009-02-12 16:52 | 趙斌
          很好的經歷啊,呵呵,部署生產環境、內存溢出、線程阻塞,幾乎每個大型應用上線都遇到的問題,簡直就是三部曲啊。  回復  更多評論
            
          # re: 一次性能調優的實戰
          2009-06-17 10:22 | ufo
          (web server軟件)UFO不會出現一個字節的內存泄漏和一個線程的不能回收,使用UFO做Web Server的好處是網站能做得很穩定,永遠也不會自己down掉;UFO在托管機房丟包率很高、遭受Hacker攻擊、互聯網 骨干網被黑等惡劣的環境條件下仍然能很好地運行;UFO在對付Hacker方面(防Hacker弄down和Hacker抓取不該訪問的資源)也有足夠措施。
          另外,UFO幾乎不會進行垃圾回收,消耗CPU很少,在普通的PC Server上用UFO運行網站,平時CPU占用率<0.1%,最多時也不會超 過5%。您知道,JVM的垃圾回收會導致大量的運算,消耗很多CPU,從而導致Server的負載能力和響應速度下降。UFO在對象管理方面采 用了很好的機制和算法,做得很出色。用UFO運行網站,可以一直保證高負載能力,快速的響應速度和低CPU消耗。發布網址:www.gm365.com
            回復  更多評論
            
          <2009年2月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          1234567

          關注工作流和企業業務流程改進。現就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

          常用鏈接

          留言簿(38)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          常去的網站

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 文山县| 大丰市| 永城市| 简阳市| 武川县| 合肥市| 淅川县| 柘荣县| 安义县| 莱芜市| 孟津县| 延吉市| 虞城县| 巴里| 米易县| 利川市| 望都县| 兴文县| 松江区| 堆龙德庆县| 吉木萨尔县| 利川市| 喀什市| 靖宇县| 黄浦区| 大渡口区| 新竹市| 临城县| 商都县| 诸暨市| 沂水县| 桂阳县| 澄迈县| 仁化县| 昭平县| 周宁县| 扎赉特旗| 邢台市| 米易县| 闸北区| 莫力|