【问题标题】:SOA/Web Service PaginationSOA/Web 服务分页
【发布时间】:2010-06-22 14:42:30
【问题描述】:

在 SOA 中,我们不应该在客户端和服务器之间建立或保持状态(或设计依赖关系)。这是可以理解的。但是,如果客户端想要使用可能返回开放式“行”数的实时服务,可以遵循哪些模式?

Web 应用程序,类似于 SOA,但允许状态(会话)已通过分页解决了这个问题。分页要求(在大多数情况下,尤其是使用 SQL)服务器保存数据并且客户端以块的形式请求数据。

如果我们在哪里考虑 Web 服务的类似分页的场景,这些遵循哪些模式仍将允许遵循(或尽可能接近)SOA 的原则。

思想家的一些规则: 1) 由 SQL 数据库支持(因此在选择集中没有行号的概念) 2)在分页期间不要跳过一行或重复一组中的一行很重要 3) 其他客户端可以随时向数据库中插入和删除数据 4) 无需将数据集视为实时(可更新)数据集

就我个人而言,我认为上面的 1 和 2 已经通过将解决方案空间与需求限制在一起来拼写我们的解决方案。

我提出的解决方案是将数据(尽可能多地选择)存储在只读存储/缓存中,可以在结果集中为其分配一个行号,并允许在此数据快照上进行分页。我将拥有存储快照的基础设施(服务器、外部缓存、memcached 或 ehcache - 这必须非常大)。此类查询的结果将是快照 ID,客户端可以使用快照 API(Web 服务)和快照 ID 从快照中检索数据。在 x 是合理的时候,结果将以只读、只转发的方式处理 x 记录。

我们将不胜感激相互竞争的想法和想法、批评或赞誉。

【问题讨论】:

标签: web-services session pagination soa


【解决方案1】:

Web Service 中的分页结果实际上很容易实现。

您所要做的就是向 Web 服务调用添加两个参数:页面大小、页码。

页面大小是要包含在页面中的结果数。页码是您要查找的结果的页码。

然后,您的网络服务会返回数据库(或缓存),检索结果,确定哪些结果适合所请求的页面,然后仅返回这些结果。

然后,客户端必须对他们希望从服务获得的结果的每页发出一个请求。

【讨论】:

  • 谢谢 - 但不符合要求。回到数据库并不能提供一致的结果,可以在调用之间添加、删除或更改数据,这使得一致性变得困难。您可以通过这种方式跳过行,因为上面已删除数据。如果排序标准不是唯一的,您也无法保证顺序。请记住,我正在寻找一种我可以在全球范围内应用的模式来解决这些问题。不错的尝试。
【解决方案2】:

您对 memcached 提出的建议也适用于缓存表。第一个服务调用将 (1) 将结果插入到具有快照 ID 的缓存表中 (2) 从缓存表中返回第一页和快照 ID。后续调用将通过使用快照 ID 查询缓存表,根据页面大小和页码返回页面。

我认为这也可以通过使用内存缓存表来优化,但这取决于您的数据库是否支持从磁盘表到内存表的 INSERT-INTO。不过,这在集群环境中可能会变得复杂。

如果您在请求之间保留特定于客户端的副本,无论存储在会话对象、数据库表还是 memcached 数据存储中,这种缓存本质上都是有状态的。但是,鉴于这些要求,您别无选择,只能以某种形式缓存结果,除非您有可能将已删除或不再相关的记录作为合法结果返回。

【讨论】:

    【解决方案3】:

    SOA 不适用于此类低级功能。

    SOA 旨在将业务领域粘合在一起,而不是前端到后端。并不是因为您的应用程序使用 Web 服务与后端对话,您就有了一个“SOA”应用程序。这是没有意义的,因为 SOA 在 1 个独立系统的上下文中毫无意义。

    从这个角度来看,很明显,在 SOA 中,调用者不应该知道您正在分页的 SQL 表,这是 SOA 应该隐藏的实现细节。另一方面,服务器不应该知道客户端的状态,因为它应该不知道客户端的细节,才能真正开放。

    所以,请理解分页不是 SOA。随心所欲,只需了解您用于分页的 Web 服务是应用程序的内部工件,而不是用于 SOA 总线中的外部客户端。还要记住,它不能与服务器中的 out 状态保持事务一致。问题可能是应用程序的 UI 和 SOA 总线只有一个服务层,需要将它们分开。

    在 SOA 总线中使用这个 web 服务会很糟糕。当用户分页和其他应用程序挂在它上面时,我无法保持一致,它们会与特定的 SQL 绑定。

    ...那么您不妨授予对表的直接 SQL 访问权限。

    SOA 用于系统之间的业务消息,而不是将应用程序的前端粘合到后端。

    【讨论】:

    【解决方案4】:

    同样的问题,使用 Navision 方法解决。

    $ws->getList($first_record_id, $limit)
    

    这会返回一个从传递的 id 开始的 $limit 元素的页面

    select * from collection where collection.id > $first_record_id ASC limit $limit
    

    按 id ASC 排序

    Navision 使用 Key(每个元素都有一个键),但在 MySQL 中使用自动增量 id 更好。

    在这种情况下,分页用于处理大型结果集,而不是用于前端分页...

    【讨论】:

      【解决方案5】:

      我不确定 SOA 是否值得关注。您遇到的问题似乎与您的 API 分页有关。我将向您指出 twitter 如何处理他们的分页 dev.twitter.com/rest/public/timelines

      【讨论】:

        猜你喜欢
        • 2012-12-26
        • 1970-01-01
        • 2012-06-12
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多