We're building a java web application where each customer will have an instance of it with it's own database schema.
我们正在构建一个java web应用程序,其中每个客户都将拥有它自己的数据库模式的实例。
It will be managed by my company so I would like to know what is the best approach to have several apps instances running on the same Tomcat runtime since we tried to run 3 instances on a single Tomcat and it ended up on an Out of memory exception. We considered to run multiple tomcat instances in the same server but we haven't already tested it. Also we are considering to have a separate server for each customer.
它将由我的公司管理,因此我想知道在同一个Tomcat运行时运行多个应用程序实例的最佳方法是什么,因为我们尝试在一个Tomcat上运行3个实例,结果是在内存异常的情况下运行。我们考虑在同一个服务器上运行多个tomcat实例,但是我们还没有对它进行测试。我们还考虑为每个客户提供一个单独的服务器。
From your experience with similar scenarios, what is your opinion?
从你的经验来看,你的观点是什么?
EDITED: This application can't be multi-tenant since there will be code customizations in some parts of it as well as some other business facts that require an application instance per client. So please the application architecture is not the subject here.
编辑:这个应用程序不可能是多租户的,因为在它的某些部分会有代码自定义,以及其他一些需要每个客户端应用程序实例的业务事实。因此,请不要在这里使用应用程序架构。
Thank you,
谢谢你!
Gyo
Gyo
2 个解决方案
#1
3
You want to use multi tenant architecture. There will be only one database and web application instance, and every record will be qualified by the 'owner' company. You can use the subdomain/domain which the client uses to access your application to differentiate between them.
您希望使用多租户架构。将只有一个数据库和web应用程序实例,并且每个记录都将被“所有者”公司限定。您可以使用客户端用来访问应用程序的子域/域来区分它们。
Simplistically, you add a 'domain_id' column to every table and you have a 'where domain_id=?' in every query. Each user will have an associated domain_id which you will pick up on login and put in session. In reality there will be other considerations.
简单地,在每个表中添加“domain_id”列,并且有一个“domain_id=?”在每一个查询。每个用户都将有一个相关的domain_id,您将在登录和会话中获得它。事实上,还有其他的考虑。
EDITED: Based on the edit in the question, here is additional part to the answer.
编辑:根据编辑的问题,这里有额外的部分的答案。
In multitenant architecture it is possible to customise every instance without maintaining separate codebases. Some of the customisations can be part of the 'profile'. This is suitable for data values and flags, like currency, date format, etc. The case where new functionality specific to a client is required, this can be achieved by supporting plugins.
在多租户体系结构中,不需要维护单独的代码基就可以定制每个实例。一些定制可能是“配置文件”的一部分。这适用于数据值和标记,如货币、日期格式等。如果需要特定于客户端的新功能,可以通过支持插件来实现。
Taking a one time pain to fit your solution into a multi tenant architecture will be better than the on going pain of maintaining several separate versions of your code for each client. You might want to read up on the topic of 'technical debt'.
为了将您的解决方案与多租户体系结构相匹配,花一段时间的痛苦将比为每个客户机维护多个不同版本的代码所带来的痛苦要好。你可能想了解一下“技术债务”这个话题。
An ERP is a complex case of a business application, and you can get inspiration from reading the OpenBravo Trial FAQ to get an idea of what we are saying. Openbravo is open source and you may get technical details by looking at their code.
ERP是一个复杂的商业应用案例,你可以通过阅读OpenBravo试用FAQ获得灵感来了解我们所说的内容。Openbravo是开源的,您可以通过查看它们的代码获得技术细节。
#2
2
My Opinion is exactly the same as Kinjal Dixit one. Your approach is wrong and will be an huge waste of resources.
我的观点和Kinjal Dixit一模一样。你的方法是错误的,将会是巨大的资源浪费。
If you want to be able to deploy different version of the web-app for the same server you will have to isolate the class-loading of each app and this will imply an huge memory consumption. Otherwise if all web-app will always be the same there is no interest to deploy it many times.
如果你想在同一台服务器上部署不同版本的web应用程序,你将不得不隔离每个应用程序的类加载,这将意味着巨大的内存消耗。否则,如果所有的web应用程序都是相同的,那么就没有兴趣多次部署它。
Having a separate server for each customer will also be a waste of resource (multiple instance of JVM, multiple classloading of the same libraries, multiplication of the number of thread and so of the cost of scheduling) and will significantly complicate the deployment, especially if you plan some clustering strategy where the load balancing will probably become a hell
为每个客户有一个单独的服务器也会浪费资源(多个JVM实例,多个类加载相同的库,乘法的线程的数量,这样的调度)的成本将大大复杂化部署,特别是如果你计划一些聚类策略的负载平衡可能会成为一个地狱
Moreover if you want to have some specific feature for a given client it will also become a hell to manage / deploy / upgrade, etc...
此外,如果您想为给定的客户端提供一些特定的特性,那么它也将成为管理/部署/升级的地狱,等等……
Multi-tenant architecture does not necessary imply to share the database (you can have a DB instance per client and dispatch the request with an interceptor at low level) however sharing the web-app is an absolute necessity.
多租户架构并不意味着共享数据库(您可以在每个客户机上拥有一个DB实例,并且在低级别上使用拦截器发送请求),但是共享web应用程序是绝对必要的。
I'd also advice to provide some kind of configuration to allow to enable custom features for a given client.
我还建议提供一些配置,以允许为给定客户机启用定制功能。
I worked for a company where we encountered exactly this problem (expose a legacy web application as a SAAS one) we started by deploying one web-app per client, spent huge time in various optimization (including class loading factorization) to reach the "huge" number of 14 customer per server.
我在一家公司工作,在那里我们遇到了这个问题(将遗留的web应用程序作为SAAS),我们首先部署了一个客户端web应用程序,在各种优化(包括类装载分解)中花费了大量时间,以达到每台服务器14个客户的“巨大”数量。
This was far from our performance expectation and we finally switched to a multi-tenant architecture, but keeping one DB instance per customer to avoid the important cost of data-model refactoring. The new deployment was able to handle more than 100 customer on the same server with incomparable performance.
这与我们的性能期望相去甚远,我们最终转向了多租户架构,但每个客户保留一个DB实例,以避免数据模型重构的重要成本。新的部署能够在相同的服务器上处理超过100个客户,具有无与伦比的性能。
EDIT (according to question update)
编辑(根据问题更新)
If you absolutely want to avoid multi-tenancy then i'd recommend to use only one servlet container (tomcat) per server. In this case you will have to let the default web-app classloading isolation (as you will have custom code in different instances) which will imply a high memory footprint. You should however put all common libraries in the common/lib tomcat directory to factorize their loading ( see http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html).
如果您绝对希望避免多租户,那么我建议每个服务器只使用一个servlet容器(tomcat)。在这种情况下,您将不得不让默认的web应用程序类加载隔离(因为您将在不同的实例中拥有自定义代码),这将意味着内存占用率很高。但是,您应该将所有公共库放在公共/lib tomcat目录中,以便将它们的加载分解(参见http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html)。
#1
3
You want to use multi tenant architecture. There will be only one database and web application instance, and every record will be qualified by the 'owner' company. You can use the subdomain/domain which the client uses to access your application to differentiate between them.
您希望使用多租户架构。将只有一个数据库和web应用程序实例,并且每个记录都将被“所有者”公司限定。您可以使用客户端用来访问应用程序的子域/域来区分它们。
Simplistically, you add a 'domain_id' column to every table and you have a 'where domain_id=?' in every query. Each user will have an associated domain_id which you will pick up on login and put in session. In reality there will be other considerations.
简单地,在每个表中添加“domain_id”列,并且有一个“domain_id=?”在每一个查询。每个用户都将有一个相关的domain_id,您将在登录和会话中获得它。事实上,还有其他的考虑。
EDITED: Based on the edit in the question, here is additional part to the answer.
编辑:根据编辑的问题,这里有额外的部分的答案。
In multitenant architecture it is possible to customise every instance without maintaining separate codebases. Some of the customisations can be part of the 'profile'. This is suitable for data values and flags, like currency, date format, etc. The case where new functionality specific to a client is required, this can be achieved by supporting plugins.
在多租户体系结构中,不需要维护单独的代码基就可以定制每个实例。一些定制可能是“配置文件”的一部分。这适用于数据值和标记,如货币、日期格式等。如果需要特定于客户端的新功能,可以通过支持插件来实现。
Taking a one time pain to fit your solution into a multi tenant architecture will be better than the on going pain of maintaining several separate versions of your code for each client. You might want to read up on the topic of 'technical debt'.
为了将您的解决方案与多租户体系结构相匹配,花一段时间的痛苦将比为每个客户机维护多个不同版本的代码所带来的痛苦要好。你可能想了解一下“技术债务”这个话题。
An ERP is a complex case of a business application, and you can get inspiration from reading the OpenBravo Trial FAQ to get an idea of what we are saying. Openbravo is open source and you may get technical details by looking at their code.
ERP是一个复杂的商业应用案例,你可以通过阅读OpenBravo试用FAQ获得灵感来了解我们所说的内容。Openbravo是开源的,您可以通过查看它们的代码获得技术细节。
#2
2
My Opinion is exactly the same as Kinjal Dixit one. Your approach is wrong and will be an huge waste of resources.
我的观点和Kinjal Dixit一模一样。你的方法是错误的,将会是巨大的资源浪费。
If you want to be able to deploy different version of the web-app for the same server you will have to isolate the class-loading of each app and this will imply an huge memory consumption. Otherwise if all web-app will always be the same there is no interest to deploy it many times.
如果你想在同一台服务器上部署不同版本的web应用程序,你将不得不隔离每个应用程序的类加载,这将意味着巨大的内存消耗。否则,如果所有的web应用程序都是相同的,那么就没有兴趣多次部署它。
Having a separate server for each customer will also be a waste of resource (multiple instance of JVM, multiple classloading of the same libraries, multiplication of the number of thread and so of the cost of scheduling) and will significantly complicate the deployment, especially if you plan some clustering strategy where the load balancing will probably become a hell
为每个客户有一个单独的服务器也会浪费资源(多个JVM实例,多个类加载相同的库,乘法的线程的数量,这样的调度)的成本将大大复杂化部署,特别是如果你计划一些聚类策略的负载平衡可能会成为一个地狱
Moreover if you want to have some specific feature for a given client it will also become a hell to manage / deploy / upgrade, etc...
此外,如果您想为给定的客户端提供一些特定的特性,那么它也将成为管理/部署/升级的地狱,等等……
Multi-tenant architecture does not necessary imply to share the database (you can have a DB instance per client and dispatch the request with an interceptor at low level) however sharing the web-app is an absolute necessity.
多租户架构并不意味着共享数据库(您可以在每个客户机上拥有一个DB实例,并且在低级别上使用拦截器发送请求),但是共享web应用程序是绝对必要的。
I'd also advice to provide some kind of configuration to allow to enable custom features for a given client.
我还建议提供一些配置,以允许为给定客户机启用定制功能。
I worked for a company where we encountered exactly this problem (expose a legacy web application as a SAAS one) we started by deploying one web-app per client, spent huge time in various optimization (including class loading factorization) to reach the "huge" number of 14 customer per server.
我在一家公司工作,在那里我们遇到了这个问题(将遗留的web应用程序作为SAAS),我们首先部署了一个客户端web应用程序,在各种优化(包括类装载分解)中花费了大量时间,以达到每台服务器14个客户的“巨大”数量。
This was far from our performance expectation and we finally switched to a multi-tenant architecture, but keeping one DB instance per customer to avoid the important cost of data-model refactoring. The new deployment was able to handle more than 100 customer on the same server with incomparable performance.
这与我们的性能期望相去甚远,我们最终转向了多租户架构,但每个客户保留一个DB实例,以避免数据模型重构的重要成本。新的部署能够在相同的服务器上处理超过100个客户,具有无与伦比的性能。
EDIT (according to question update)
编辑(根据问题更新)
If you absolutely want to avoid multi-tenancy then i'd recommend to use only one servlet container (tomcat) per server. In this case you will have to let the default web-app classloading isolation (as you will have custom code in different instances) which will imply a high memory footprint. You should however put all common libraries in the common/lib tomcat directory to factorize their loading ( see http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html).
如果您绝对希望避免多租户,那么我建议每个服务器只使用一个servlet容器(tomcat)。在这种情况下,您将不得不让默认的web应用程序类加载隔离(因为您将在不同的实例中拥有自定义代码),这将意味着内存占用率很高。但是,您应该将所有公共库放在公共/lib tomcat目录中,以便将它们的加载分解(参见http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html)。