簡體   English   中英

非常簡單的企業應用程序架構 - 使其擴展

[英]Very simple Enterprise Application Architecture - making it scale

我正在為我的一個Intranet企業應用程序使用一個非常簡單的架構。

客戶:

  • 1個代理在每台計算機上運行發送系統配置數據(一次),報告(每2到5分鍾)=>從客戶端流向服務器的數據大小是幾百個字節,很少接觸到一個KB。

服務器:

  • 1個Web應用程序(管理客戶端的前端,查看報告)
  • 一個Web服務,用於接收所有傳入的數據(它只是轉儲到表中)
  • 每隔幾秒讀取轉儲並執行相關查詢的系統服務 - 插入,更新用於報告的實際表(此步驟可能與ETL進行比較)

由於數千個客戶端同時向服務器發送數據,服務器只是將這些傳入數據轉儲到臨時表中(每個客戶端發送數據一個插入)。 在后台運行的系統服務不斷刷新此臨時表 - 在某種意義上 - 每隔10秒,它從轉儲表中讀取前100行,將此數據組織到用於報告的相關表中,並從轉儲中刪除這100行等等。

到目前為止,我已經在2000台計算機的網絡中運行我的應用程序,它似乎運行良好。 現在我需要擴展它以支持25,000個客戶端的網絡。 我將以每秒25,000個請求運行模擬測試,並檢查架構是否保持良好狀態。

服務器是基於.NET的。 ASP .NET Web應用程序 - 用於轉儲數據的前端Web服務。 基於.NET的系統服務來執行ETL。 SQL Server 2005/2008作為數據庫服務器。

希望從stackoverflow社區獲得一些建設性的批評和指導,以改善這種架構。 您認為使用單個服務器與25,000個客戶端合作的方式是否足夠好? 您認為最有可能隨着並發活動的增加而崩潰的組件是什么? 它存在根本缺陷嗎? 歡迎各種指導。 謝謝。

均勻分布,“最壞情況”你的速度為12500轉/分鍾,即每秒209轉。

你應該做的最好的是前端負載平衡。

如果你有4台機器,那么每台機器每秒可以降低52轉。 每台機器在本地存儲它們的trans數據,然后分批批量插入到后端最終數據庫中。 這樣可以使主數據庫的傳輸量保持較低。 插入1行和50行(取決於行大小)之間的區別非常小。 在某些時候它取決於網絡開銷等“相同”。

因此,如果我們向下舍入到50(為了便於數學運算),前端機器每5秒將250行插入到后端數據庫中。 這不是一個低的音量(再次取決於行的大小)。

你提到在后端每個進程輪詢100個recs。 無論您在這里使用什么號碼,加上處理時間,都需要小於您的總流量和所需的完成時間。

具體來說,后端處理在短期內比前端插入速度慢,只要從長遠來看,你的后端趕上了。 例如,您的大部分流量可能是從上午8點到下午5點,但所有說完成后,您的后端處理將在晚上9點之前完成。

否則,后端永遠不會趕上,你總是落后,積壓就越來越大。 所以你需要確保你也能正確處理。

如果您的報告查詢很昂貴,最好也可以卸載它們。 讓前端計算機將原始數據發送到單個中間層計算機,然后讓第3台計算機將大量(可能是每天)批量導出到本地報告數據庫中以進行數據庫查詢。

另外,考慮故障和可用性方案(即如果您丟失了一台負載平衡的前端機器,您是否仍能跟上流量等)。 這里有很多失敗的空間。

最后,通常情況下,更新往往比刪除更便宜,因此如果您可以刪除停機時間而不是主流處理,那么如果需要,您可能會在那里找到一些性能。

