3

尽管这是一个以 Java 为中心的问题,但它确实适用于任何使用多层架构的系统。

在 3 层架构中,通常有 3 层:

  • 客户端代码所在的客户端/表示层;
  • 业务逻辑所在的中间件层;
  • RDBMS 和其他数据密集型系统所在的数据/eis层

在 Java 领域,对于 Web 应用程序,这可能如下所示:

  • 一个应用服务器,例如同时GlassFish运行“Web 层”(WAR 构成 Web 应用程序中的客户端层)和“业务层”(EJB、中间件等);和
  • 包含数据层的 RDBMS 服务器

在虚拟化/集群环境中,这些应用程序(GlassFish、RBMBS,如 Oracle 或 PostgreSQL 等)将在 VM 上运行。

我的问题:在这些虚拟机之间分配/分布这个 3 层架构的标准方法是什么?意思是,以下任何一种“策略”都可能是可行的,但不是优先的:

  1. 一台同时运行 GlassFish 和 RDBMS(所有 3 层)的虚拟机(假设所有虚拟机都是 Ubuntu 服务器,因此成本/价格不考虑在内)
  2. 两个虚拟机:一个运行 GlassFish 的应用服务器虚拟机和一个运行 PostgreSQL 等数据库服务器虚拟机
  3. 三个虚拟机:两个应用服务器虚拟机都运行 GlassFish,但是 1 个 GlassFish 实例仅运行 WAR(Web 层),而第二个 FlassFish 实例运行中间件/业务逻辑;然后是第三个数据库服务器

显然,如果所有服务器(所有层)都在同一个 VM 上运行,它们可能会运行得更快或更高效,因为它们不会因网络延迟而陷入困境。但是它们会在同一个虚拟机上,这需要我需要大型硬件来支持它们。此设置可能还存在安全问题。

每个都有优点/缺点。我对哪些策略最能实现以下目标感兴趣:(1) 最大限度地提高吞吐量/速度,(2) 最适合集群/云环境,以及 (3) 最大限度地提高安全性。

提前致谢!

4

2 回答 2

2

(1) 最大化吞吐量/速度,

这完全取决于您的应用程序。例如,数据库可能是您的瓶颈,在这种情况下,您在 JVM 中所做的事情非常重要。

(2) 最适合集群/云环境

如果您要分发您的系统,您很可能想要分发您的表示层。这是因为他们所做的工作取决于客户的数量,而每个客户所做的工作在很大程度上是独立的。(在表示层)

(3) 最大限度地提高安全性。

拥有更多虚拟机并不能保证提高安全性。应该设置您的 JVM,以便在其中运行的不同应用程序无论如何都非常独立。如果您想防止拒绝攻击并且您的后端服务被其他系统使用,您可能希望将它们分开,否则没有太大区别。

于 2012-01-09T16:59:23.430 回答
1

我认为您的问题的答案在很大程度上取决于此应用程序行为、数据库使用情况等......如果不查看当前的性能指标(正如已经提到的其他答案),什么也不能说。我发表了一些我的想法作为指导。

数据库

大多数组织在单独的主机中运行 RDBMS,一些工程师会选择从不虚拟化这些,这取决于他们的数据库供应商最佳实践对他们的案例的看法(也就是说,我通常认为 VM 等同于物理主机,并且我在任何时候都使用它们可能的)。

在性能方面,RDBMS 通常需要内核调整或非常规的文件系统策略,将它们放在不同的主机中会有所帮助。如果需要在高可用性模式或集群中设置数据库,将其与应用程序服务器分开也可以使事情变得更容易。请注意,如果您需要进行数据库调优,如果认真对待,这可能是一个困难的话题,并且它通常涉及诸如对齐磁盘中的分区之类的事情,试图通过巧妙地分配数据库数据段/文件来减少磁盘磁头移动,考虑到DBMS 和 OS 缓存大小和策略...所有这些都会影响在同一主机上运行的其他应用程序,所以我宁愿不理会数据库。

此外,RDBMS 通常服务于多个应用程序(这是有充分理由的:有时某些集成需要访问多个应用程序数据库)。将它们与应用程序服务器分开会有所帮助。

此外,数据库系统有自己的升级、备份、分发/集群和管理程序,并且通常由与应用服务器不同的人维护。因此,如果单独考虑,整个数据库管理主题更容易处理。如果数据库成为瓶颈,您可以单独处理数据库,而无需考虑其他层是否会影响性能。

对于规模合理的生产环境,我确实建议将 RDBMS 单独保留在单个主机中。但是,当然,如果您没有性能、管理或可用性要求,您可以考虑对所有内容使用共享服务器。

玻璃鱼

一般而言,当您想要将 Java EE 应用程序部署到多个服务器(以实现负载平衡或高可用性)时,您需要将相同的应用程序服务器和工件安装到集群中的所有应用程序服务器。然后,您可以选择在集群的每个节点上启用哪些工件。一些应用程序服务器可以根据服务器负载启用或禁用组件。在这种情况下,您的应用程序服务器就是您需要分发的“单元”。

现在,在某些情况下,您或您的组织可能更愿意为 Web 层和业务层提供完全分离的网络层(即安全问题)。在这种情况下,您将为此使用单独的主机。如果您的 Web 层非常重,并且您发现需要将其与业务层分开扩展(即您发现需要 6 个 Web 服务器,但您可以使用 1 或 2 个 EJB 容器来实现),我会将这两个层分开也。

注意:在同一个 Glassfish 实例中运行 Web 层和 EJB 层有一些好处:因为它们共享 JVM,所以 Web 层和业务层之间的调用可以使用引用调用语义。根据您的工作负载以及响应的大小和序列化成本,这可能会导致性能显着提高。

在大多数情况下,对于许多企业应用程序,我只会使用包含两个层的一或两台服务器(取决于您是否需要高可用性),因为即使负载增加,您仍然可以垂直增长(增加服务器功率或 VM 资源)或水平增长(添加另一个服务器和负载平衡请求)。

全球可用和高吞吐量的应用程序需要考虑许多其他方面才能使其具有可扩展性(只需将节点添加到 Java EE 集群节点不会削减它),所以我认为没有任何解决方案更好或者更糟糕的是为了部署到“云”,但总的来说,如果您计划部署到弹性虚拟化服务并且您的要求证明了这一点,我建议将 Web 层和业务层分开。

安全

在我看来,讨论的主题对安全没有直接影响。

最后,我相信关于这个话题可以说更多,而且我的经验有限,所以请多多指教;)。

于 2012-01-09T17:32:26.857 回答