今天群里有個朋友說他們醫院項目采用直連數據庫,高峰時期sqlserver的連接數達到7000多,於是我准備做個用diocp做個demo,服務端用連接池。白天的時候我在想,並發如果7000個。如果用diocp做三層服務器,連接池應該在100個左右。今天晚上奮斗了一晚上,准備把測試過程中碰到的問題總結一下。
所有的代碼測試代碼寫完后,准備開始測試,配置后服務端的連接池(config\dbpool.config)
{ "main": { "host": ".", "user": "sa", "password": "efsa", "database": "EF_DATA" }, }
配置中main為連接池中連接的ID<通過id獲取連接>
在客戶端編寫測試線程
procedure TTester.Execute; var lvCds:TClientDataSet; begin InterlockedIncrement(__TesterCount); lvCds := TClientDataSet.Create(nil); try while (not self.Terminated) and (not __stop) do begin try FRDBOperator.clear; FRDBOperator.RScript.S['sql'] := FSQL; FRDBOperator.QueryCDS(lvCds); except on E:Exception do begin TFileLogger.instance.logErrMessage(FTesterCode + E.Message); end; end; //每執行一次進行異常關閉連接 FRDBOperator.Connection.close; end; TFileLogger.instance.logDebugMessage(FTesterCode + '線程已經停止[' + TesterCode + ']'); FConnection.close; finally InterlockedDecrement(__TesterCount); lvCds.Free; end; end;
開始測試100,個線程,在筆記本上測試
問題來了
幾下客戶端就連接不上了,怎么連接都連接不上<服務端連接數為0>,關閉了客戶端重新開也不行。心中一下就涼了,不會我寫的iocp這么脆弱吧。
經過幾個小時的折騰和寫各種日志,發現服務端中工作線程和監聽線程都是好好的,沒有退出線程。
后來我查看網絡情況發現服務端有在監聽9983端口<但是telnet不通>,我發現有好多被關閉的127.0.0.1->127.0.0.1:9983的連接,但是在網絡狀態中可以看到,
過一段幾分鍾后,發現又可以連接上,估計客戶端不能頻繁的建立連接和關閉連接。
后來把客戶端代碼修改下<刪除下面的代碼>。發現一切正常,還好不是服務端的問題,diocp還是經的住考驗。
//每執行一次進行異常關閉連接
FRDBOperator.Connection.close;
開啟1000個客戶端,不停獲取數據,發現服務端連接池中最多只有7個連接,不過機器比較卡了<畢竟是筆記本>,想想我白天是多想了,diocp根據cpu的數量開啟的工作線程工作線程如果是7個,連接數肯定也不會超過7個。就算客戶端連接有7000個,數據庫的連接數也就是7個而已。
就算有7000個連接估計同時在執行數據庫的也不過就幾百個而已。處理起來應該是沒有問題的。明天給群里的朋友測試下。多弄幾台客戶端測試下
=============2015-01-28 10:10:24
上面測試環境,邏輯是在io線程中處理,其實把邏輯數據投遞到其他線程池進行處理,是可以突破7個連接的限制。
后來的diocp1和現在的diocp3都有這種方案了依靠iocpTask/qworker進行邏輯的處理,這樣不占用通信io線程