在最壞的情況下,這意味着您的系統需要每分鍾流失5000-13000個請求。 您需要以60-70%的系統利用率(比如當前的2000個客戶端)計算系統的粗略吞吐量 - 如果Web服務每個請求大約需要50毫秒,那么這意味着它可以支持每分鍾最多1200個請求。 可以對.NET服務進行類似的計算。 隨着負載的增加,吞吐量可能會降低,因此實際數量會減少。 根據此類計算,您需要決定是否必須擴展系統。 您可以在多台服務器上運行您的服務,負載將被分割。 如果db server成為瓶頸,則可以以群集方式使用它。 您需要檢查的是,您的.NET服務實現是否允許並行性(IMO,Web服務將更少狀態並且應該擴展無問題) - 例如,您是否需要按照收到的順序插入記錄等等

運行模擬,看看它是如何支撐的。 可能是瓶頸的是網絡和可能的磁盤i / o。 在這種情況下,我可以提出一些建議。

第一關,我希望你使用UDP而不是TCP?

嘗試讓服務偵聽多個NIC。 使多個應用程序實例運行並訪問該表。 我不知道你正在使用什么數據庫但是sqlite對於這種類型的應用程序來說是完美的...它有一些功能可能有助於提高性能而不會經常觸摸磁盤。

服務器中有很多內存。

假設所有這些都完成了,如果它仍然沒有執行那么

下一步是擁有一系列中間服務器,每個服務器收集數千個客戶端的結果,然后通過更高速的鏈接將它們轉發到主服務器進行處理。 您甚至可以將它們批量發送到主服務器,並通過該鏈接壓縮數據。 或者只是SCP將它們轉移到它上面並批量導入結果。

無論如何,只是我的想法。 我正在研究類似的東西,但我的數據量將在幾個不同的高端服務器上連續幾乎連續1 - 2Gbit鏈接。所以中間服務器就是我們正在做的事情,

每秒25k請求需要擴展(即使每分鍾25k,每秒25k實際上是一個巨大的負載,你需要很多服務器來處理它)。 您必須擁有WWW服務服務器的園區,每個服務器都將請求轉儲到本地存儲(隊列)中。 您不能讓WWW服務器直接在后端進行通話,它會因爭用而死亡(由於客戶端請求嘗試在數據庫中的同一位置插入/更新而導致鎖定排除)。 WWW服務只是在本地轉儲請求,然后返回HTTP響應並繼續。 從中間層WWW服務器,這些請求必須聚合並加載到中央服務器。 這種加載必須可靠,易於配置,而且速度非常快。 不要因為'我只是自己用重試邏輯寫一個復制實用程序'的陷阱而陷入困境,那條道路鋪滿了屍體。 這個本地存儲的一個很好的候選者是SQL Server Express實例,聚合和加載的一個很好的候選者是Service Broker。 我知道這種架構有效,因為我已經完成了使用它的項目,請參閱High Volume Contiguos實時審計和ETL 我知道使用這種架構來擴展它的項目( 真的很高,請參閱March Madness on Demand實時分析與SQL Server 2008 R2 StreamInsight關於如何收集Silverlight媒體流運行時智能(兩個鏈接上的重點是不同的)技術,但sinc eI碰巧知道該項目很好我知道他們如何從WWW網絡服務收集數據到他們的后端)。

通過我的計算,在最壞的情況下,你每120秒有25000個插入。 每隔10秒就會讀取100行,這意味着在120秒內您已經讀取了1200行。 這意味着您的臨時表將不斷累積數據。

擴展系統需要做的是考慮如何向系統添加組件以處理負載。

設計Web服務以便能夠觸發對負責將數據插入臨時表的“從屬”的請求。 臨時表名稱列表需要保存在一些常見的命名服務中(就像另一個名稱表一樣簡單也可以)。

以類似的方式設計系統ETL服務,以選擇臨時表,讀取其所有行,完成其工作並將臨時表標記為已處理並返回休眠狀態。

這樣,您可以為插入和ETL添加其他進程。

最后,您的報告存儲庫將以驚人的速度增長。 希望那里的數據可以每周或每月清理一次?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM