Quantcast
Viewing all articles
Browse latest Browse all 2367

WCF探勘7-XML序列化資料量觀察

早先我們觀察過WCF HTTP vs TCP的傳輸量差異,該測試呼叫GetData()作業傳入數字接回字串,並不算真的用到WCF的DataContract/DataMember序列化功能,故這次改聚焦在物件資料的序列化上,再做一次比較。

我小幅改寫Visual Studio WCF專案範本的CompositeType,增加一個IntValue。

    [DataContract]
publicclass CompositeType
    {
bool boolValue = true;
string stringValue = "Hello ";
int intValue = 1;
 
        [DataMember]
publicbool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }
 
        [DataMember]
publicstring StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
 
        [DataMember]
publicint IntValue
        {
            get { return intValue; }
            set { intValue = value; }
        }
    }

GetDataUsingDataContract()也做一點改寫,傳回值改成CompositeType[],傳回資料筆數由傳入的CompositeType.IntValue決定,藉此彈性控制傳回結果筆數,以觀察資料筆數多寡對資料量的影響。

public CompositeType[] GetDataUsingDataContract(CompositeType composite)
        {
if (composite == null)
            {
thrownew 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,簡單驗證資料正確性。

staticvoid Main(string[] args)
        {
string[] bindingTypes = newstring[] {
"BasicHttpBinding_IService1",
"NetTcpBinding_IService1"
            };
foreach (var bindingType in bindingTypes)
            {
                var tsc = new WcfWas.Service1Client(bindingType);
                var compData = new WcfWas.CompositeType()
                {
                    BoolValue = true
                };
                var counts = newint[] {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

Image may be NSFW.
Clik here to view.

NetTcpBinding

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

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

Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 2367

Trending Articles