Java 高效地部署同一战争的多个实例(不同上下文、相同容器)
我有一个WAR(app.WAR)和一个容器(Tomcat、Jetty、Glassfish等等)。 我的目标是按需在容器上部署同一web应用程序的数百个实例Java 高效地部署同一战争的多个实例(不同上下文、相同容器),java,tomcat,glassfish,jetty,war,Java,Tomcat,Glassfish,Jetty,War,我有一个WAR(app.WAR)和一个容器(Tomcat、Jetty、Glassfish等等)。 我的目标是按需在容器上部署同一web应用程序的数百个实例 http://foo/app1 --> app.war http://foo/app2 --> app.war http://foo/app3 --> app.war ... http://foo/appN --> app.war 实现这一目标的一些明显方法: 在Tomcat中,为每个应用程序创建一个contex
http://foo/app1 --> app.war
http://foo/app2 --> app.war
http://foo/app3 --> app.war
...
http://foo/appN --> app.war
实现这一目标的一些明显方法:
- 在Tomcat中,为每个应用程序创建一个context.xml文件(名为appN.xml),所有这些文件都指向同一个WAR。其他容器也有类似的方法
- 这种方法的问题是:它会将战争爆发N次,占用大量磁盘空间
- 使用符号链接创建指向app.war分解版本的webapp/{app1,app2,appN}文件夹。这可以防止磁盘空间爆炸,但JVM仍在向内存加载许多重复的JAR
- 使用一些共享库文件夹来包含大多数JAR(以及前两个选项的组合)
有什么想法吗?您可以在前端配置Apache(mod_proxy/mod_proxy_ajp),将命名的虚拟主机指向部署在Tomcat上的单个WAR。您的应用程序的设计/编写方式应能为所有请求提供服务——每个网站名称的特定配置可以存储在数据库中或作为应用程序中的配置文件——您的应用程序只需探测用户的请求域名,以确保应用了正确的设置(每个会话一次)。一般来说,您应该能够用一个应用程序解决这个问题。伟大的开发人员是懒惰的。如果这是一个实验,那么您列出的任何方法都可以工作 如果这是为了生产,那么我建议不要这样做。虽然我没有测试所有的容器,但我使用的容器让我相信,简单地为无头虚拟机提供容器会更有弹性。Linux虚拟机可以非常小,使用虚拟机技术,您可以根据需要添加或减少任意多的实例 如果你真的想拥有一个动态增长的解决方案,那么你应该设法消除单一的失败点,而不是试图将你的整个世界都整合到一个整体中
如果您确实需要“第二次”加载扩展/收缩,那么您应该查看AWS或CloundFoundry。如果您使用Jetty,您可以通过编程方式添加上下文
WebAppContext webapp = new WebAppContext();
webapp.setBaseResource(myBaseDirectory);
webapp.setContextPath(myContextPath);
在所有上下文中循环执行此操作。它的磁盘空间开销应该接近于零
在Tomcat中可能也有类似的方法。很抱歉有点离题,但在我看来,您的场景会显示“多租户”应用程序,这样您就有了一个为多个“租户”(客户)服务的应用程序 关于多租户设置,必须考虑以下因素:
- 客户无法访问彼此的数据(如果他们将数据存储在同一数据库、同一模式中,并使用“鉴别器”字段分隔数据)。这可以通过使用Spring Security和
- Hibernate具有4.0版的内置功能
- 这两个问题也可能有用
- (用于使用不同的数据源(每个客户的不同数据库或同一数据库上的不同模式)
- 共享代码意味着为一个客户修复的bug是为所有客户修复的(如果不同的客户对什么构成bug以及什么构成特性有不同的看法,这也可能是一个缺点)
- 集群部署可以在客户之间共享负载(但是,需要确保所有客户都可以使用峰值容量)
- 代码将更加复杂,因为查询需要确保客户之间的“区别”有效,而不会意外地将客户暴露给彼此的数据
- 您可以使WAR文件保持不变,甚至是经过签名的,这样就可以清楚地知道您部署了哪个版本
- 您为定制/配置web应用程序所做的所有修改都是单独的,因此很容易识别,以便查看和迁移到新版本
- 您可以创建一个参数化模板覆盖,其中包含应用于web应用程序的许多实例(例如,对于多租户部署)的常见自定义和配置
- 由于分层部署清楚地标识了公共组件和特定于实例的组件,Jetty能够共享模板的类加载器和静态资源缓存,从而大大减少了多个实例的内存占用