WCF探勘7-XML序列化資料量觀察
| | | 0 | |
早先我們觀察過WCF HTTP vs TCP的傳輸量差異,該測試呼叫GetData()作業傳入數字接回字串,並不算真的用到WCF的DataContract/DataMember序列化功能,故這次改聚焦在物件資料的序列化上,再做一次比較。
我小幅改寫Visual Studio WCF專案範本的CompositeType,增加一個IntValue。
[DataContract]
public class CompositeType
{ bool boolValue = true;
string stringValue = "Hello ";
int intValue = 1; [DataMember]
public bool BoolValue
{ get { return boolValue; } set { boolValue = value; } }
[DataMember]
public string StringValue
{ get { return stringValue; } set { stringValue = value; } }
[DataMember]
public int IntValue
{ get { return intValue; } set { intValue = value; } }
}
GetDataUsingDataContract()也做一點改寫,傳回值改成CompositeType[],傳回資料筆數由傳入的CompositeType.IntValue決定,藉此彈性控制傳回結果筆數,以觀察資料筆數多寡對資料量的影響。
public CompositeType[] GetDataUsingDataContract(CompositeType composite) { if (composite == null)
{ throw new ArgumentNullException("composite");
}
var res = new List<CompositeType>(); for (var i = 0; i < composite.IntValue; i++) res.Add(new CompositeType() { BoolValue = composite.BoolValue,
StringValue = "Item" + i, IntValue = i
});
return res.ToArray(); }
Client端則修改如下,改呼叫GetDataUsingDataContract(),透過IntValue要求Server傳回1、16、64、128或256筆結果,取得結果後加總各筆資料的IntValue並檢視最後一筆的StringValue,簡單驗證資料正確性。
static void Main(string[] args)
{ string[] bindingTypes = new string[] {
"BasicHttpBinding_IService1", "NetTcpBinding_IService1" };
foreach (var bindingType in bindingTypes)
{ var tsc = new WcfWas.Service1Client(bindingType); var compData = new WcfWas.CompositeType() { BoolValue = true };
var counts = new int[] {1, 16, 64, 128, 256};
for (int i = 0; i < counts.Length; i++)
{ compData.IntValue = counts[i];
var res = tsc.GetDataUsingDataContract(compData);
var sum = res.Sum(o => o.IntValue);
var txt = res.Last().StringValue;
Console.WriteLine("Items Count={0}, Sum={1}, String={2}", res.Length, sum, txt);
}
}
Console.Read();
}
執行結果如下,顯示內容沒什麼意義,期間的資料傳輸量才是重點。
Items Count=1, Sum=0, String=Item0 Items Count=16, Sum=120, String=Item15 Items Count=64, Sum=2016, String=Item63 Items Count=128, Sum=8128, String=Item127 Items Count=256, Sum=32640, String=Item255 Items Count=1, Sum=0, String=Item0 Items Count=16, Sum=120, String=Item15 Items Count=64, Sum=2016, String=Item63 Items Count=128, Sum=8128, String=Item127 Items Count=256, Sum=32640, String=Item255
所以我們開啟MNM,觀察HTTP及TCP傳輸的封包記錄如下。黃底部分是每次Server用來回傳結果的封包,旁邊已加註該次傳回資料筆數方便對照。
BasicHttpBinding

NetTcpBinding

整理結果如下,中間兩欄的數字為HTTP及TCP傳回不同結果筆數產生資料量(Bytes),最後一欄則為TCP資料量除以HTTP資料量的比例。

數字有點可疑,BasicHttpBinding使用XML序列化,NetTcpBinding採二進位序列化,但差距比想像的小很多,且筆數愈多,差距愈小,在256筆時,資料量比例約為10:8,與直覺出入甚大。莫非與HTTP壓縮有關?檢視封包內容,果然看到SOAP XML被IIS壓縮,實際上傳送的不是XML,而是被壓縮過看似亂碼的資料。

為觀察未壓縮的原始資料量,在IIS關閉動態內容壓縮:

重新測試一次,這回可在封包觀察到SOAP XML的模樣,很肥!

而用XML傳256筆資料要花35,118 bytes。

重新統計IIS未壓縮模式下的SOAP XML傳輸,除了單筆資料外,不管筆數多寡,TCP資料量固定維持SOAP XML的15%,符合我們的認知。

實務上,IIS會啟用動態壓縮,最後的實驗純屬好奇並非常態,第一次做的統計才接近真實狀況。也就是說,在IIS壓縮加持下,HTTP+SOAP XML的資料量膨脹不如想像嚴重(例如:256筆時僅多21%),但每次傳輸耗用較多封包數,資料量較大仍是事實,基於效能考量,Intranet的純Windows應用仍應優先考慮TCP。
Comments
Be the first to post a comment