程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則34:創建大容量的Web API(2)

Effective C#原則34:創建大容量的Web API(2)

編輯:關於C語言

這個客戶的例子清楚簡 單的演示了這個問題:在服務器與客戶端之間一來一回的傳輸整個對象。但為了 寫出高效的代碼,你應該擴展這個簡單的例子,應該讓它包含正確的相關對象集 合。在遠程請求中,使用對象的單個屬性就是使用太小的粒子(譯注:這裡的粒 子就是指一次交互時所包含的信息量)。但,對於每次在服務器與客戶之間傳輸 來說,一個客戶實例可能不是大小完全正確的粒子。

讓我們來再擴展一 下這個例子,讓它更接近現實設計中會遇到的一些問題,我們再對系統做一些假 設。這個軟件主要支持一個擁有1百萬客戶的在線賣主。假設每個用戶有一個訂 購房子的主要目錄,平均一點,去年有15個訂單。

每個電話接線員使用 一台機器輪班操作,而且不管電話訂單者是否回答電話,他們都要查找或者創建 這條訂單記錄。你的設計任務是決定大多數在客戶和服務器之間傳輸的高效對象 集合。

你一開始可能消除一些顯而易見的選擇,例如取回每一個客戶以 及每次的訂單信息是應該明確禁止的:1百萬客戶以及15百萬(1千5百萬)訂單記 錄顯然是太大了而不應該反回到做一個客戶那裡去。這樣很容易在另一個用戶上 遇到瓶頸問題。在每次可能要更新數據時,都會給服務器施加轟炸式打擊,你要 發送一個包含15百萬對象的請求。當然,這只是一次事務,但它確實太低效了。

相反,考慮如何可以最好的取回一個對象的集合,你可以創建一個好的 數據集合代理,處理一些在後來幾分鐘一定會使用的對象。一個接線員回復一個 電話,而且可能對某個客戶有興趣。在電話交談的過程中,接線員可能添加或者 移除訂單,修改訂單,或者修改一個客戶的賬號信息。明顯的選擇就是取回一個 客戶,以及這個用戶的所有訂單。服務器上的方法可能會是這樣的:

public OrderData FindOrders( string customerName )
{
 // Search for the customer by name.
 // Find all orders by that customer.
}

對的嗎?傳送到客戶而且客戶已經接 收到的訂單很可能在客戶機上是不須要的。一個更好的做法就是為每個請求的用 戶只取回一條訂單。服務器的方法可能修改成這個樣子:

public OrderData FindOpenOrders( string customerName )
{
 // Search for the customer by name.
 // Find all orders by that customer.
 // Filter out those that have already
 // been received.
}

這樣你還是要讓客戶機為每個電話訂單創建一 個新的請求。有一個方法來優化通信嗎?比下載用戶包含的所有訂單更好的方法 。我們會在業務處理中添加一些新的假設,從而給你一些方法。假設呼叫中心是 分布的,這樣每個工作組收到的電話具有不同的區號。現在你就可以修改你的設 計了,從而對交互進行一個不小的優化。

每個區域的接線員可能在一開 始輪班時,就取回並且更新客戶以及訂單信息。在每次電話後,客戶應用程序應 該把修改後的數據返回到服務上,而且服務器應該響應上次客戶請求數據以後的 所有修改。結果就是,在每次電話後,接線員發送所有的修改,這些修改包含這 個組中其它接線員所做的所有修改。這樣的設計就是說,每一個電話只有一次會 話,而且每一個接線員應該在每次回復電話時,手裡有數據集合訪問權。這樣服 務器上可能就有兩個這樣的方法:

public CustomerSet RetrIEveCustomerData(
 AreaCode theAreaCode )
{
 // Find all customers for a given area code.
 // Foreach customer in that area code:
  // Find all orders by that customer.
  // Filter out those that have already
  // been received.
 // Return the result.
}
public CustomerSet UpdateCustomer( CustomerData
 updates, DataTime lastUpdate, AreaCode theAreaCode )
{
 // First, save any updates, marking each update
 // with the current time.
 // Next, get the updates:
 // Find all customers for a given area code.
 // Foreach customer in that area code:
  // Find all orders by that customer that have been
  // updated since the last time. Add those to the result.
 // Return the result.
}

但這樣可能還是要浪費一些帶寬。當每個已知客 戶每天都有電話時,最後一個設計是最有效。但這很可能是不對的。如果是的, 那麼你的公司應該在客戶服務上存在很大的問題,而這個問題應該用軟件是無法 解決的。

如何更進一步限制傳輸大小呢,要求不增加會話次數和及服務 器的響應延時?你可以對數據庫裡的一些准備打電話的客戶進行一些假設。你可 以跟蹤一些統計表,然後可以發現,如果一些客戶已經有6個月沒有訂單了,那 麼他們很可能就不會再有訂單了。這時你就應該在那一天的一開始就停止取回這 些客戶以及他們的訂單。這可以收縮傳輸的初始大小,你同樣可以發現,很多客 戶在通過一個簡短電話下了訂單過後,經常會再打電話來詢問上次訂單的事。因 此,你可以修改訂單列表,只傳輸最後的一些訂單而不是所有的訂單。這可能不 用修改服務器上的方法簽名,但這會收縮傳輸給客戶上的包的大小。

這 些假設的討論焦點是要給你一些關於遠程交互的想法:你減少兩機器間的會話頻 率和會話時數據包的大小。這兩個目標是矛盾的,你要在這兩者中做一個平衡的 選擇。你應該取兩個極端的中點,而不是錯誤的選擇過大,或者過小的會話。

返回教程目錄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved