我们将状态DataSnap服务器用于某些业务逻辑任务,并提供clientdataset数据。
如果我们必须更新服务器以修改业务规则,我们将新版本复制到一个新的空文件夹并注册它(取决于Delphi版本,只需启动或运行TRegSvr实用程序)。
即使旧的服务器实例正在运行,我们也可以这样做。但是,注册新版本后,所有新客户端连接仍将使用当前运行的(旧)服务器实例。所有客户端必须先断开连接,然后新服务器将用于下一个客户端。
注册后是否有办法将所有新客户端连接指向新服务器?
(我知道新的或更改过的方法签名也需要更改并重新启动客户端,但这个问题是关于不影响界面的内部修改)
我们正在使用Socket连接,并且所有客户端共享相同的服务器应用程序(只打开一个应用程序窗口)。在早期,我们使用了远程数据模块的不同配置,这导致每个客户端有一个应用程序窗口。也许这可能是一个解决方案? (因为每个新客户端都会启动当前注册的可执行文件)
更新:Delphi XE是否为“热部署”(更新服务器)提供了一些支持?我们目前使用Delphi 2009,但如果它更容易实现“热部署”,则会升级到XE。
答案 0 :(得分:6)
您可以将您的appserver分成2个新服务器,一个是简单的代理对象,将所有方法(以及可选的包含状态信息)重定向到实际实现业务逻辑的第二个。您还需要在代理服务器中实现“静默重新连接”功能,以便在您决定随时更换业务应用服务器时不会干扰已连接的客户端。从来没有做过这样的设计,但希望这个想法很清楚
答案 1 :(得分:1)
您是否尝试重命名当前服务器并将新服务器放在具有正确名称的相同位置(而不是更改注册表位置)。在成功之前,我已经为COM库做了这个。我不确定它是否适用于远程启动规则,因为它可能会寻找要连接的现有实例而不是完全新鲜的服务器。
可能有点hackish但你会让客户端在服务器上调用一个方法来指示新版本可用。这将允许它执行任何必要的清理,因此它不会同时与现有服务器实例和新服务器实例通信。
答案 2 :(得分:1)
这个问题可能没有一个简单的答案,我怀疑你必须修改客户端。我能想到的最简单的解决方案是在服务器上有一个标志(一个通常称为方法的属性或out参数),客户端定期检查它,告诉客户端断开连接并重新连接(称为ImBeingRetired)。
在某些情况下也可以为datasnap编写回调(尽管我从未这样做过)。这将允许服务器通知客户端它应该重新启动或重新连接。
我能想到的最后一个选项(尚未提及)将使客户端/服务器无状态,以便每次客户端想要连接的东西时,获得它想要的东西然后断开连接。
不幸的是,这些选项都不是您想要回答的问题,但可能会给您一些想法。
答案 3 :(得分:0)
使用DNS可能是最简单的,但是映射传播到客户端需要时间(如果客户端在LAN之外),并且两个客户端可能会看到不同的结果。有些防火墙具有IP地址映射功能,可以映射公共IP地址和内部IP地址。理想的方法是使用负载均衡器并将其配置为50:50并在需要升级时将其更改为100:0,但这需要花钱。更便宜的替代方案是在BSD vm上运行软件负载均衡器,但它可能需要一些工作。
编辑:我想说的是会话变量,而不是会话。你说服务器是有状态的。如果它包含一些使用会话变量的业务逻辑,则需要在外部存储以在切换期间通过重新连接保留。实际的DataSnap会话将丢失,因此当您在升级期间关闭Web框1时,客户端将通过Web框1获得“找不到会话{some-uuid}”错误,并且它将重新连接到Web框2。 你也可以使用3个IP地址(1个公共地址和2个私有地址),这样客户端总能看到1个地址,这是更好的方法。
答案 4 :(得分:0)
我通过拥有一个特定的表来保存我的“数据版本”,做了类似的事情。每次我更新服务器或更改系统范围的全局设置时,我都会增加此字段。当客户端启动时,它始终检查此值,并在任何事务/查询之前再次检查。如果该值与我刚开始时的值不同,那么我需要完成我的重新初始化逻辑,这很容易包括重新登录到更新的服务器。
我使用IIS发布我的应用服务器,因此更改的数据将是应用服务器的路径。我保留旧的,以回应任何现有的交易。一旦我知道没有更多客户端连接到该版本,这些将被删除。
如果您记录客户端最后连接的服务器(因此可以了解),您可以轻松地知道要保留哪些版本。
答案 5 :(得分:0)
对于较新版本(Delphi 2010及更高版本),有一个有趣的解决方案
Implementing Failover and Load Balancing in DataSnap 2010 by Andreano Lanusse
How to direct DataSnap client connections to various DS Servers?