上周接到一位從事電子產品生產的大學同學的QQ說他的一個ERP系統有問題,幫他看看,周末他過來詳細的了解了一下情況:周一到周五使用的用戶數是10-20個人,系統慢起來就是大家一起慢,人數少的時候不慢,另外一個揪心的問題就是大家同時使用的使用經常無故的退出,而且他還強調了他買的是一個強大的服務器了,系統運行了2年時間,數據量也不大。
先描述下系統情況:
操作系統:WindowsServer 2003
.NET版本:.NET 2.0/ASP.NET 2.0
數據庫: SQL Server
從前面描述的問題,初步可以判定:
1、系統不穩定,估計是系統大量使用了Session ,Session丟失導致不穩定
2、10-20個用戶訪問就很慢,可以判斷使用的是SQL Server Express 版本,SQL Server Express 最大的並發用戶數小於等於12個,只能支持一個CPU,最大的內存量是1G等.
了解完情況就開始動手啦,首先登陸到他的的服務器去看了下,上述判斷成立:
1、SQL Server Express 是2005的,SQL Server Express 2005的介紹可以看這里 http://msdn.microsoft.com/zh-cn/library/ms345154(v=SQL.90).aspx ,他的服務器有4核,只能有效使用到一個核,不支持執行諸如並行查詢這樣的功能,這個就可以很好的解釋他的用戶量碰到的場景。解決方案就是幫他裝一個SQL Server 2008 R2 標准版的吧。
2、看到他的Session 模式是InProc,由於Asp.net程序是默認配置,所以Web.Config文件中關於Session的設定如下:
<sessionState mode='InProc' cookieless='true' timeout='1200'/>
我們會發現sessionState標簽中有個屬性mode,它可以有3種取值:InProc、StateServer?SQLServer(大小寫敏感) 。默認情況下是InProc,也就是將Session保存在進程內(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),這個進程不穩定,在某些事件發生時,進程會重起,所以造成了存儲在該進程內的Session丟失。 開發這系統的程序員吧timeout時間設置為了1200,這里可看出在不正確的使用Session,程序代碼必然在大量的應用Session,這個應該是導致系統不穩定的根源。
哪些情況下該進程會重起呢?微軟的一篇文章《PRB: 會話變量是間歇性地丟失在 ASP.NET 應用程序中》告訴了我們:
1、配置文件中processModel標簽的memoryLimit屬性
2、Global.asax或者Web.config文件被更改
3、Bin文件夾中的Web程序(DLL)被修改
4、殺毒軟件掃描了一些.config文件。
解決方案:
前面說到的sessionState標簽中mode屬性可以有三個取值,除了InProc之外,還可以為StateServer、SQLServer。這兩種存Session的方法都是進程外的,所以當aspnet_wp.exe重起的時候,不會影響到Session。
現在請將mode設定為StateServer。StateServer是本機的一個服務,可以在系統服務里看到服務名為ASP.NET State Service的服務,默認情況是不啟動的。當我們設定mode為StateServer之后,請手工將該服務啟動。
這樣,我們就能利用本機的StateService來存儲Session了,除非電腦重啟或者StateService崩掉,否則Session是不會丟的(因Session超時被丟棄是正常的)。
除此之外,我們還可以將Session通過其他電腦的StateService來保存。具體的修改是這樣的。同樣還在sessionState標簽中,有個stateConnectionString='tcpip=127.0.0.1:42424'屬性,其中有個ip地址,默認為本機(127.0.0.1),你可以將其改成你所知的運行了StateService服務的電腦IP,這樣就可以實現位於不同電腦上的Asp.net程序互通Session了。
如果你有更高的要求,需要在服務期重啟時Session也不丟失,可以考慮將mode設定成SQLServer,同樣需要修改sqlConnectionString屬性。
3、數據庫的所有表除了主鍵外沒有任何索引,這對於數據量不大的時候體現不出來,雖然這個問題不是這次的問題的重點,不過是將來這個系統的隱患。這個屬於數據庫優化部分,本次可以不做,需要拿到代碼后分析都用到那些查詢條件,好建立索引。
服務器上的調整完了,可以解決他的大問題了,然后讓他向開發商要到了最新的代碼,期間的很多事情讓我無限感慨中國的軟件業為什么做不好。雖然這只是一個小示例,基本上可以代表中國的微小軟件開發商的狀態。
1、代碼沒有源代碼控制:要到的代碼和運行環境不一致,這個是對他的當前這個系統最沒把握的地方,這個項目使用的是ASP.NET Web Site 方式開發的,把他生產環境的運行的代碼拷到本地來,這個可以解決當前運行的版本和代碼部分一致性了,還有這個項目參照的微軟的那個寵物商店模式搞的,PetShop是一個范例,微軟用它來展示.Net企業系統開發的能力。業界有許多.Net與J2EE之爭,許多數據是從微軟的PetShop和Sun的PetStore而來。這種爭論不可避免帶有濃厚的商業色彩,對於我們開發人員而言,沒有必要過多關注。PetShop是一個小型的項目,系統架構與代碼都比較簡單,這也是這個項目看起來還可以的一個原因,不過Web Site 部分的代碼看起來真是揪心,一眼掃過去,就可以看到大量的不安全、穩定的代碼,隨時可能報錯。也許這是一個系統不穩定的原因。
2、系統的開發人員能力弱:這個項目的流程,包括頁面怎么做都是我的這位同學定的,不得佩服這位兄弟,他是學物理的,大學畢業后工作了2年開始出來獨立創業,搞電子產品零部件的開發,期間的經歷也很心酸,現在已經有基礎,最近生意也不錯。他不會開發程序,會搞硬件設計。他把軟件的開發工作委托一個小公司開發完成,也一直是這家公司做維護。最近他受不了,找到我,想今后不再這家公司幫他維護了,讓我幫他搞搞。據他描述,他提的修改問題給開發人員,改后就出現另外的問題。很多問題沒法解決,看着這些開發人員很頭疼。沒有版本控制,開發人員水平差也許是導致他的抱怨的原因。