5

我们将有状态的 DataSnap 服务器用于一些业务逻辑任务,并提供客户端数据集数据。

如果我们必须更新服务器来修改业务规则,我们将新版本复制到一个新的空文件夹并注册它(取决于 Delphi 版本,只需启动或运行 TRegSvr 实用程序)。

即使旧服务器实例正在运行,我们也可以这样做。但是,注册新版本后,所有新的客户端连接仍将使用当前正在运行的(旧)服务器实例。所有客户端都必须先断开连接,然后新服务器将用于下一个客户端。

有没有办法在注册后立即将所有新客户端连接定向到新服务器

(我知道新的或更改的方法签名也需要更改并重新启动客户端,但这个问题是关于不影响界面的内部修改)

我们使用的是 Socket 连接,所有客户端共享同一个服务器应用程序(只打开一个应用程序窗口)。在早期,我们使用了远程数据模块的不同配置,这导致每个客户端有一个应用程序窗口。也许这可能是一个解决方案?(因为每个新客户端都会启动当前注册的可执行文件)

更新:Delphi XE 是否为“热部署”(更新的服务器)提供一些支持?我们目前使用 Delphi 2009,但如果它提供更轻松的“热部署”实施,我们将升级到 XE。

4

6 回答 6

6

您可以将您的应用程序服务器分成 2 个新服务器,一个是一个简单的代理对象,将所有方法(如果有的话还可以包含状态信息)重定向到第二个实际实现您的业务逻辑的对象。如果您决定随时更换业务应用服务器,您还需要在代理服务器中实现“静默重新连接”功能,以免打扰连接的客户端。我自己以前从未做过这样的设计,但希望这个想法很清楚

于 2009-06-09T06:23:05.757 回答
1

这个问题可能没有一个简单的答案,我怀疑您将不得不修改客户端。我能想到的最简单的解决方案是在服务器上设置一个标志(某个通常称为方法的属性或输出参数),客户端会定期检查该标志,告诉客户端断开连接并重新连接(称为 ImBeingRetired 之类的东西)。

在某些情况下也可以为 datasnap 编写回调(尽管我从未这样做过)。这将允许服务器通知客户端它应该重新启动或重新连接。

我能想到的最后一个选项(尚未提到)是使客户端/服务器无状态,以便每次客户端想要连接的东西时,得到它想要的东西然后断开连接。

不幸的是,这些选项都不是您想要的问题的答案,但可能会给您一些想法。

于 2009-06-11T04:17:04.023 回答
1

您是否尝试过重命名当前服务器并将新服务器以正确的名称放在相同的位置(而不是更改注册表位置)。我之前成功地为 COM 库做过这个。我不确定它是否适用于远程启动规则,因为它可能会寻找一个现有的实例来连接,而不是一个全新的服务器。

这可能有点骇人听闻,但您会让客户端调用服务器上的一个方法,指示有更新的版本可用。这将允许它执行任何必要的清理,因此它最终不会同时与现有服务器实例和新服务器实例通信。

于 2009-06-04T11:58:48.370 回答
0
  1. (可选)设置 vmware vSphere、ESX,或查找已有的托管服务。
  2. 将会话变量存储在 db 中。
  3. 准备 2 个具有 2 个不同 IP 地址的网络盒并部署您的东西。
  4. 设置 DNS、防火墙、负载平衡器或 BSD 虚拟机,以便名称“example.com”解析为 Web 框 1。
  5. 将新版本部署到 web box 2。
  6. 使用您选择的任何路由方法切换到 web box 2。
  7. 如果一切正常,将新版本部署到 web box 1。

使用 DNS 可能是最简单的,但是映射传播到客户端需要时间(如果客户端在您的 LAN 之外),并且两个客户端可能会看到不同的结果。一些防火墙具有 IP 地址映射功能,您可以映射公共 IP 地址和内部 IP 地址。理想的方法是使用负载均衡器并将其配置为 50:50,并在您想要升级时将其更改为 100:0,但它需要花钱。一种更便宜的替代方法是在 BSD vm 上运行软件负载平衡器,但它可能需要一些工作。

编辑:我的意思是会话变量,而不是会话。你说服务器是有状态的。如果它包含一些使用会话变量的业务逻辑,则需要将其存储在外部,以便在切换期间在重新连接时保留。实际的 DataSnap 会话将丢失,因此当您在升级过程中关闭 web box 1 时,客户端将收到 web box 1 的“Session {some-uuid} is not found”错误,它将重新连接到 web box 2。您也可以使用 3 个 IP 地址(1 个公共和 2 个私有),因此客户端总是看到 1 个地址,这是更好的方法。

于 2009-06-07T16:18:08.817 回答
0

我通过拥有一个保存我的“数据版本”的特定表来做了类似的事情。每次我更新服务器或更改系统范围的全局设置时,我都会增加这个字段。当客户端启动时,它总是检查这个值,并在任何事务/查询之前再次检查。如果该值与我刚开始时的值不同,那么我需要通过我的重新初始化逻辑,这可以很容易地包括重新登录到更新的服务器。

我正在使用 IIS 发布我的应用服务器,因此会更改的数据将是应用服务器的路径。我保留了旧的可用,以响应任何正在进行的现有交易。最终,一旦我知道该版本不再有客户端连接,这些将被删除。

如果您记录客户端上次连接的服务器(因此会知道),您可以轻松地知道要保留哪些版本。

于 2010-10-25T16:07:07.403 回答
0

对于较新的版本(Delphi 2010 及更高版本),有一个有趣的解决方案

  • 对于使用 HTTP 传输的系统:

在 DataSnap 2010 中实现故障转移和负载平衡 作者 Andreano Lanusse

  • 以及 TCP/IP 传输的相关问题:

如何将 DataSnap 客户端连接定向到各种 DS 服务器?

于 2012-08-06T16:05:18.273 回答