uniGUI HyperServer 是一种新的服务器体系架构, 旨在高度提高 uniGUI 应用程序的可用性、稳定性和特定的可伸缩性。 这一目标是通过应用业界已知和广泛使用的技术 (如负载平衡和过程回收) 实现的。
传统的 uniGUI 应用程序服务器由一个单独的进程和多个线程组成。 单个进程可以是 uniGUI 可执行文件或 ISAPI 或 Apache 工作进程。 在所有情况下, 所有会话都驻留在单个进程中, 并且在同一进程中有多个线程用于处理传入的请求。
uniGUI HyperServer 改变了模型, 变成了一个多进程多线程模型。 在这个新模型中, 会产生几个工作进程来服务同一 web 应用程序。 会话将在工作进程之间划分, 并且基于配置, 您可能有多个工作进程用于相同的 uniGUI 应用程序。 工作进程由另一个实际上叫 HyperServer 进程来管理和调度。 HyperServer 将是所有客户端请求的入口点。 HyperServer 将接受所有请求并将它们分发到工作进程中。 HyperServer 还有责任在需要时生成新的工作进程, 并在不再需要时回收它们。 由于 uniGUI 会话是有状态的, 因此 HyperServer 的另一个重要职责是将传入的会话请求定向到创建该特定会话的正确的工作进程。 在 HyperServer术语中, 每个工作进程称为一个节点。
在继续之前,我们先来学习一下HyperServer引入的几个新术语。
HyperServer
HyperServer是所有请求的主要入口点。它将过滤请求并将它们引导到相应的节点。如果请求未与节点关联,则HyperServer将根据负载分配算法将其定向到任意节点。 HyperServer还负责创建新节点并在需要时回收它们。
毋庸置疑,HyperServer本身是一个uniGUI应用程序,专为此特定目的而设计。 HyperServer以预编译的二进制文件(Exe和Dll)的形式部署。可用的部署选项包括:独立服务器,ISAPI模块和Windows服务。将来HyperServer组件将包含在uniGUI库中,因此开发人员将能够创建自己的自定义HyperServers。
Node(节点)
HyperServer节点实际上是一个工作进程。同时,uniGUI应用程序本身也以独立的EXE模式部署。开发人员将以Node的形式部署他们的应用程序。开发人员在设计Node应用程序时不需要采取任何特殊设计,跟开发任何标准的uniGUI应用程序是一样的。
Node Id(节点ID)
每个节点都有一个唯一的节点ID。在创建节点时分配节点ID。当节点被回收时,将重新使用节点ID。
Transport(传输通道)
HyperServer使用传输通道在内部与节点通信。目前仅实现HTTP传输通道。未来,将基于各种技术实现其他的Transport,如Wiidows Pipes,TCP和UDP。
Node Recycling(节点回收)
节点将根据预定的设计方案进行回收,当需要回收节点时,将请求关联的进程做终止操作并在确认此请求后,Node将开始终止其所有会话并最终终止其进程。如果节点未确认回收请求,则HyperServer将强制终止该请求。
Active Node(激活节点)
活动节点是那些主动服务会话的节点,他们能够接受新的会话。
Suspended Node(挂起结点)
挂起的节点是无法与HyperServer通信的节点。在正常操作下,HyperServer会以特定间隔轮询其所有节点。如果其中一个节点未能响应,则将其标记为已暂停。如果节点在一定量的重试后未能响应,则它将被视为失败的节点并将被清除。
Purged Node(清除节点)
清除节点是从活动节点列表中删除并发送到回收队列的节点。清除节点既不接受新会话也不处理任何传入请求。下次清理回收队列时,它将从进程空间中删除。
Discarded Node(丢弃节点)
丢弃节点是实际拥有多个会话的节点,但它不接受新会话。它将继续存在,直到所有会话终止。在没有剩余会话时,它将被清除。
Persistent Node Zero(零持久节点)
零持久节点是一个Id = 0的节点,它保证持续运行,虽然偶尔也会像其他节点一样被回收,但在回收后会立即重新加载,不会被永久卸载。持久节点的主要目的是确保一次至少运行一个节点。考虑一种情况,一个uniGUI应用程序需要在线程中执行后台任务,这个任务可能利用放置在ServerModule上的TUniThreadTimer中执行。在传统的uniGUI应用程序中,只有一个进程,因此后台任务可以保证以Singleton的形式运行。但是,在同时运行同一进程的多个副本的HyperServer中,应该有一种机制来确保您的Singleton方法仅在其中一个节点中运行。零持久节点选项完美地满足此目的。您需要做的就是启用此选项并检查uniGUI应用程序中的Node Id。如果名为NodeZero的ServerModule中的布尔属性为True,则运行后台任务是安全的。
在下面的代码中,只在当前节点是Node Zero(Node Id = 0)时才执行ThreadTimer事件。
procedure TUniServerModule.UniThreadTimer1Timer(Sender: TObject); begin if NodeZero then // run code if I'm Node #0 begin // Your task here end; end;
或者,如果您计划使用HyperServer或传统的单一进程模式部署应用程序,则可以使用以下语法。
procedure TUniServerModule.UniThreadTimer1Timer(Sender: TObject); begin if NodeZero or (not NodeMode) then // run code either if I'm Node #0 or I'm not a Node! begin // Your task here end; end;