首页 新闻 会员 周边

WCF性能问题大探讨

0
[已解决问题] 解决于 2013-07-08 21:15

最进项目进行性能优化工作,主要是WCF方面的性能优化。

一丶说说我们项目的结构:

  1. 安卓前台,通过创建HTTP请求调用WCF服务

    参考文章:http://blog.csdn.net/cch5487614/article/details/6333077 (安卓怎么调用WCF方法)

  2. WCF后台,主要是提供数据,以及做一些重要的业务逻辑处理

 

二丶传输格式

  数据传输格式:后台处理安卓前台的请求,返回的对象要通过JSON转化之后才返回给前台

  注意:JSON转化后的字符串长度一般在10000。

 

三丶WCF的配置文件

 1   <system.serviceModel>
 2     <services>
 3       <service name="JsonService.Operations" behaviorConfiguration="Service">
 4         <endpoint address="" binding="basicHttpBinding"  bindingConfiguration="httpBinding_Config" contract="IJsonOperation" >
 5         </endpoint>
 6         <host>
 7           <baseAddresses>
 8             <add baseAddress="http://192.168.23.8/Service/"/>
 9           </baseAddresses>
10         </host>
11       </service>
12     </services>
13     <behaviors>
14       <serviceBehaviors>
15         <behavior name="Service">
16           <serviceMetadata httpGetEnabled="true" />
17           <serviceDebug includeExceptionDetailInFaults="true" />
18           <serviceThrottling maxConcurrentCalls="8000" maxConcurrentInstances="8000" maxConcurrentSessions="8000"/>
19         </behavior>
20       </serviceBehaviors>
21     </behaviors>
22     <bindings>
23       <basicHttpBinding>
24         <binding name="httpBinding_Config"  maxReceivedMessageSize="2147483647" useDefaultWebProxy="false" textEncoding="utf-8" maxBufferPoolSize="2147483647"   maxBufferSize="2147483647" messageEncoding="Text" sendTimeout="00:10:00">
25           <security mode="None"></security>
26           <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647"/>
27         </binding>
28       </basicHttpBinding>
29       <netNamedPipeBinding>
30         <binding name="PipeBinding" maxConnections="100" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"  sendTimeout="00:10:00">
31           <security mode="None" ></security>
32           <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647"/>
33         </binding>
34       </netNamedPipeBinding>
35     </bindings>
36   </system.serviceModel>

 

  WCF的实例模型和并发模型的设置:

1     [ServiceBehavior( InstanceContextMode = InstanceContextMode.Single, 
              UseSynchronizationContext = false,
              ConcurrencyMode = ConcurrencyMode.Multiple,
              IncludeExceptionDetailInFaults = true)]

  

  注意:项目中每一个方法中的执行时间都不会超过一秒(项目中的代码优化已经做到很好了,一般情况下都没有问题)。

 

三丶尝试的解决方案

  1. 字符串压缩

  2. 调整限流设置 - serviceThrottling 

  3. 增大WCF并发时的线程数量

    参考:http://www.cnblogs.com/shanyou/archive/2013/02/09/2909569.html

   通过这样修改后感觉效果不是很明显。

  

四丶测试结果

  同时开启500个线程去调用WCF服务方法,得到的数据是:

  就调用一个方法,JSON转化的字符串长度为6500.

  最后面是调用时间,单位为毫秒。

  

  现象:调用的时间会一直在增加,最终的时间为200毫秒。

 

五丶疑问

  1. 为什么调用时间一直在增加,我不是设置了并发模型了,怎么会这样?

  2. JSON的大字符串传输有什么好的办法解决?

  3. 有没有人有安卓调用WCF的性能优化经验?

 

最后希望大家给我点建议。

TimYang的主页 TimYang | 初学一级 | 园豆:12
提问于:2013-07-01 21:05
< >
分享
最佳答案
0

“调用的时间会一直在增加”可能是计算调用时间的代码有问题,建议检查一下

我觉得这样的应用场景,性能瓶颈不在WCF

奖励园豆:5
dudu | 高人七级 |园豆:30994 | 2013-07-01 21:22

这就是我的测试代码,dudu大哥这样写有问题不?
1
public partial class Form1 : Form 2 { 3 private JsonOperationClient client = null; 4 5 public Form1() 6 { 7 InitializeComponent(); 8 9 client = new JsonOperationClient(); 10 InvokeService(); 11 } 12 13 private void InvokeService() 14 { 15 ThreadPool.QueueUserWorkItem(p => 16 { 17 IList<string> clientNames = GetClientNames(); 18 foreach (string clientName in clientNames) 19 { 20 InvokeTestMethods(clientName); 21 } 22 }); 23 } 24 25 private void InvokeTestMethods(string clientName) 26 { 27 Thread thread = new Thread(p => 28 { 29 Stopwatch stopwatch = new Stopwatch(); 30 stopwatch.Start(); 31 string connectionName = clientName; 32 client.GetSystemMessageForList(clientName); 33 stopwatch.Stop(); 34 int threadID = Thread.CurrentThread.ManagedThreadId; 35 MyAction action = () => this.richDisplayMessage.Text += connectionName + " 连接成功 - " + stopwatch.ElapsedMilliseconds + ". ||ThreadID: " + threadID + Environment.NewLine; 36 this.BeginInvoke(action); 37 }); 38 thread.IsBackground = true; 39 thread.Start(); 40 } 41 }
TimYang | 园豆:12 (初学一级) | 2013-07-01 21:35

