6

决定使用 PerSession 还是 PerCall 的一般经验法则是什么?

我有一个稍微重(我认为..)的 WCF 服务,其中包含大约 80 个表的 CRUD 方法。

我已将 WCF 服务分为 1 项服务中的 7 个合同(即 1 项服务中的 7 个端点),以便每个合同都处理自己的域,例如我有一个销售合同,因此所有与销售相关的表及其相应的操作在销售“有界上下文”内

所以我的 WCF 服务结构看起来像这样:

public partial class ABCService : ISalesService
{
   //CRUD methods of all tables related to Sales
}

public partial class ABCService : IMarketingService
{
    //CRUD methods of all tables related to Marketing
}

public partial class ABCService : ICustomerService
{
    //CRUD methods of all tables related to Customer
}

public partial class ABCService : IProductService
{
    //CRUD methods of all tables related to Products
}

我对 PerCall 的担忧是,因为我有一个相当大的 DB/WCF 服务,我担心每次调用所消耗的资源量乘以用户数量和他们调用服务的速率,将是太棒了。

我不知道细节,但我读过创建通道代理是昂贵的操作。

哦,我使用手动编码的代理而不是 VS 的添加服务引用来使用我的 WCF 服务。

所以,我的问题是,我应该使用哪个?PerSession 还是 PerCall?

更新:

  1. 我不需要在通话之间维护状态。
  2. 我正在使用 NetTCP 绑定
4

2 回答 2

19

在我看来,做决定要考虑这两点

  1. 用于InstanceContextMode.PerSession- 如果您的用户在服务器上的 WCF 服务上存储了一些会话值。
  2. 用于InstanceContextMode.PerCall- 如果您的用户在服务器上的 WCF 服务的会话中没有存储任何内容,即 WCF 服务需要没有存储在内存中的每个用户设置。需要可扩展性。

关于When-And-Why的一些要点,

InstanceContextMode.PerCall

  • 如果您的服务是无状态且可扩展的,即好处类似于 HTTP,因为它也是无状态的。
  • 如果服务具有轻量级初始化代码(或根本没有)。
  • 如果您的服务是单线程的。
  • 示例场景:对于给定时间段内的任何 1000 个客户端请求,对于 100 个活动调用PerCall,将只有 100 个对象实例化。其次,如果服务器崩溃,那么在这种情况下,唯一会发生的错误将是正在进行的 100 个实际请求(假设快速故障转移)。其他 900 个客户端可以在下次调用时被路由到另一台服务器。PerCall

InstanceContextMode.PerSession

  • 如果您的服务必须在来自同一客户端的调用之间保持某种状态。
  • 如果您的服务具有轻量级初始化代码(或根本没有)。即使您只为每个客户端代理获取一个新实例,您仍然需要小心在构造函数中包含昂贵的初始化代码。
  • 示例场景:对于给定时间段内的任何 1000 个客户端请求,PerSession您可能在服务器上实例化了 1000 个对象,但在任何时候实际上只有 100 个对象在调用中处于活动状态。因此,实例化PerSession的对象可能会浪费资源,并且可能会影响在负载下服务请求的能力。其次,如果服务器崩溃,那么在PerSession该服务器上有会话的所有 1000 个客户端都将丢失会话并且无法完成他们的工作。

参考链接:

  1. MSDN - WCF 实例化、并发和限制
  2. SO - 每个呼叫与每个会话
  3. MSDN - 在 WCF 上下文中使用会话
于 2013-02-27T06:24:37.203 回答
1

您在网上看不到此类问题的很多答案的原因是它取决于。我要做的是尝试一下——然后在您托管服务的服务器上打开 perfmon 并为您的服务添加计数器。如果您不熟悉,只需 google wcf 性能管理器计数器。

好消息是 WCF 使更改设置变得非常容易。

如果您关心在客户端实例化代理的成本,请记住 perCall 是一种服务行为,而不是客户端行为。即使您将服务实例上下文设置为 PerCall,您仍然可以创建代理的一个实例并从该代理进行一堆方法调用。所有 perCall 的意思是,当您进行调用时,会创建一个服务实例,调用您的方法,然后再次拆除该服务实例。如果您没有对服务实例进行任何昂贵的初始化(即,如果它们基本上是静态方法),那么每次调用都可以。

于 2013-02-27T05:55:31.593 回答