负载平衡Web应用程序

有负载平衡的tomcat Web服务器。 每个请求都可以由不同的tomcat服务器提供。

在为基于j2ee(struts)的Web应用程序编写代码时,我们如何处理这个问题?

首先,您需要为会话关联性/粘性会话设置负载均衡器,以便它继续将所有请求转发到基于JSESSIONID的同一个Tomcat(只要它已启动)。

Tomcat集群文档说明了应用程序成功完成会话复制的两个重要要求:

  • 您的所有会话属性都必须实现java.io.Serializable
  • 确保您的web.xml具有元素或设置在

如果您开始将对象放入会话中而不实现Serializable (或者具有不实现Serializable属性/字段),那么您将遇到问题。

(实际上,无论你使用哪个servlet容器,这些都适用。我相信。)

更新:为了解决为什么在平衡多个服务器之间的负载时使用粘性会话的注释中的一些问题,我认为用一个例子解释这个问题最简单。

首先,只有当您的应用程序在会话中保留某种数据时,这才真正重要,这可能不是每个应用程序(尽管可能最多)。 如果你没有在会话中保存数据,那么你可能不会关心任何这些,你可以在这里停止阅读。

拥有一个环境,您可以将数据保存在会话中,但是您没有粘性会话,这会让您感到头疼。

假设first.jsp更新特定会话属性中的某个值,而second.jsp恰好读取此相同的会话属性。 您可以设置Tomcat以将会话数据复制到群集中的所有服务器,但此复制不会立即发生。 如果first.jsp的初始请求由server1处理并且在完成后一纳秒后,同一个访问者向second.jsp发出请求,该请求在非粘性环境中由server2处理。 由于复制不是即时的,您是否有任何方法可以知道您是否正在阅读最新的会话数据? 您是否必须添加某种逻辑来同步整个群集中的读取? 这将成为巨大的痛苦。

设置会话关联性/粘性会话消除了这种麻烦; 通过同一节点从同一客户端服务器获取所有请求,您不必担心“在处理请求时,此节点是最新的吗?” 当节点发生故障时,客户端仍然可以故障转移到群集中的另一个节点,该节点具有其会话数据的副本,但是对于粘性会话,这种情况很少见,而不是常态。

还有另一个需要粘性会话的原因:在群集中的节点之间加载。 如果会话中的请求可以由任何节点处理,那么这意味着您在集群中设置了全部复制(意味着node1的会话数据被重新复制到node2,node3,…,节点) N,node2的会话数据被复制到node1,node3,… none N等。 当群集变大时,全对会话复制可能变成带宽和资源密集型,因为群集的每次添加都意味着另一个需要与群集中的每个其他单个节点通信的节点。

另一种方法是将节点的数据复制到集群中的少数“好友”,以便在节点发生故障的情况下,其数据可在其他地方获得,但不必每个节点都必须有副本。 在这种情况下,您将配置群集,以便node1将其数据复制到节点2和3,节点2将其数据复制到节点3和4等,形成链。 在这种情况下,向群集添加其他节点不会导致节点之间的通信量快速增加,就像在“全部 – 所有”方案中一样。