如何在数据库绑定的应用程序之间进行有效的通信?

Posted

技术标签:

【中文标题】如何在数据库绑定的应用程序之间进行有效的通信?【英文标题】:How to effectively communicate between database bound applications? 【发布时间】:2012-06-14 18:07:46 【问题描述】:

我们有许多不同的老式客户端-服务器 C# WinForm 客户端应用程序,它们本质上是数据库的前端。然后有一个 C# 服务器端 Windows 服务等待客户端应用程序提交订单,然后处理它们。

服务器端服务确定是否有工作要做的方式是轮询数据库。多年来,由于无数的业务规则,轮询等待订单的逻辑变得更加复杂。因此,即使无事可做,轮询存储过程本身也会使用相当多的 SQL Server 资源。再加上订单在提交的那一刻就被处理的要求,并且您遇到了性能问题,因为数据库正在不断地被轮询。

该设置现在实际上运行良好,但负载即将通过屋顶,很明显,它无法承受。

在一堆不同的客户端应用程序和服务器端 Windows 服务之间进行通信的有效方法有哪些,它们比当前方法更具前瞻性?

数据库服务器是 SQL Server 2005。如果真的需要,我可能有能力购买最新的 SQL Server,但我宁愿不参加这场战斗。

【问题讨论】:

是否必须通过数据库进行通信,还是客户端可以使用其他方式与服务进行通信? @PanagiotisKanavos 所有选项都摆在桌面上。 我并不是说这是一个好主意,但是从存储过程或触发器调用的 CLR 例程中设置互斥锁可能值得一看。从设计的角度来看,我讨厌它,但它可能会最大限度地减少客户端的更改,并允许您在切换之前很好地测试通知。 【参考方案1】:

您可以通过多种方式通知客户。

您可以使用像NServiceBus 这样的现成解决方案,将信息从服务器发布到客户端或其他服务器。 NServiceBus 使用 MSMQ 以一种非常简单且持久的方式将一条消息发布给多个订阅者。 您可以使用 MSMQ 或其他队列产品从服务器发布消息,这些消息将传递给客户端。 您可以在 Windows 服务上托管 WCF 服务,并使用双工通道从每个客户端连接到它。每次发生更改时,服务都会通知相应的客户甚至所有客户。这对代码来说更复杂,但也更灵活。您可能可以将足够的信息发回给客户,让他们根本不需要轮询数据库。 您可以让服务向所有客户端广播一个 UDP 数据包,以通知他们需要提取的更改。您可能可以在数据包中添加足够的信息,以允许客户端决定是否需要从服务器提取数据。这对于服务器和网络来说是非常轻量级的,但它假定所有客户端都在同一个 LAN 中。

【讨论】:

【参考方案2】:

也许您可以利用SqlDependency 仅在数据实际更改时接收通知。

【讨论】:

【参考方案3】:

您可以使用任何消息传递中间件(如 MSMQ、JMS 或 TIBCO)在您的客户端和服务之间进行通信。

【讨论】:

【参考方案4】:

到目前为止,最简单、最可能也是最便宜的答案就是购买更大的服务器。

除此之外,您的开发工作极有可能在早期失败。我所说的失败并不是说你最终会刮掉你最终构建的任何东西。相反,我的意思是您在调试无数业务规则时启动更改,订单将被搞砸。

坦率地说,我不会考虑在压力下进行沟通变革;假设您关于短期内负载“穿过屋顶”的说法。

如果您的风险敞口必须在第一天 100% 正常运行(当您预计订单会大量增加时,这很正常),并且没有任何问题,那么只需升级数据库服务器即可。哎呀,我 不会 甚至在它上面安装最新的 sql server。相反,只需购买一台更大的机器,安装完全相同的操作系统和数据库服务器(以及补丁级别)并移动您的数据库。

然后查看您的架构,以确定哪些需要消除,哪些可以挽救。

【讨论】:

我认为这在这种情况下行不通。会有太多的死锁、等待等......因为每个人都会遇到相同的数据。虽然我可能应该试试看会发生什么。【参考方案5】:

如果每个人都连接到 SQL Server,那么还有Service Broker 的选项。与迄今为止推荐的其他消息传递/队列解决方案不同,它完全包含在您的数据库中(无需部署、管理和配置单独的产品),它针对您的备份/恢复和高可用性需求提供单一故事(无需单独的备份对于消息存储,没有单独的 DR/HA,无论您的 DB 解决方案是什么,也是您的消息解决方案),并通过统一的编程 API (SQL)。

即使所有内容都在一个 SQL Server 实例中(即多个 SQL 服务实例之间无需通过网络进行通信),Service Broker 仍然拥有无人能比的王牌:activation。通过激活,您完全无需轮询,因为系统本身会在有事件要处理时启动您的处理代码(将“激活”)。处理代码可以是内部的(T-SQL 过程或 SQLCLR .Net 过程)或外部的(请参阅external activator)。

【讨论】:

以上是关于如何在数据库绑定的应用程序之间进行有效的通信?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何有效地在 Android 手机上的服务器之间发送 JSON 数据?

如何从绑定服务与处理程序进行通信?

如何在以下用例的通知扩展和应用程序之间进行通信?

如何在 Windows 窗体应用程序和网站之间进行通信?

Android:如何在 2 个活动之间进行通信

SAML 中的服务提供者和实际应用程序之间如何/应该如何进行通信?