十五天精通WCF——終結篇 那些你需要注意的坑

一線碼農發表於2015-08-01

    

          終於一路走來,到了本系列的最後一篇了,這一篇也沒什麼好說的,整體知識框架已經在前面的系列文章中講完了,wcf的配置眾多,如果

不加一些指定配置,你可能會遇到一些災難性的後果,快來一睹為快吧。

 

一: 第一個大坑 【資料傳輸量】

   我們使用wcf的目的,就是用來進行分散式的資料互動,既然是互動,就一定要進行資料交換,可能一些新人並沒有注意到wcf在資料傳輸量上

面做了一個大小限制,比如我現在要傳輸一個2m的txt給service,會出現什麼情況???

 1        static void Main(string[] args)
 2         {
 3             try
 4             {
 5                 var txt = File.ReadAllText("E:\\1.txt");
 6 
 7                 HomeServiceClient client = new HomeServiceClient();
 8 
 9                 client.Get(txt);
10 
11                 int i = 10;
12 
13             }
14             catch (Exception ex)
15             {
16 
17                 throw;
18             }
19         }

 

可是的可是,我們在玩aspnet的時候,再大的傳輸量都見過,但為什麼這玩意就拋異常了呢???下面一個問題就來了,這個傳輸預設值到底

是多少??? 接下來我們就用ILSpy翻翻看。

 

可以看到,這個叼毛玩意居然只有 64k。。。沒錯,你看到的就是64k,也就說明你的傳輸量不能大於64k,否則請求就會在client端拒絕,

知道了原因,我們現在就可以這麼修改config了。

    <bindings>
      <netTcpBinding>
        <binding name="MySessionBinding" maxReceivedMessageSize="2147483647"/>
      </netTcpBinding>
    </bindings>

 

有很多資料在配置這個坑的時候,也會使用MaxBufferSize 和 MaxBufferPoolSize,就是用來增加緩衝區和緩衝池的大小。

 

一: 第二個大坑 【併發量太低】

  說起這個大坑,還得先從一段程式碼說起,下面是一段對服務進行2w次併發呼叫,然後我們看看效果。

    public class Program1
    {
        static void Main(string[] args)
        {
            try
            {
                for (int i = 0; i < 200000; i++)
                {
                    try
                    {
                        Task.Factory.StartNew((obj) =>
                        {
                            try
                            {
                                HomeServiceClient client = new HomeServiceClient();

                                Console.WriteLine("第 {0} 個請求開始。。。", obj);

                                client.Get("12312");

                                Console.WriteLine("第 {0} 個請求結束。。。", obj);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                        }, i);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }

                Console.Read();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }

 

    從上面你可以看到,當併發數達到800左右的時候,servcie端就開始拒絕client端過來的請求了,並且之後的1min的時間裡,client端

開始出現超時異常,這肯定不是我想看到的, 那有人就要說了,我的併發達到800多很正常啊,如果提高這個併發呢???其實在wcf裡面

有一個叫做ServiceThrottlingElement繫結元素,它就是用來控制服務端的併發數。

 

這三個屬性的大概意思,我想大家都看的明白,不過有點奇怪的是,這三個屬性的預設值 和 ILSpy中看到的不一樣。。。

 

也懶的研究原始碼了,不管怎麼樣,反正這三個屬性值都是int型別的,所以我將他們設定為int.maxValue就好了。

<system.serviceModel>
    <behaviors >
      <serviceBehaviors >
        <behavior name="nettcpBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <!--是否在錯誤中包含有關異常的詳細資訊-->
          <serviceDebug includeExceptionDetailInFaults="True" />
          <serviceThrottling maxConcurrentCalls="2147483647" maxConcurrentInstances="2147483647" maxConcurrentSessions="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <netTcpBinding>
        <binding name="MySessionBinding" />
      </netTcpBinding>
    </bindings>

    <services>
      <service behaviorConfiguration="nettcpBehavior" name="MyService.HomeService">
        <endpoint address="net.tcp://127.0.0.1:19200/HomeService" binding="netTcpBinding"
          bindingConfiguration="MySessionBinding" contract="MyService.IHomeService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:1920" />
          </baseAddresses>
        </host>
      </service>
    </services>

  </system.serviceModel>

 

然後我們再把程式跑起來看一看。。。

 

      現在你可以發現併發早已突破800了,不過你要記住,如果併發數太多,容易造成系統資源耗盡,導致崩潰,這時候負載均衡就來

了,對吧,wcf需要修改的配置還有很多,正因為wcf框架龐大,很多預設配置不符合生產需求,所以大家在工作中需要注意,這個系列

就到此打住了,希望對你有幫助。

 

相關文章