负载平衡Web应用程序 [英] Load balance web application

查看:127
本文介绍了负载平衡Web应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There are load balanced tomcat web servers. Every request could be served by different tomcat server.

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

How could we take care of this while writing code for the j2ee (struts) based web application?

推荐答案

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

First of all, you'll want to set up your load balancer for session affinity/sticky sessions, so that it continues forwarding all requests to the same Tomcat (as long as it is up) based on JSESSIONID.

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

The Tomcat clustering doc states two important requirements for your application to successfully have it's sessions replicated:


  • 所有会话属性必须实现 java.io.Serializable

  • 确保您的网站.xml具有< distributable /> 元素或设置在< Context distributable =true/>

  • All your session attributes must implement java.io.Serializable
  • Make sure your web.xml has the <distributable/> element or set at your <Context distributable="true" />

如果您开始将对象放入会话中但未实现 Serializable (或者哪些属性/字段没有实现 Serializable ),那么你将遇到问题。

If you start putting Objects into Session which don't implement Serializable (or which have properties/fields that don't implement Serializable), then you're going to have problems.

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

(Actually these points all apply regardless of which servlet container you are using, I believe.)

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

Update: To address some of the questions in the comments about why use sticky sessions when you are balancing the load between multiple servers, I think it's easiest to explain this with an example.

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

First of all, this only really matters if your application keeps some sort of data in-session, which may not be every single application (although it's probably most). If you don't keep data in-session then you probably won't care about any of this and you can just stop reading here.

有一个环境让你保持会话中的数据,但你有粘性会话会打开一个令人头疼的世界。

Having an environment where you keep data in session but you do not have sticky session would open up a world of headaches.

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

Let's say first.jsp updates some value in a particular session attribute, and second.jsp happens to read this same session attribute. You can set up Tomcat to replicate session data to all servers in the cluster, but this replication does not occur instantly. What if the initial request for first.jsp is handled by server1 and one nanosecond after it completes, the same visitor makes a request to second.jsp, which in your non-sticky environment gets handled by server2. Since replication is not instantaneous, do you have any way of knowing if you are reading the most up-to-date session data? Do you have to add some sort of logic to synchronize your reads across the cluster? This would become giant pain.

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

Setting up session affinity/sticky sessions removes this headache; by having all requests from the same client server by the same node, you don't have to worry about "is this node up to date by the time it handles the request?" When the node fails, the client can still failover to another node in the cluster, which has a copy of it's session data, but with sticky sessions this becomes the rare case and not the norm.

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

There is another reason to want sticky sessions: load between the nodes in the cluster. If a request in a session could be handled by any node, then that would imply that you have all-to-all replication set up in the cluster (meaning the session data of node1 is replcated to node2, node3, ..., node N, the session data of node2 is replicated to node1, node3, ... none N, etc). All-to-all session replication can become bandwidth and resource intensive when the cluster gets larger, because each addition to the cluster means yet another node that needs to communicate with every other single node in the cluster.

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

An alternative to this is have a node's data replicated to only a few "buddies" in the cluster, so that in case the node fails it's data is available elsewhere but without every single node having to have a copy. In this scenario, you would configure the cluster so that node1 has it's data replicated to nodes 2 and 3, node 2 has it's data replicated to nodes 3 and 4, etc., forming a chain. In this scenario, adding additional nodes to the cluster does not cause the amount of communication between nodes to increase rapidly as it does in an all-to-all scheme.

这篇关于负载平衡Web应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