我有一个托管在 IIS 中的 WCF 服务,它是各种第三方 API 的适配器。该服务所做的就是:
- 接受来自 GUI 的同步操作调用
- 向第三方发起同步 Http 请求
- 将结果转换为规范格式
- 返回 GUI
实际上,它花费了大部分等待网络 I/O 来完成的时间。
在保持 GUI 同步界面的同时实现此类服务扩展的最佳模式是什么?我知道对于具有大量 I/O 的 ASP.NET 应用程序,建议使用异步处理程序来释放执行请求的线程。
WCF有什么好的模式吗?
谢谢,
皮奥特尔
I have a WCF service hosted in IIS which is an adapter for various ThirdParty APIs. All this service does is:
- accept a synchronous operation call from GUI
- fire a synchronous Http Request to third party
- convert the result to canonical format
- return to GUI
In practice it spends most of the waiting on network i/o to complete.
What is the best pattern to make such service scale while maintaining synchronous interface for the GUI? I know that for ASP.NET apps that have a lot of i/o it is recommended to use async handlers to free-up the thread executing request.
Is there any good pattern for WCF?
Thanks,
Piotr
发布评论
评论(2)
正如您所描述的,这是一个潜在的可扩展性问题。
ASP.NET 有一个线程池(我上次检查的是 250 个,但可以增加到 1000 个 - 可配置,但不建议超过 1000 个)处理请求。 ASP.NET 中的 HTTP 请求具有线程关联性,因此这些线程和请求之间存在一对一的关系。
当您调用外部服务时,请求线程会一直挂起,如果您用完线程,您的客户端将收到 503 错误。
用于扩展此服务的解决方案通常包括客户端请求启动操作,然后客户端将不断轮询服务以查看是否可以已经完成了。如果您以轻量级且高效的方式实现这些服务,您会损失一点性能,但会获得很大的可扩展性。
您还需要考虑:
As you have described, this is a potential scalability issue.
ASP.NET has a thread pool that (last time I checked was 250 but could increase up to 1000 - configurable but above 1000 not really recommendable) serves requests. HTTP requests in ASP.NET have thread-affinity so there is a one-to-one relationship between these threads and requests.
When you call externals services, requests thread keeps hanging and if you run out of threads, your client will receive a 503 error.
Solution for scaling this service would normally include a request by the client to start the operation and then client would continuously poll the service to see if it has finished. If you implement these services as light-weight and efficient, you lose a bit of performance but gain so much scalability.
You would also need to think about:
我遇到过这个“AsyncPattern”,这可能是这个问题的解决方案(http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.asyncpattern.aspx)
我看起来像是一种“释放”服务线程的方法,而它正在等待 I/O 完成。同时,它从调用者的角度保留了操作的同步性质(即,这是严格的服务端实现细节)。缺点似乎是服务端的代码复杂性:所有外部调用都必须使用 Begin/End API。
一些有用的链接:
“OperationContractAttribute”的“AsyncPattern”属性有什么用“+wcf?
WCF - AsyncPattern 性能
http://blogs.msdn.com/b/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx
I have come across this "AsyncPattern" which may be the solution to this problem (http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.asyncpattern.aspx)
I looks like a way to “free-up” the service thread while it’s waiting on the I/O to be completed.At the same time it preserves the synchronous nature of the operation from the caller perspective (i.e. this is strictly service side implementation detail). The disadvantage appears to be code complexity on the service side: all the external call’outs must use Begin/End API.
Some useful links:
What is the use of "AsyncPattern" property of "OperationContractAttribute" + wcf?
WCF - AsyncPattern Performance
http://blogs.msdn.com/b/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx