最近在调优SliverLightweb程序,两个下手点:wcf调用方式优化;iis并发访问优化
来源:互联网 发布:mac图片编辑大小 编辑:程序博客网 时间:2024/06/07 05:18
把同事总结的一份wcf调用方式记录下来,感谢同事的总结与分享
XXX系统的silverlight项目中,一般会出现当两个页面同时想wcf发送请求时(比如查询),数据会按照请求顺序一个一个返回,不管第二个请求查询数据有多快,也会等到第一个请求数据返回后才返回,影响了项目的性能。
经调查,这与wcf的并发和实例有关系,得到如下结论:
调查结果:如下
1. 为什么会出现请求按顺序返回结果的现象?
因为我们的项目用的wcf并发模式是个单线程的模式,即某时刻只能有一个线程调用服务实例,其余的线程处于等待队列中。但是当某线程回调客户端操作时,该线程就不再锁定该服务实例,等待队列中的下个线程将锁定服务实例进行调用。当回调客户端的线程执行完客户端调用后再回到服务端时,它将进入线程等待队列中重新排队等待。
通俗的讲:当客户端三次请求(A,B,C)到达服务端后,A请求将锁定服务实例,并调用服务,B请求和C请求将在等待队列中排队。在A请求处理过程中进行回调时,A请求会暂时释放对服务实例的锁定,此时队列中的B请求会锁定服务,进行调用。当B请求处理回调时,B请求也会暂时释入服务实例锁定,此时C请求会锁定服务进行调用......。当A回调结束后会重入服务实例,并在等待队列的尾部排队等待后续处理。
2. 如何解决这个现象?
经调查,发现WCF有两种控制并发的行为: InstanceContextMode 和 oncurrencyMode。
具体为:
InstanceContextMode服务行为用来控制实例而且可以设置成以下三种值:
Single. 服务类的一个实例处理所有接收到的请求。这实现了一个单例。
PerCall. 为每个接收到的请求创建一个服务类的实例。
PerSession. 每个客户端会话创建一个服务类实例。当使用不支持会话的信道时,所有的服务调用与PerCall一样,即便是InstanceContextMode被设置成PerSession.。
ConcurrencyMode服务行为用来控制一个服务实例内部的线程并发。默认设置,ConcurrencyMode.Single,指导WCF在某一时刻旨在服务类的实例中执行一个线程。这个行为可以被设置成三个值之一:
Single. 在一个时刻只有一个线程可以访问服务类。这是最安全的设置因为服务操作不必担心线程安全。
Reentrant. 在一个时刻仅有一个线程可以访问服务类,但是这个线程可以离开类并在稍后返回继续。
Multiple. 多个线程可以同步访问服务类。这个设置要求类创建在线程安全基础上。
默认的情况下是,两者的行为的默认选择分别是:PerSession和Single,这样就形成了“请求-响应”的调用模式,造成数据阻塞,所以我们修改这两个行为相互配合:
InstanceContextMode
ConcurrencyMode
Single
PerCall
PerSession
Single默认
服务是单例:一个实例被创建来处理请求,当一个请求呗处理时,所有的顺序请求被加入队列并按照fifo(先进先出)处理。
属于最基本的wcf请求模式,不能解决问题
每次调用都创建一个实例。并发请求没有影响,因为每个实例都有它自己线程来执行。
优点可以解决问题,但每次请求都创建一个实例,相当于new一个服务对象,如果服务的构造函数有数据加载或复杂操作,会影响性能
每个客户端会话创建一个实例,而且仅有一个线程被创建来处理那个会话的请求,如果客户端再一次会话上使用多个异步调用,它们会被放入列并按照(fifo)顺序处理。
通俗理解就是多次请求,请求还是会阻塞,是项目使用的默认模式,不能解决问题。但这是针对会话来说,项目中使用的basicHttpBinding不支持会话,会降级为PerCall,和PerCall行为一样
Reentrant
服务是单例:一个实例被创建而且仅有一个现成被创建来处理请求,当一个请求被处理后,所有的请求按顺序被放入队列中并按照fifo顺序处理。
感觉这个跟ConcurrencyMode的single是一样的,不能解决问题
每次调用都创建一个实例。并发请求没有影响,因为每个实例都有它自己线程来执行。
优点可以解决问题,但每次请求都创建一个实例,相当于new一个服务对象,如果服务的构造函数有数据加载或复杂操作,会影响性能
同上。
每个客户端会话创建一个实例,而且仅有一个线程被创建来处理那个会话的请求,如果客户端再一次会话上使用多次异步调用,它们会被放入列并按照(fifo)顺序处理。单个线程可以离开这个方法,做其他工作,稍后返回,就像服务端异步编码。
通俗理解就是多次请求,请求还是会阻塞,不能解决问题,即使服务端有异步编码,但还是一个线程处理。并且这是针对会话来说,项目中使用的basicHttpBinding不支持会话,会降级为PerCall,和PerCall行为一样
Multiple
一个实例被创建但是多个线程可以再这个实例中并行执行。类的成员必须用同步代码保护,应为同样的成员可以被多个线程修改。
这个可以解决问题,并且是这几种配合中感觉比较好的但会遇到多线程的通病,需要做类成员保护,在项目中这点修改的点可能会多。
每次调用都创建一个实例。并发请求没有影响,因为每个实例都有它自己线程来执行。
优点可以解决问题,但每次请求都创建一个实例,相当于new一个服务对象,如果服务的构造函数有数据加载或复杂操作,会影响性能
同上。
每个客户端会话创建一个实例,有多个线程可以再实例中并发执行。如果客户端在一个会话总进行多次异步调用,它们是并行的,不会影响。类的成员必须用同步代码保护,因为同样的成员可以被多个线程修改。
这个是可以解决问题的,同Single差不多,但需要做类成员保护。并且这是针对会话来说,项目中使用的basicHttpBinding不支持会话,会降级为PerCall,和PerCall行为一样
从图中可以看出:当InstanceContextMode设成PerCall时,可以解决问题,但每次请求都实例化服务,影响性能。
当InstanceContextMode设成PerSession时,按项目中basicHttpBinding的使用,应该会降级成PerCall,但没有PerCall的效果。
当ConcurrencyMode设成Multiple时,服务器用多线程处理请求,可以解决问题,但要做好代码的线程保护。
推荐: ConcurrencyMode用Multiple,InstanceContextMode用Single
3. 使用方式
在服务的类前写如上的行为契约。
4. 总结
使用推荐的行为方式可以解决请求阻塞的问题,但经测试当客户端向服务发两个或多个并发请求时,响应时间或多或少都会受到影响,增加了查询时间,不可避免的发生了。
- 最近在调优SliverLightweb程序,两个下手点:wcf调用方式优化;iis并发访问优化
- Nginx并发访问优化
- IIS基本性能优化方式
- erlang程序优化点
- Android程序优化点
- IIS并发连接数及性能优化
- IIS并发连接数及性能优化
- IIS并发连接数及性能优化
- IIS并发连接数及性能优化
- ICP迭代最近点优化
- 优化IIS
- iis 优化
- iis 优化
- IIS优化
- IIS优化
- IIS优化-解决IIS访问速度慢问题
- IIS Host 的WCF大数据量大并发调用的时候IIS返回403错误
- Cocos2d-x优化中多线程并发访问
- Beetle在Tcp通讯中使用Protobuf
- 【Linux基础】面向对象程序设计的特点
- wince录音实现
- Unix vs. Linux vs. BSD
- TCP状态转换图详解
- 最近在调优SliverLightweb程序,两个下手点:wcf调用方式优化;iis并发访问优化
- 数组资源(arrays)的使用
- 客户端网络
- java的锁机制
- weblogic8.1上axis1.4客户端调用问题
- 程序员转产品经理的思考
- 以流动形式读取工程中的文件到properties文件中实例
- 超级好用的url 汉字编码函数
- 如何成为一个黑客