什么时候不应该使用 Web 服务?

Posted

技术标签:

【中文标题】什么时候不应该使用 Web 服务?【英文标题】:When should a web service not be used? 【发布时间】:2010-09-17 07:22:18 【问题描述】:

使用 Web 服务通常是一种出色的架构方法。而且,随着 .Net 中 WCF 的出现,它变得更好了。

但是,根据我的经验,有些人似乎认为应始终在数据访问层中使用 Web 服务来调用数据库。我不认为 Web 服务是通用的解决方案。

我正在考虑拥有几十个用户的小型 Intranet 应用程序。 Web 应用程序及其 Web 服务部署到一个 Web 服务器,而不是 Web 场。将来不会有另一个 Web 应用程序可以使用这个特定的 Web 服务。在我看来,调用 Web 服务的成本不必要地增加了 Web 服务器的负担。进程间调用会影响性能。维护和调试 Web 应用程序和 Web 服务的代码更加复杂。部署也是如此。我只是没有看到在这里使用网络服务的好处。

可以通过创建两个版本的网络应用程序(有和没有网络服务)来测试这一点,并进行压力测试,但我没有这样做。

您对将 Web 服务用于小型 Web 应用程序有意见吗?在其他情况下 Web 服务不是一个好的架构选择吗?

【问题讨论】:

【参考方案1】:

如果您只是为您的 Intranet 编写一个小型(少于 50 个用户)Web 应用程序,那么 Web 服务似乎有点矫枉过正。特别是如果它的主要功能(提供对许多服务的单点访问)不会被使用。

【讨论】:

小型桌面应用呢?【参考方案2】:

对于小型 Web 应用程序(但您必须问“它会一直保持小规模吗?”),使用 Web 服务、单独的业务层、数据层等等可能是矫枉过正。

在有人开枪之前,我确实同意层与层之间的逻辑分离以及单元测试、持续集成等非常出色。在我目前的角色中,如果没有他们,我会完全迷失并在角落里摇摆不定。然而,对于一个非常小规模的网络应用程序,例如用于跟踪一家拥有 36 名员工的公司的联系电话和地址,成本/收益分析表明,上面列出的所有“优点”都是多余的。

但是...记住要问“它会一直保持小规模吗?”这个问题。 :-)

【讨论】:

Web 服务无助于扩展(尤其是当有状态时,它们可能会在扩展后感到痛苦)——它们有助于集成。 是的,他们可能会很痛苦,但是说他们不能/不能帮助向外扩展是完全错误的。您可以使用它们将业务逻辑模块分配给单独的硬件,以便您的 Web 服务器调用“n”台机器为其工作。举个例子。 当然可以...因为这个,我不会使用它们。还有许多其他的扩展方式,不会强迫您发布严格的接口和 XML 序列化(即消息队列、map-reduce、网格、元组空间)【参考方案3】:

我同意在小型 Web 应用程序中使用 Web 服务会增加一层看起来不合理的复杂性。我的大多数解决方案,互联网和内部网,10-50 个用户,不使用 Web 服务。我很高兴其他人也有同样的感觉……我以为只有我一个人。

【讨论】:

我还以为只有我一个。很高兴知道我们并不孤单。【参考方案4】:

Web 服务对于数据访问来说绝对是一个糟糕的选择。几乎为零的好处是大量的开销和复杂性。

如果您的应用程序要在一台机器上运行,为什么要拒​​绝它执行进程内数据访问调用的能力?我不是在谈论从您的 UI 代码中直接访问数据库,我是在谈论将您的存储库抽象出来,但仍将它们的程序集包含在您正在运行的网站中。

在某些情况下,我会推荐 Web 服务(我假设您的意思是 SOAP),但这主要是为了互操作性。

这里的服务粒度也存在问题。 SOA 意义上的服务将封装操作或业务流程。数据访问方法只是该过程的一部分。

换句话说:

  - someService.SaveOrder(order);  // <-- bad
    // some other code for shipping, charging, emailing, etc

  - someService.FulfillOrder(order);  //<-- better
    //the service encapsulates the entire process

为了Web服务而Web服务是不负责任的编程。

【讨论】:

我完全同意。我公司的主要项目有一个 Web 应用程序与一个 Web 服务与一个持久层通信。除了 webapp,没有其他东西可以访问 web 服务。删除 Web 服务将删除一个没有任何价值的巨大层。任何地方的改变都需要更新 3 个地方!【参考方案5】:

仅仅因为该工具会生成一堆存根并不意味着它是一个很好的用途。 WS-* 在您将服务 暴露给外部各方的情况下表现出色。这意味着每个操作都应该在业务流程的粒度上,而不是在数据访问上。

大量标准可用于详细描述合同的不同方面,(假设的)完全兼容的 WS 堆栈可以消除第三方开发人员的大量痛苦,甚至允许传说中的点击式集成阿拉雅虎管道。通过良好的治理控制,您可以根据需要改进您的公共接口并管理向后兼容性。

所有这些几乎不可能自动生成。 C# 存根生成器只知道类的物理接口,但对所涉及的语义一无所知。更多详细讨论请参见this paper。

如果您正在构建一个网站,那么就构建一个网站。如果您想在应用程序中进行异步消息传递,请使用MSMQ。如果您想向内部客户端公开数据,请使用POX。如果您需要高效的二进制消息格式,请查看 Google 的 Protocol Buffers,或者如果您需要 RPC,请查看 Hessian for C# 或 DCOM。

Web 服务是一种粗粒度的集成解决方案。它们是死板的,它们比替代品慢,它们需要付出太多的努力才能做好(如果做得不好,几乎毫无意义)。

总结一下:“什么时候应该使用网络服务?” - 任何时候你都可以摆脱它

【讨论】:

【参考方案6】:

夏洛特杰出的开发人员 Nick Harrison 提出了以下使用 Web 服务有意义的场景:

在一个 Web 场中,有多个 Web 服务器托管网站,所有网站都指向在另一个 Web 服务器上运行的 Web 服务。这允许将负载分布到多个服务器上。 客户端/服务器,Windows 窗体应用程序可以在其中调用 Web 服务。 跨平台 穿过防火墙

【讨论】:

第二种情况太笼统了。有这样的案例解释了使用 Web 服务而不是库是开销的问题,并且缺点超重。【参考方案7】:

对于小型 Web 应用程序,我认为使用 Web 服务通常是一个不错的主意,您可以使用它轻松地将 Web 服务器与数据层分离。有了直截了当的开发要求和出色的工具,我看不出问题所在。

但是不要在以下情况下使用网络服务:

当您必须使用 Http 作为数据的传输和 Xml 序列化时,您需要大量不同位的数据,同步且经常。无论是 REST、SOAP 还是 WS-*,您都会遇到性能问题。您拨打的电话越多,您的系统就会越慢。如果您希望不那么频繁地异步获取中等大小的数据块,并且可以使用直接 TcpIp(例如 Wcf netTcpBinding),您会更好。 当您需要从您的 Web 服务中查询数据并将数据与其他数据源相结合时,请考虑构建一个数据仓库,该数据仓库可以填充来自整个企业的经过适当整合和合理化的数据

这是我的经验,希望对你有帮助。

【讨论】:

以上是关于什么时候不应该使用 Web 服务?的主要内容,如果未能解决你的问题,请参考以下文章

Spring 啥时候使用服务或组件? [复制]

什么时候应该使用 Docker,什么时候应该使用虚拟机? [复制]

移动端页面应该使用什么字体?

网络安全Web安全渗透测试笔试题

为啥在 Web 服务中使用 complexType?

什么时候应该使用 Localize 控件而不是 Literal?