@TimYang: 如何开启500个线程的?

dudu | 园豆:30994 (高人七级) | 2013-07-01 21:47

@dudu: 

 

  ThreadPool.QueueUserWorkItem(p =>
{ IList<string> clientNames = GetClientNames(); foreach (string clientName in clientNames) //这边会循环500次 { InvokeTestMethods(clientName); //这个方法就是开启线程,调用WCF服务
} });
就是这样开启线程的。
TimYang | 园豆:12 (初学一级) | 2013-07-01 23:04

@TimYang: 建议先简化一下代码,不进行多线程调用试试

dudu | 园豆:30994 (高人七级) | 2013-07-02 10:10

@dudu: 

 

dudu大哥,今天下午也试过了你开一个线程去调用方法。

调用的时间也是会增长的,但不会增长太多,最短时间为20毫秒,最长的为200毫秒。

是不是我WCF的配置文件有点问题呀?

TimYang | 园豆:12 (初学一级) | 2013-07-02 19:38

@TimYang: 将WCF服务端操作代码注释掉,看看仅仅调WCF耗时多少

dudu | 园豆:30994 (高人七级) | 2013-07-03 10:53

@dudu: 

 

dudu大哥,昨天下午改了一下测试代码,

上一次的测试代码我的客户端实例一直是打开的。

 1         private void InvokeTestMethods(string clientName)
 2         {
 3             Thread thread = new Thread(p =>
 4             {
 5                 Stopwatch stopwatch = new Stopwatch();
 6                 stopwatch.Start();
 7                 string connectionName = clientName;
 8                 JsonOperationClient testClient = new JsonOperationClient(); //线程每次调用都创建一个客户端实例
 9                 testClient.Open(); //打开
10                 testClient.GetSystemMessageForList(clientName);
11                 stopwatch.Stop();
12                 testClient.Close(); //关闭
13                 int threadID = Thread.CurrentThread.ManagedThreadId;
14                 MyAction action = () => this.richDisplayMessage.Text += connectionName + " 连接成功 - " + stopwatch.ElapsedMilliseconds + ". ||ThreadID: " + threadID + Environment.NewLine;
15                 this.BeginInvoke(action);
16             });
17             thread.IsBackground = true;
18             thread.Start();
19         }

这样测试下来,发现比第一次的性能更好一点,有提高30%左右。

 

你说把服务端的操作代码都注释掉,我也试过了,直接返回string.empty.

500个客户端同时调用同一个方法,发现耗时都在10毫秒以下。

 

如果不注释操作代码,返回值的字符串长度是6万。

TimYang | 园豆:12 (初学一级) | 2013-07-04 09:40

@TimYang: 性能瓶颈不在WCF,在你的服务端处理代码

dudu | 园豆:30994 (高人七级) | 2013-07-04 09:47

@dudu: 

服务端代码可以肯定执行速度很快,就是把数据返回给客户端的时候慢了很多。

我一开始想使用字符串压缩的方法,可是试了几次都没成功。

dudu大哥有什么建议吗?

TimYang | 园豆:12 (初学一级) | 2013-07-04 11:15

@TimYang: 试试启用IIS的动态压缩

dudu | 园豆:30994 (高人七级) | 2013-07-04 11:16

@dudu: 

 

我的WCF服务是寄宿在Winform中的,这样配置有效吗?

TimYang | 园豆:12 (初学一级) | 2013-07-04 12:40

@TimYang: 无效

dudu | 园豆:30994 (高人七级) | 2013-07-04 13:16

@dudu: 

 

还有什么建议吗?dudu哥

TimYang | 园豆:12 (初学一级) | 2013-07-04 15:39

@TimYang: 没有建议了,我只在IIS中跑过WCF

dudu | 园豆:30994 (高人七级) | 2013-07-04 22:14
其他回答(1)
0

问题最后是怎么解决的?

会长 | 园豆:12401 (专家六级) | 2015-08-04 17:32

你现在遇到什么问题了?

我已经不做WCF很多年了

支持(0) 反对(0) TimYang | 园豆:12 (初学一级) | 2015-08-05 19:50

@TimYang: 现在我们项目用的是wcf,而且部署在阿里云上,那叫一个慢(本来是局域网程序,没有过多考虑性能问题,后来由于不可抗拒原因要放在阿里云上),所以就搜索了下这方面的问题,正好看到这个博问,出于好奇就问了下,谢谢回复。

我现在也不知道我们遇到的性能问题主要是什么原因引起的,别的同事正在研究,老板没让我参与,我在忙别的,而且对wcf不是很熟。不过我一旦有空的话也会研究下,可惜不太可能有空了.....

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2015-08-06 09:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册