摘要:比較并對比實際的 ASP.NET Web 服務、.NET 企業服務組件和 .NET Remoting 組件之間的性能特點,并獲得如何以最佳方式使用這些技術的建議。
本頁內容
![]() |
簡介 |
![]() |
目標 |
![]() |
結果 |
![]() |
.NET Framework 2.0 性能 |
![]() |
小結 |
![]() |
附錄 A:合成基線 — 空方法測試 |
![]() |
附錄 B — 詳細測試結果 |
![]() |
附錄 C:測試應用程序注意事項 |
![]() |
附錄 D:軟件和硬件安裝 |
簡介
雖然一些技術領域(設備、硬件控制器、人身醫療保健服務、某些金融系統)極為重視絕對性能,但是這些領域趨向于屬于少數領域行列。大多數商業應用程序的首要目標是“正確性”、“交付時間”以及必要的高執行效率,僅此而已。創建能夠提供絕對高性能的應用程序所花費的成本和精力是巨大的;大多數商業系統通常不需要實現高峰性能所需的時間和技巧。然而,追求絕對的高性能通常是一種過度行為,因此,保證系統整體性能良好仍然是希望獲得最大投資回報的商業人士所追求的一個目標。
本白皮書中,我們將提供針對實際組件/服務的相對性能級別的比較分析,這些組件/服務寄宿在 .NET 提供的三種分布式組件/服務技術的內部:
• |
寄宿在 COM+ 內的 .NET 企業服務 (ES) |
• |
寄宿在 IIS 內的 ASP.NET Web 服務 (ASMX) |
• |
寄宿在 IIS 和自定義主機內的 .NET Remoting |
(注 System.Messaging 與 MSMQ COM API 的性能比較在 System.Messaging Performance 一文中闡述)。
目標
關于“哪一種技術是 Microsoft 最快的分布式應用程序技術”或“<請在這里插入技術名稱> 使用起來太慢”的觀點,業界始終存在著永無休止的辯論。本文的主要目標就是解決和闡明與 Microsoft 分布式技術的性能相關的許多問題、誤解、不準確和錯誤的信息。
我們的目的是消除目前存在的許多誤解,這些誤解均與每個 Microsoft 分布式組件/服務技術的相對性能特點相關,并且提供一組清晰的說明性測試、測試結果以及一組簡潔的指導,它們將幫助您根據需要選擇最合適的技術。
簡言之,本文的目標是:
1. |
針對大多數商業應用程序研究這三種技術之間的相對性能差異 |
2. |
糾正一些假定:關于一種技術感知到的性能損失大于另一種技術 |
3. |
幫助并指導您決定使用每項技術的最佳地點、時間和方式。 |
4. |
提供一個測試應用程序,以便您能夠在自己的環境和計算機上運行這些測試。我們強烈建議您構建并運行這個測試環境,以研究和分析這些技術的性能特點。這樣,您將能夠完全理解影響分布式系統性能的多種因素。 |
這不是一個基點
本白皮書介紹的測試旨在提供接受測試的特定技術之間的一致比較結果。這些測試不是為度量每項技術在負載時的最大絕對性能而設計的。
測試驅動程序(客戶端)是單線程的,因此序列化同步調用與調用服務的響應速度一樣快。使用這種設計方式時,瓶頸通常不是服務器 CPU 的使用率。
多個客戶端或一個多線程客戶端可能會導致服務器在每秒內處理更多的調用。對于更多的 CPU 密集型服務器應用程序測試而言,多個客戶端并不能顯著改變接受測試的技術的絕對性能或相對性能。
對于最輕量的測試而言,使用多個客戶端可能會實現更高的 (2X) 累積服務器吞吐量。多個客戶端也可能改變不同技術的相對性能。
單一客戶端或多個客戶端是否更為實用依賴于 Web 服務的部署地點和部署方式。本文的結論不受使用單一客戶端進行度量的決策影響。
測試
在以下性能測試中,我們將探究合成基線和實際情況。我們設定要檢查的通用問題是:
1. |
.NET Remoting 比 ASMX 更快嗎? |
2. |
ES 比 Remoting 更慢嗎? |
3. |
ASMX 用于實際操作是不是太慢了? |
• |
為了檢查這些問題,我們進行了一些測試。主要的測試用于檢查針對操作進行調用的性能,這些操作要么接受一個重大請求并完成大量工作,要么被要求完成大量工作并返回小結果集或大結果集。這些測試的目的是說明這些技術在典型商業環境中的性能,這些環境很可能就是您在構建系統時使用的。 |
所有這些測試都是針對每個可用技術的協議運行的:
• |
企業服務(使用實時激活)
| ||||||||||||||||||
• |
ASP.NET Web 服務
| ||||||||||||||||||
• |
.NET Remoting
|
以下所有測試均基于反復調用服務器端方法的單一客戶端應用程序。我們計算了集合中每個測試在每秒內的遠程調用/方法調用的平均次數,整個集合重復計算了 10 次,從而獲得了一個完整的多階段測試執行的平均偏差和標準偏差。
結果
測試 1:創建和存儲定單
第一個測試旨在模擬每種技術在最優化情況下呈現的性能特點 — 這里調用的操作要完成大量的工作。為了完成大量工作,調用的操作將定單存儲在一個數據庫中,這涉及到在一個事務內將記錄寫入兩個表格。
調用方創建以下 Order 類的一個實例。
[Serializable] public class Order { public int OrderID; public String CustomerID; public int EmployeeID; public DateTime OrderDate; public Address ShippingAddress; public Address BillingAddress; public int ShipVia; public decimal Freight; public LineItem[] LineItems; }
Order 類包含一個類型為 Address 的子對象和一個包含 20 個 LineItems 的數組:
[Serializable] public class Address { public String Name; public String Street; public string City; public string Region; public string PostalCode; public string Country; } [Serializable] public class LineItem { public int ProductID; public double UnitPrice; public short Quantity; public double Discount; }
這個數據對象在方法調用期間從調用方傳遞到服務器,并由接受測試的不同技術進行序列化并傳送到網絡上。
服務器端的實現與以下代碼類似:
SqlConnection _conn; private void InitializeComponent() { // ... large parts of generated code removed _conn = new SqlConnection(); // ... large parts of generated code removed } public void StoreOrder(Order o) { using (_conn) { _conn.Open(); using (SqlTransaction tx = _conn.BeginTransaction()) { using (SqlCommand cmd = new SqlCommand(@"INSERT INTO Orders(EmployeeID, " + "CustomerID, OrderDate, RequiredDate, ShipVia, ShippedDate, " + "ShipName, Freight, ShipAddress, ShipCity, ShipRegion, " + "ShipCountry, ShipPostalCode) VALUES (@EmployeeID, @CustomerID, " + "@OrderDate, @RequiredDate, @ShipVia, @ShippedDate, @ShipName, " + "@Freight, @ShipAddress, @ShipCity, @ShipRegion, @ShipCountry, " + "@ShipPostalCode); SELECT @@IDENTITY", _conn,tx)) { cmd.Parameters.Add("@EmployeeID", o.EmployeeID); cmd.Parameters.Add("@CustomerID",o.CustomerID); cmd.Parameters.Add("@OrderDate",o.OrderDate); cmd.Parameters.Add("@RequiredDate",o.OrderDate.AddDays(10)); cmd.Parameters.Add("@ShipVia",o.ShipVia); cmd.Parameters.Add("@ShippedDate",o.OrderDate.AddDays(5)); cmd.Parameters.Add("@ShipName",o.ShippingAddress.Name); cmd.Parameters.Add("@Freight",o.Freight); cmd.Parameters.Add("@ShipAddress",o.ShippingAddress.Street); cmd.Parameters.Add("@ShipCity",o.ShippingAddress.City); cmd.Parameters.Add("@ShipRegion",o.ShippingAddress.Region); cmd.Parameters.Add("@ShipCountry",o.ShippingAddress.Country); cmd.Parameters.Add("@ShipPostalCode",o.ShippingAddress.PostalCode); decimal orderID = (decimal) cmd.ExecuteScalar(); o.OrderID = (int) orderID; } using (SqlCommand cmd = new SqlCommand(@"INSERT INTO [Order Details] (OrderID, " + "ProductID, UnitPrice, Quantity, Discount) VALUES (@OrderID, " + "@ProductID, @UnitPrice, @Quantity, @Discount)", _conn,tx)) { cmd.Parameters.Add("@OrderID",SqlDbType.Int); cmd.Parameters.Add("@ProductID",SqlDbType.Int); cmd.Parameters.Add("@UnitPrice",SqlDbType.Money); cmd.Parameters.Add("@Quantity",SqlDbType.SmallInt); cmd.Parameters.Add("@Discount",SqlDbType.Real); foreach (LineItem itm in o.LineItems) { cmd.Parameters["@OrderID"].Value = o.OrderID; cmd.Parameters["@ProductID"].Value = itm.ProductID; cmd.Parameters["@UnitPrice"].Value = itm.UnitPrice; cmd.Parameters["@Quantity"].Value = itm.Quantity; cmd.Parameters["@Discount"].Value = itm.Discount; cmd.ExecuteNonQuery(); } } tx.Commit(); } _conn.Close(); } }
測試執行完成后,服務器端邏輯使用第二個事務來刪除插入的記錄,因此無論這個測試執行多少次,都能提供一個一致的基準。

圖 1. 通過一個真正的服務器端實現在計算機之間傳遞“定單”
查看圖 1 中的測試結果時,請注意,ES @73 CPS 與 ASP.NET Web 服務 @63 CPS 之間只有 14% 的差距,速度最快的協議與速度最慢的協議之間的最大差距是 45%。這一結果清楚地表明,在執行的工作量隨傳輸數據所花費的時間成比例增長時,任何一種給定的傳輸協議與其他協議相比,其優越性都會減弱。
我們還創建了一個匹配的 ADO.NET DataSet 測試,生成了類型化 DataSet,其中包含如圖 2 定義的 DataTable。

圖 2. 這個 DataSet 表示一個購買定單
這個 DataSet 與生成的 SqlDataAdapter 一起使用,SqlDataAdapter 中包含的 SqlCommand 與上述代碼片段中的類似。
當定單作為一個 DataSet 從調用方傳遞到服務器并存儲起來時,我們得到如圖 3 所示的結果。

圖 3. 將購買定單存儲為 DataSet
需要注意的是,使用 DataSet 嚴重影響了性能(下降了大約 50%),但是協議之間的差異進一步縮小。另外值得注意的是,傳遞數據對象最慢的協議在傳遞 ADO.NET DataSet 時,超出了最佳性能。
這一結果清楚地表明在系統各層之間傳遞 ADO.NET DataSet 會帶來極大的性能損失。
測試 2:檢索 Northwind 產品數據
這項測試的目的是說明從一個服務返回相對可調整的數據量時每種技術的性能特點,而這個服務不需要執行大量工作。
為了模擬這個情況,我們構建了一些方法,用于從熟悉的 SQL Server“Northwind”示例數據庫中檢索和返回“product”記錄列表。
我們認為在這項測試中,二進制序列化技術(ES/COM+ 和 Remoting Binary/TCP)的性能最好,而基于 SOAP 的技術將得到較低級別的性能,這是由于它需要傳輸的數據量更大,以及它的序列化和反序列化機制更為復雜。
在第一項測試中,我們定義了一個 [Serializable] 類,它具有與 XML 序列化程序兼容的公共成員:
[Serializable] public class Product { public int ProductID; public string ProductName; public int SupplierID; public int CategoryID; public string QuantityPerUnit; public decimal UnitPrice; public short UnitsInStock; public short UnitsOnOrder; public short ReorderLevel; public bool Discontinued; }
在服務器端實現中,我們打開一個指向 SQL Server 的數據庫連接,對數據庫執行查詢,并使用 ADO.NET SqlDataReader 填寫一個 ArrayList,其中包含該類的 77 個 Product 實例。然后,將 ArrayList 返回給調用方。
結果如圖 4 所示。

圖 4. 將 Northwind 產品目錄作為對象進行檢索
這些結果表明企業服務(通過 DCOM)和基于 TCP 的二進制 Remoting 為不安全的調用提供同等級別的性能。同時,也表明 ASP.NET Web 服務提供的性能大約是企業服務性能的 62%,傳輸速度最慢的協議與最快的協議相比,每秒鐘只響應后者調用次數的 17%。
在這項測試和所有后續測試中,有一點很明確,那就是為什么在生成 SOAP 服務時通常建議不要使用 .NET Remoting SoapFormatter:因為 ASP.NET Web 服務堆棧的速度比它快兩倍。
在第二項測試中,我們實現了這樣一個方法:它在一個 ADO.NET DataSet 對象(該對象完全基于基礎表格布局)中返回請求的數據,并使用 SqlDataAdapter 來填充 DataSet 的 DataTable。表格定義如圖 5 所示。

圖 5. 訪問產品目錄的類型化 DataSet
圖 6 說明結果:

圖 6. 將 Northwind 產品目錄作為 DataSet 進行檢索
這項測試的結果清楚地表明,將 DataSet 從服務返回到調用方極大地降低了性能 — 較之于二進制傳輸幾乎降低了 75%!還需要注意的是,四個速度最快的協議的性能完全相同,這意味著,所有這四項技術都受序列化、反序列化和 DataSet 傳輸的遏制。而且,最快的協議 (ASMX @ 39 cps) 和最慢的協議(Remoting HTTP/SOAP (IIS) 集成安全性 @ 25 cps)之間只有 14 cps 的性能差異 — 僅相差 30%。
這突出地說明,雖然使用 DataSet 在應用程序各層之間傳遞信息很方便,但是這樣做會極大地影響性能。我們稍后將討論這個問題。
需要指出的是,循環訪問 ADO.NET DataSet、構造數據對象集合以及序列化該集合這一系列操作,比只將 ADO.NET DataSet 返回給調用方速度更快!如果這是一個實際系統,需要在服務器和調用方之間傳遞 DataSet,那么我們只需少量工作就能將系統的這部分性能提高大約四倍。
測試 3:檢索客戶信息
在下一項測試中,我們想通過在“Northwind”SQL Server 示例數據庫中檢索一條客戶記錄,來檢查每項技術在傳輸極少量數據時表現出的相對性能特點。
我們創建以下 [Serializable] Customer 類,以便將檢索到的數據從服務器傳送回客戶端:
[Serializable] public class Customer { public String CustomerID; public String CompanyName; public String ContactName; public String ContactTitle; public string Address; public string City; public string Region; public string PostalCode; public string Country; public string Phone; public string Fax; }
以下顯示服務器端實現的部分代碼,其中使用一個 SqlDataReader 來填充 Customer 類的新實例:
public Customer GetCustomer(string id) { using (SqlConnection conn = new SqlConnection(...)) { conn.Open(); String sql = "SELECT CustomerID, CompanyName, ContactName, " "ContactTitle, Address, City, Region, " + "PostalCode, Phone, Fax, Country FROM " + "Customers WHERE (CustomerID = @CustomerID)"; using (SqlCommand cmd = new SqlCommand(sql,conn)) { cmd.Parameters.Add("@CustomerID", id); SqlDataReader rdr = cmd.ExecuteReader(); if (rdr.Read()) { Customer c = new Customer(); c.CustomerID = (string) rdr[0]; c.CompanyName = (String) rdr[1]; c.ContactName = (String) rdr[2]; c.ContactTitle = (String) rdr[3]; c.Address = (String) rdr[4]; c.City = (String) rdr[5]; c.Region = rdr.IsDBNull(6) ? "" : rdr[6] as string; c.PostalCode = (String) rdr[7]; c.Phone = (String) rdr[8]; c.Fax = (String) rdr[9]; c.Country = (String) rdr[10]; return c; } else { return null; } } } }
性能比較結果如圖 7 所示。

圖 7. 將客戶數據作為對象進行檢索
這些結果更為明顯地突出了每項基本技術之間的性能差異。這些差異在這項測試中非常明顯,因為檢索和返回一條記錄所做的工作在整體調用開銷中所占的百分比很小,所以傳輸開銷起到了較重要的作用。由于 SOAP/HTTP 的傳輸開銷比二進制/DCOM 更高,因此 SOAP 傳輸顯示出比二進制機制低得多的吞吐量。
下面,我們測試返回類型化 DataSet 的同一項操作,如圖 8 所示。

圖 8. 訪問客戶信息的類型化 DataSet
使用以下類似的服務器端實現來填充這個 DataSet:
SqlDataAdapter _customerAdapter; SqlCommand _customerSelect; SqlConnection _conn; private void InitializeComponent() { // ... large parts of generated code removed _conn = new SqlConnection(); _customerAdapter = SqlDataAdapter(); _customerSelect = SqlCommand(); _customerSelect.CommandText = "SELECT CustomerID, CompanyName, " + "ContactName, ContactTitle, Address, City, Region, " + "PostalCode, Phone, Fax, Country FROM Customers WHERE " + "(CustomerID = @CustomerID)"; _customerSelect.Connection = _conn; _customerSelect.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.NVarChar, 5, "CustomerID")); _customerAdapter.SelectCommand = this.sqlSelectCommand3; _customerAdapter.TableMappings.AddRange(new DataTableMapping[] { new DataTableMapping("Table", "Customers", new DataColumnMapping[] { new DataColumnMapping("CustomerID", "CustomerID"), new DataColumnMapping("CompanyName", "CompanyName"), new DataColumnMapping("ContactName", "ContactName"), new DataColumnMapping("ContactTitle", "ContactTitle"), new DataColumnMapping("Address", "Address"), new DataColumnMapping("City", "City"), new DataColumnMapping("Region", "Region"), new DataColumnMapping("PostalCode", "PostalCode"), new DataColumnMapping("Phone", "Phone"), new DataColumnMapping("Fax", "Fax"), new DataColumnMapping("Country", "Country")})}); // ... large parts of generated code removed } public PerfTestDataSet GetCustomerAsDataset(string id) { using (_conn) { _conn.Open(); customerAdapter.SelectCommand.Parameters["@CustomerID"].Value = id; PerfTestDataSet ds = new PerfTestDataSet(); _customerAdapter.Fill(ds,"Customers"); return ds; } }
在測試框架中運行這段代碼時,得到如圖 9 所示的結果。

圖 9. 將客戶數據作為 DataSet 進行檢索
與前面的測試相似,顯然,交換 ADO.NET DataSet 消極地影響了性能,而且所有技術在吞吐量方面的差異在返回序列化對象時變得更小,這表明 ADO.NET DataSet 遏制了吞吐量。
.NET Framework 2.0 性能
撰寫本文時,Microsoft 正致力于發布 .NET Framework 2.0(先前代號為“Whidbey”),它包含了大量改進、增強和新功能,包括:
• |
完全支持基于 x64 和 IA64 的機器 |
• |
通過 System.Transactions 實現的全新事務支持 |
• |
針對 System.Net 的許多增強,包括連接識別和支持代理 |
• |
針對 Windows 窗體和 Web 窗體的重大改進 |
• |
“ClickOnce”自動化應用程序部署基礎結構 |
除了 .NET Framework 2.0 包含的新功能和增強功能之外,在顯著提高性能和改進內存利用率方面也付出了大量努力,這涉及到包括 BCL、XML 序列化、網絡吞吐量、ADO.NET、ASP.NET 等在內的許多領域。
有關這些性能改進和吞吐量改進的早期示例,請參見以下白皮書:
• |
Comparing XML Performance .NET Framework 2.0 Beta 2、.NET Framework 1.1 和 Sun Java 1.5 Platforms |
• |
Comparing Web Service Performance 用于 .NET Framework 2.0 的 WS Test 1.1 Benchmark Results、.NET 1.1、Sun JWSDP 1.5 和 IBM WebSphere 6.0 |
隨著 .NET Framework 2.0 繼續向 RTM (release to manufacturing) 版本邁進,在未來的一段時間內,將發布更多有關性能分析和比較的白皮書。為了及時查閱這樣的白皮書,請訪問下列在線資源:
• |
The .NET Framework Developer Center |
• |
Competitive Reports and Evidence: Comparing .NET to J2EE |
小結
上述實際測試結果如表 1 所示。
表 1. 結果摘要 | |||
每秒進行的調用次數(四舍五入) | 企業服務 | ASP.NET Web 服務 | .NET Remoting TCP Binary |
測試 1:存儲定單 |
73 |
63 |
72 |
測試 2:檢索產品 |
147 |
93 |
149 |
測試 3:檢索客戶 |
618 |
289 |
682 |
這些結果表明您期望在實際應用程序中獲得的性能特點,而且,用于實際應用程序的 Web 服務(通常認為速度極慢)和 DCOM(是本測試中最快的分布式應用程序技術之一)之間的差異事實上是很小的。
有關接受測試技術的結論將在后面內容中詳細討論,但是在這里加以總結:
• |
盡管 ASMX 不是目前發布的最快的技術,但是它的性能足以應付大多數商業環境。而且,ASMX 服務易于定制,并能提供諸如互操作和向后兼容等其他多種優點,因此在構造當今的服務時,ASMX 應該是您的首選。 |
• |
如果絕對性能是最重要的因素,您應該使用企業服務組件來構建系統中以性能為重的部分。COM+ 的整體性能最佳,并且是一個用于分布式組件的安全、可靠的宿主環境。ES/COM+ 與 Indigo 服務集成得很好,使得將 ES 組件轉換為 Indigo 服務相對簡單。 |
• |
盡管 .NET Remoting 在 TCP 上使用二進制序列化時性能良好,但是當 Remoting 組件寄宿在 IIS 中和/或用于發送和接收 SOAP 消息時,其性能將降低。而且,.NET Remoting 組件只與 .NET Remoting 端點進行交互,因此我們極力主張在任何可以使用 Remoting 的地方優先考慮 ASMX 或 ES。 |
從這些結果得出的一個主要結論是,如果服務器執行工作花費的時間在每個調用的整體持續時間內所占的百分比不高,那么傳輸時間將占用很大一部分比例的調用時間。如果您從一個“快速的”傳輸協議(例如 COM+ 之下的 DCOM)轉換到一個“開銷”更大的傳輸協議(例如 ASMX 之下的 SOAP/HTTP),則可能會體驗到嚴重的性能影響。因此,這清楚地表明了我們的建議 — 在服務器端為每個方法調用執行盡可能多的工作,以及避免不必要的網絡遍歷。
隨著調用服務執行的工作量的增加,這些技術優于其他技術的性能優勢將變小。許多文章都闡述過這個結論,包括 .NET Enterprise Services Performance。
這些測試還表明,這些技術之間的性能差異比特定應用程序決策(例如,使用 DataSet 還是序列化結構)之間的差異更小。
在重點關注本文中的性能數字的同時,還要注意,在計劃開發項目時,性能不是要考慮的唯一因素。諸如安全性、可擴展性、管理、開發人員工作效率、互操作和 Microsoft 分布式技術的未來發展方向等其他因素都應該予以考慮,Developing Distributed Services Today 一文為如何最好地選擇利用每項技術的時間和地點及其未來發展提供了說明性指導。
建議
根據這些測試的結果以及未來的技術發展方向和最佳實踐,并結合以下建議,您將能夠構建不易受性能問題困擾的系統:
盡可能使用 ASMX
為了向為服務提供最廣泛的使用范圍,請考慮盡可能使用 ASMX 來發布服務。這將使任何通過 HTTP 與 SOAP 進行會話的系統都可以調用服務,無論該系統運行或實現哪種平臺、設備或語言。您可以從上述結果中看到,ASMX 在許多情況下都很適用。即使在由單線程應用程序調用的單處理器機器上,ASMX 每秒鐘也能夠處理 63 個復雜操作 — 每秒鐘只比同等的 ES 組件少 10 個調用!在生產環境中,您可以期望使用一臺承載 ASMX 服務的機器來獲得更好的性能,因此 ASMX 的性能不應該是您采用這項重要技術的障礙。
Web 服務也呈現出其他有用的特征和特性,包括(但不限于):
• |
可擴展性 — 使用負載平衡技術很容易定制一個 Web 服務,例如 Windows 網絡負載平衡,或由 Cisco、F5 等供應商提供的硬件設備。這一領域需要了解的知識還有很多。 |
• |
可用性 - ASMX Web 服務可以通過結合多種技術配置成具有高度可用性的服務,例如,結合 Windows 2003 Server 中內置的負載平衡與 IIS6 基礎框架的強大功能(例如,自動回收和重新啟動失敗的服務)。 |
• |
互操作性 - Web 服務在標準化交互安全、可靠的事務型通訊協議的活動中處于核心地位,這些通訊協議能夠使分散、異構的系統之間進行自由地通訊。 |
• |
效率 - 對于大多數開發人員而言,通過合理使用一些屬性并遵循一些建議,生成 ASMX Web 服務是一件非常容易的事。 |
使用 ASMX 生成 Web 服務
有很多原因可以解釋為什么 ASMX 是一個用于生成和部署服務的絕佳平臺(如 prescriptive guidance 中所述),并且從本文得出的結果來看,在與使用 SOAP 進行會話時,ASMX 通常要比 Remoting 優越。
還需要注意的是,雖然 .NET Remoting 能夠支持 SOAP/HTTP(通過它的 SoapFormatter 和 HttpChannel),但我們還是反對使用 Remoting 公開 Web 服務。.NET Remoting SoapFormatter 使用 RPC 編碼方法,它已經不是對 SOAP 進行編碼的標準方法了(document-literal 是未來大多數供應商的技術和平臺所使用的標準編碼機制);因此,通過 Remoting 服務進行的互操作將十分有限。
根據可擴展性選擇 Web 服務
上文沒有說明(但是與這個討論話題休戚相關)的一點是,Web 服務會話主要通過 HTTP 進行,它是一種易于達到負載平衡的無狀態通訊技術。這意味著,使用 TCP 或 HTTP(例如寄宿在 IIS 內部)也可以使無狀態的 Remoting 組件達到負載平衡,盡管這在要求會話狀態時會變得錯綜復雜。
為了使 ES/COM+ 組件達到負載平衡,必須使用組件負載平衡 (CLB),這是 Application Center 2000. Alas 提供的一個功能,AppCenter 2000 將在 2006 年 7 月至 2011 年之間提供這項擴展支持。因此,為了避免在 2011 年之前重新構建系統以使之不再依賴于 CLB,強烈建議您在新的開發項目中回避這項技術,并盡快遷移至其他策略。一個好的移植策略是使當前的 COM+ 組件面向 ASMX Web 服務,由 ASMX Web 服務將調用直接傳遞到 COM+ 組件,并使您的 Web 服務達到負載平衡,如上文所述。
僅在服務內部使用企業服務
.NET 企業服務是 .NET Framework 的一層,它提供對多種 COM+ 服務的訪問和支持。如果您需要使用多種 COM+ 服務中的任意一種,例如,跨越幾個對象/服務的分布式事務、細粒度的安全性、JITA 和對象池,那么您應該選擇企業服務。企業服務和 COM+ 是經過嚴格測試、高度優化的技術,能夠提供非?焖、低延遲時間的進程間和計算機間的調用。
然而,我們強烈建議您不要廣泛公開您的企業服務組件,并且僅在服務邊界內使用這項技術。如果您希望提供對服務的訪問,則我們極力主張通過使用 ASMX 的 Web 服務公開您的服務功能。如果您有確定的 ES/COM+ 代碼基,則我們建議盡可能使您的 COM+ 服務面向 ASMX Web 服務。
考慮在您構建的架構之上使用一個宿主架構
正如在前面看到的,ASP.NET 發布了功能強大的 Web 服務,這些服務交互性強,并且得益于 IIS(特別是 Windows 2003 Server 中的 IIS6)提供的強大宿主功能。
COM+ 在 Microsoft 平臺上提供最快的組件性能,它還可以為企業服務和 COM+ 組件提供經過試驗的、可信、安全而可靠的宿主環境。它還提供分布式事務支持、安全措施(身份驗證和加密)、可靠性、可用性和管理服務,是用于在服務內承載復雜的、基于組件的系統的明智選擇。
盡管 .NET Remoting 在 TCP 上使用二進制序列化也能夠提供良好的性能,但是它不提供任何宿主環境、安全性、可靠性、可用性或“范圍外”的管理功能。為了承載使用 TCP 的 Remoting 組件,必須編寫自己的(安全的、可擴展的、可靠的)宿主應用程序,這可不是微不足道的任務。如果希望在 HTTP 上使用 Remoting,可以選擇使用 IIS 作為宿主,但是您會發現,在 IIS 中承載 Remoting 組件并使用 SOAP/HTTP 會話將極大地影響 Remoting 的性能 — ASMX 通常性能更好!
因此,我們極力主張盡可能使用寄宿在 IIS 內的 ASMX 或寄宿在 COM+ 內的企業服務組件來發布服務(而不是使用 Remoting)。
避免在服務之間傳遞 DataSet
在我們的測試中,選擇服務與調用方交換數據的方法(以 DataSet 或序列化結構)帶來的性能影響比選擇任何一種特定的分布式系統技術帶來的影響大得多。
從性能角度來看,我們強烈主張將 DataSet 作為數據傳輸機制的使用限制在應用程序真正需要的部分,并盡可能選擇使用 [Serializable] 結構。
ADO.NET DataSet 提供許多優秀方法,用于檢索、操作、排序和塑造數據,將數據存儲在本機以便脫機使用,以及將更改同步到中央數據庫。如果您的應用程序需要這些功能,那么,這當然是個正確的選擇。在 .NET Framework 1.x 中,DataSet 值通常序列化為 XML 格式(即使您聲明想要序列化為二進制格式,或者將它們與 ES 或 Remoting 一起使用),并且還包含描述數據的 XSD。這當然會影響性能。
此外,請記住 DataSet 是一項特定于 .NET 的技術,它將極大地限制您的互操作性,因為其他平臺不一定能夠序列化和解析包含序列化 DataSet 的數據。
通過交換序列化數據結構,您能夠獲得重大的性能改進。正如上述測試表明的那樣,內置的運行時格式化和 XML 序列化框架使之變得很容易。
使用經過驗證的連接共享
所有使用 Internet Information Server 作為宿主并與集成安全性相結合的測試已經配置為通過選項 useAuthenticatedConnectionSharing 和 useUnsafeAuthenticatedConnectionSharing 運行,這兩個選項可用于 ASP.NET 客戶端和 .NET Remoting。這項配置允許客戶端和服務器重用一個現有的 NTLM 驗證連接。
當我們設置這個選項時,您能夠看到如圖 10 所示的性能結果,我們采用的測試最初是在圖 1(將購買定單存儲為對象)中使用的。請注意,僅當使用 Internet Information Server (IIS) 做為服務器并在虛擬目錄的配置中要求“Windows In Security”時,這項設置才起作用。
MSDN Magazine 2004 年 9 月號的專欄 Web Q&A: Caching Transforms, Connection Sharing, and More 討論了這些折衷選擇。

圖 10. UnsafeAuthenticatedConnectionSharing 的影響
您可以在 ASP.NET Web 服務內部結合使用Windows 集成安全性 和該項設置:
MyWebService svc = new MyWebService(); svc.Credentials = System.Net.CredentialCache.DefaultCredentials; svc.UnsafeAuthenticatedConnectionSharing = true;
按以下方式與 .NET Remoting 結合使用:
IMyRemote rem = (IMyRemote) Activator.GetObject(typeof(IMyRemote), "HTTP://..."); IDictionary snkprops = ChannelServices.GetChannelSinkProperties(rem); snkprops["unsafeauthenticatedconnectionsharing"] = true;
附錄 A:合成基線 — 空方法測試
這項測試“劃分出”接受比較的基本技術之間的性能差異。這些測試針對操作發出調用,這些調用不接受參數、不執行工作,也不返回結果。服務器端實現如下列代碼一樣簡單:
public void TransferEmpty() { // do nothing }
注 需要記住的是,這些合成基線的數字只用于說明每項接收測試技術的通訊結構的相對性能級別,并不反映實際系統中預期的性能特點。

圖 11. 在進程間調用無參數方法(合成基線)
圖 11 中的測試結果與常見的設想非常吻合:ES 提供了迄今為止最好的性能,這是由于它對 COM+ 和 DCOM 的信任以及高性能的 LPC(輕量過程調用)上層通訊結構。.NET Remoting 網絡協議的性能次之。ASP.NET Web 服務稍遜一籌,但是仍然要比寄宿在 IIS 內的 .NET Remoting 快。
第二步,我們在計算機之間運行了這項測試。我們通過設置生成的 ASP.NET 的“Url”屬性來將其重定向,為 COM+/企業服務組件導出應用程序代理,并針對這項測試的 .NET Remoting 部分使用 Activator.GetObject()。得出的結果與之前的測試結果如出一轍,只不過由于涉及到網絡遍歷,因此每秒鐘的調用次數有些偏低:

圖 12. 在計算機之間調用無參數的空方法(合成基線)
請注意,計算機之間的網絡遍歷從本質上抑制了最快的傳輸協議(ES 和 Remoting Binary/TCP),但是對較慢的傳輸協議幾乎沒有影響。這清楚地表明,與主要為網絡通訊服務的技術(例如,IIS 和 ASMX)相比,COM+ 的進程間通訊機制特別高效。
需要記住的一點是,正如前面提到的那樣,這項測試是虛構的,僅用于說明傳輸協議的功能。
附錄 B — 詳細測試結果
將定單存儲為對象 | ||
測試 | 平均調用次數/秒 | 標準偏差 |
企業服務 |
73 |
0.39 |
企業服務(驗證) |
73 |
0.34 |
Remoting TCP/Binary |
72 |
2.71 |
Remoting HTTP/Binary |
68 |
0.86 |
Remoting HTTP/Binary (IIS) |
66 |
0.31 |
ASP.NET Web 服務 |
63 |
2.71 |
Remoting HTTP/Binary (IIS) 密碼 |
63 |
0.39 |
Remoting TCP/SOAP |
56 |
1.97 |
Remoting HTTP/SOAP |
53 |
0.57 |
Remoting HTTP/Binary (IIS) 集成 |
51 |
0.28 |
Remoting HTTP/SOAP (IIS) |
50 |
0.16 |
ASP.NET Web 服務 — 集成 |
50 |
0.30 |
Remoting HTTP/SOAP (IIS) 密碼 |
49 |
0.29 |
Remoting HTTP/SOAP (IIS) 集成 |
40 |
0.84 |
將定單存儲為 DataSet | ||
測試 | 平均調用次數/秒 | 標準偏差 |
企業服務 |
35 |
0.54 |
企業服務(驗證) |
35 |
0.51 |
ASP.NET Web 服務 |
34 |
0.43 |
Remoting TCP/Binary |
34 |
0.85 |
Remoting HTTP/Binary |
32 |
0.77 |
Remoting HTTP/Binary (IIS) |
32 |
1.10 |
Remoting TCP/SOAP |
32 |
0.77 |
Remoting HTTP/Binary (IIS) 密碼 |
31 |
1.47 |
Remoting HTTP/SOAP |
30 |
0.68 |
Remoting HTTP/SOAP (IIS) |
30 |
0.48 |
Remoting HTTP/SOAP (IIS) 密碼 |
30 |
0.46 |
ASP.NET Web 服務 — 集成 |
29 |
0.37 |
Remoting HTTP/Binary (IIS) 集成 |
28 |
0.37 |
Remoting HTTP/SOAP (IIS) 集成 |
26 |
0.31 |
將產品作為對象加載 | ||
測試 | 平均調用次數/秒 | 標準偏差 |
Remoting TCP/Binary |
149 |
3.05 |
企業服務 |
147 |
2.29 |
企業服務(驗證) |
146 |
2.49 |
Remoting HTTP/Binary |
118 |
2.13 |
Remoting HTTP/Binary (IIS) |
114 |
0.63 |
Remoting HTTP/Binary (IIS) 密碼 |
106 |
1.19 |
ASP.NET Web 服務 |
93 |
1.04 |
Remoting HTTP/Binary (IIS) 集成 |
76 |
0.81 |
ASP.NET Web 服務 — 集成 |
67 |
0.35 |
Remoting TCP/SOAP |
33 |
0.34 |
Remoting HTTP/SOAP |
30 |
0.32 |
Remoting HTTP/SOAP (IIS) |
30 |
0.25 |
Remoting HTTP/SOAP (IIS) 密碼 |
29 |
0.16 |
Remoting HTTP/SOAP (IIS) 集成 |
26 |
0.14 |
將產品作為 DataSet 加載 | ||
測試 | 平均調用次數/秒 | 標準偏差 |
ASP.NET Web 服務 |
39 |
0.12 |
企業服務 |
39 |
0.26 |
企業服務(驗證) |
39 |
0.21 |
Remoting TCP/Binary |
39 |
1.16 |
Remoting HTTP/Binary (IIS) |
36 |
0.24 |
Remoting HTTP/Binary |
35 |
1.10 |
Remoting HTTP/Binary (IIS) 密碼 |
35 |
0.17 |
ASP.NET Web 服務 — 集成 |
33 |
0.09 |
Remoting HTTP/Binary (IIS) 集成 |
31 |
0.21 |
Remoting TCP/SOAP |
30 |
1.27 |
Remoting HTTP/SOAP (IIS) |
29 |
0.12 |
Remoting HTTP/SOAP |
28 |
1.07 |
Remoting HTTP/SOAP (IIS) 密碼 |
28 |
0.06 |
Remoting HTTP/SOAP (IIS) 集成 |
0.08 |
[Text] |
將客戶作為對象加載 | ||
測試 | 平均調用次數/秒 | 標準偏差 |
Remoting TCP/Binary |
682 |
12.32 |
企業服務 |
618 |
13.78 |
企業服務(驗證) |
616 |
7.76 |
Remoting HTTP/Binary |
406 |
7.84 |
Remoting TCP/SOAP |
359 |
11.62 |
Remoting HTTP/Binary (IIS) |
324 |
4.26 |
ASP.NET Web 服務 |
289 |
2.68 |
Remoting HTTP/SOAP |
267 |
6.18 |
Remoting HTTP/Binary (IIS) 密碼 |
261 |
2.39 |
Remoting HTTP/SOAP (IIS) |
214 |
2.84 |
Remoting HTTP/SOAP (IIS) 密碼 |
186 |
0.81 |
Remoting HTTP/Binary (IIS) 集成 |
134 |
0.95 |
ASP.NET Web 服務 — 集成 |
130 |
0.67 |
Remoting HTTP/SOAP (IIS) 集成 |
112 |
0.55 |
將客戶作為 DataSet 加載 | ||
測試 | 平均調用次數/秒 | 標準偏差 |
Remoting TCP/Binary |
91 |
2.69 |
企業服務 |
90 |
0.30 |
企業服務(驗證) |
90 |
0.26 |
ASP.NET Web 服務 |
83 |
0.24 |
Remoting HTTP/Binary |
80 |
0.67 |
Remoting TCP/SOAP |
78 |
1.04 |
Remoting HTTP/Binary (IIS) |
78 |
0.22 |
Remoting HTTP/Binary (IIS) 密碼 |
75 |
0.26 |
Remoting HTTP/SOAP |
71 |
0.92 |
Remoting HTTP/SOAP (IIS) |
67 |
0.34 |
Remoting HTTP/SOAP (IIS) 密碼 |
64 |
0.20 |
ASP.NET Web 服務 — 集成 |
62 |
0.14 |
Remoting HTTP/Binary (IIS) 集成 |
59 |
0.15 |
Remoting HTTP/SOAP (IIS) 集成 |
52 |
0.13 |
空消息,進程間 | ||||||||||
測試 | 平均調用次數/秒 | 標準偏差 | ||||||||
企業服務 |
14687 |
52.66 | ||||||||
企業服務(驗證) |
12293 |
31.71 | ||||||||
Remoting TCP/Binary |
3538 |
38.87 | ||||||||
Remoting HTTP/Binary |
1069 |
8.05 | ||||||||
Remoting TCP/SOAP |
1075 |
11.87 | ||||||||
Remoting HTTP/SOAP |
612 |
7.88 | ||||||||
Remoting HTTP/Binary (IIS) |
589 |
1.83 | ||||||||
ASP.NET Web 服務 |
517 |
1.44 | ||||||||
Remoting HTTP/Binary (IIS) 集成 |
451 |
1.19 | ||||||||
Remoting HTTP/Binary (IIS) 密碼 |
421 |
0.90 | ||||||||
Remoting HTTP/SOAP (IIS) |
406 |
1.76 | ||||||||
ASP.NET Web 服務 — 集成 |
403 |
0.76 | ||||||||
Remoting HTTP/SOAP (IIS) 集成 |
336 |
0.57 | ||||||||
Remoting HTTP/SOAP (IIS) 密碼 |
32
延伸閱讀
文章來源于領測軟件測試網 http://www.kjueaiud.com/
領測軟件測試網最新更新
關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved 北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2 技術支持和業務聯系:info@testage.com.cn 電話:010-51297073 老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
|