【问题标题】:WCF: Per-Call and Per-Session services...need convincing that Per-Call is worthwhileWCF:Per-Call 和 Per-Session 服务...需要说服 Per-Call 是值得的
【发布时间】:2010-03-30 02:05:22
【问题描述】:

我们目前正在审查我们的 WCF 服务设计,令我困扰的一件事是在 Per-Call 和 Per-Session 服务之间做出决定。我相信我理解这两者背后的概念,但我并没有真正看到 Per-Call 服务的优势。我了解使用 Per-Call 服务的动机是 WCF 服务仅在调用期间保存一个服务器对象,从而限制了服务实例持有昂贵资源的时间,但对我来说它更易于使用更类似于 OO 的 Per-Session 模型,其中您的代理对象实例始终对应于同一个服务器对象实例,并且只需手动处理任何昂贵的资源。

例如,假设我有一个带有添加、更新、删除、选择方法的 CRUD 服务。这可以通过在服务器对象构造函数中实例化的数据库连接(“昂贵的资源”)作为 Per-Call 服务来完成。或者,它可以是一个 Per-Session 服务,在每个公开的 CRUD 方法中实例化并关闭一个数据库连接。

对我来说,这在资源方面并没有什么不同,它使编程模型更简单,因为客户端可以确保他们的代理始终具有相同的服务器对象:调用之间可能存在的任何廉价状态都得到维护,并且当服务再次实例化一个新的服务器对象时(如 Per-Call 的情况),方法上不需要额外的参数来识别服务必须检索哪些状态数据。就像使用类和对象一样,同样存在资源管理问题,但我们不会为对象上的每个方法调用创建新的对象实例!

那么我在 Per-Call 模型中缺少什么?

谢谢

【问题讨论】:

    标签: wcf


    【解决方案1】:

    PerCall 或 PerSession 没有对错之分,只是长处和短处不同。您似乎从面向对象的角度接近 PerSession 是一个自然的契合。典型的 SOA 方法是 PerCall 方法。

    在所有条件相同的情况下,权衡是性能与可扩展性。 PerSession 应该执行得更好,因为该对象不必在后续请求中实例化。 PerCall 应该可以更好地扩展,因为在服务器上实例化的唯一对象正在执行实际工作。这不仅仅是“昂贵”的资源,而是服务器上打开的所有会话。例如在 PerSession 情况下,您可能在服务器上实例化了 1000 个对象,但任何时候实际上只有 100 个对象处于调用状态。但是,在 PerCall 情况下,对于 100 次调用,只会实例化 100 个对象。实例化的 PerSession 对象可能会浪费资源,并且可能会影响在负载下处理请求的能力。

    如果我的服务是公开的,我也不希望我的对象生命周期受服务消费者一时兴起;我会担心我的服务可能会被恶意或错误代码取消。

    PerCall 方法的另一个潜在好处是系统可用性。回到前面的示例,如果 PerSession 服务器崩溃,那么在该服务器上拥有会话的所有 1000 个客户端都将丢失会话并且无法完成他们的工作。在 PerCall 情况下,唯一会发生的错误是正在进行的 100 个实际请求(假设快速故障转移)。其他 900 个客户端可以在下次调用时被路由到另一台服务器。这对于 SLA 来说可能很重要。

    【讨论】:

      【解决方案2】:

      简而言之,答案将是无状态和可扩展性。

      如果您知道服务将如何被使用的环境,并且您可以共享资源,那么每个会话就可以很好地工作,这使服务有状态。当您需要引入故障安全服务器、负载平衡和路由服务调用时,会话服务将出现问题,因为调用并不总是解析到同一个服务对象。此外,如果服务被客户端使用而工作流不固定,那么您如何知道何时释放该会话的服务对象?大多数时候您依赖租约超时,但在重负载环境中,这本身也会产生问题,即在内存中创建对象并只是空闲。

      在设计方面,让服务调用相互独立也是一种很好的做法。所以你不依赖以前的服务调用来设置对象的状态。

      【讨论】:

      • 我对负载平衡和路由了解不多,但在不知道您的客户如何使用您的代理的情况下,我同样的论点适用:编码您的服务器对象不要占用昂贵的资源,所以那么客户端是否关闭代理也没关系。此外,它似乎与我在 Juval Lowys WCF 书中读到的内容不一致,其中指出“如果 Per-Call 服务真的是无状态的,那么首先就不需要 Per-Call。这是因为服务已声明您需要 Per-Call 模式。”除了负载平衡/路由,我仍然看不出有什么不同。
      • 这种区别在可扩展性上更加突出,但如果这些不是考虑因素,那么我同意你上面的评论。在负载较重的服务器上,假设您的服务在 5 分钟内从不同的客户端调用 10k 次,在每个会话配置中,主机将需要保持这个 10k 会话对象处于活动状态并为其租用状态池化。这显然会对服务器的内存和性能产生开销。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多