servlet容器是否可以防止web应用程序相互干扰,它们是如何做到这一点的?

时间:2021-10-25 14:04:42

I know that a servlet container, such as Apache Tomcat, runs in a single instance of the JVM, which means all of its servlets will run in the same process.

我知道servlet容器(比如Apache Tomcat)在JVM的一个实例中运行,这意味着它的所有servlet都将在同一个进程中运行。

I also know that the architecture of the servlet container means each web application exists in its own context, which suggests it is isolated from other web applications.

我还知道servlet容器的体系结构意味着每个web应用程序都存在于自己的上下文中,这表明它与其他web应用程序是隔离的。

As depicted here: servlet容器是否可以防止web应用程序相互干扰,它们是如何做到这一点的?

这里所描述:

Accepting that each web application is isolated, I would expect that you could create 2 copies of an identical web application, change the names and context paths of each (as well as any other relevant configuration), and run them in parallel without one affecting the other. The answers to this question appear to support this view.

考虑到每个web应用程序都是独立的,我希望您可以创建两个相同的web应用程序的副本,更改每个web应用程序的名称和上下文路径(以及任何其他相关配置),并并行运行它们,而不会有一个影响另一个。这个问题的答案似乎支持这一观点。

However, a colleague disagrees based on their experience of attempting just that.

然而,一位同事却不同意这种说法,因为他有过这样的经历。

They took a web application and tried to run 2 separate instances (with different names etc) in the same servlet container and experienced issues with the 2 instances conflicting (I'm unable to elaborate more as I wasn't involved in that work).

他们使用了一个web应用程序,并试图在同一个servlet容器中运行两个单独的实例(名称不同等等),并遇到了两个实例冲突的问题(我无法详细说明,因为我没有参与到该工作中)。

Based on this, they argue that since the web applications run in the same process space, they can't be isolated and things such as class attributes would end up being inadvertently shared. This answer appears to suggest the same thing

基于此,他们认为,由于web应用程序在相同的进程空间中运行,它们不能被隔离,诸如类属性之类的东西最终会被无意地共享。这个答案似乎表明了同样的事情

The two views don't seem to be compatible, so I ask you: Do servlet containers prevent web applications deployed to the same container from conflicting with each other?

这两个视图似乎不兼容,所以我问您:servlet容器是否防止部署到同一容器的web应用程序彼此冲突?

If yes, How do they do this?

如果是,他们怎么做?

If no, Why does interference occur?

如果没有,为什么会发生干扰?

and finally, Under what circumstances could separate web applications conflict and cause each other interference?, perhaps scenarios involving resources on the file system, native code, or database connections?

最后,在什么情况下,独立的web应用程序会发生冲突并导致相互干扰?,可能涉及文件系统、本机代码或数据库连接上的资源的场景?

3 个解决方案

#1


15  

The short answer is that the servlet container isolates the applications by using a separate classloader for each application - classes loaded by separate classloaders (even when from the same physical class files) are distinct from each other. However, classloaders share a common parent classloader and the container may provide a number of other container-wide resources, so the applications are not completely isolated from each other.

简而言之,servlet容器通过为每个应用程序使用单独的类加载器来隔离应用程序——由单独的类加载器(即使来自相同的物理类文件)加载的类彼此不同。然而,类装入器共享一个公共的父类装入器,容器可能提供许多其他容器范围的资源,因此应用程序之间并不是完全隔离的。

For example, if two applications share some common code by each including the same jar in their war, then each application will load their own instance of the classes from the jar and a static variable (e.g. a singleton) of a class in one application will be distinct from the static variable of the same class in the other application.

例如,如果两个应用程序共享一些常见的代码由每个包括相同的jar的战争,那么每个应用程序将从jar装载自己的类的实例和一个类的静态变量(例如,一个单例)在一个应用程序将不同于同一类的静态变量在另一个应用程序。

Now, take for example, that the applications try to use java.util.Logger (and presumably don't include their own instance of the Logger classes in their war files). Each application's own classloader will not find the class in the war file, so they will defer to their parent classloader, which is probably the shared, container-wide classloader. The parent classloader will load the Logger class and both applications will then be sharing the same Logger class.

现在,以应用程序试图使用java.util为例。日志记录器(大概不会在它们的war文件中包含它们自己的日志记录器类实例)。每个应用程序自己的类加载器将不会在war文件中找到类,因此它们将遵从它们的父类加载器,它可能是共享的、容器范围的类加载器。父类加载器将加载Logger类,并且两个应用程序将共享相同的Logger类。

#2


5  

Servlets in the same container will share some resources. I think it should be possible to deploy the same web application twice in the same container provided that you give each a different name and they don't collide on a particular resource. This would theoretically be the same as deploying two different servlets which just happen to have the same implementation, which we do all the time.

同一个容器中的servlet将共享一些资源。我认为应该可以在同一个容器中部署相同的web应用程序两次,前提是您给每个应用程序一个不同的名称,并且它们不会在特定的资源上发生冲突。这在理论上与部署两个不同的servlet是相同的,而这两个servlet恰好具有相同的实现,我们一直都是这样做的。

Some shared resources, off the top of my head (and I'm not an expert so don't quote any of this!):

一些共享的资源,在我脑海中浮现(我不是专家,所以不要引用这些!)

  • Libraries (jars) in tomcat/common/lib (Tomcat 5) or tomcat/lib (Tomcat 6).
  • tomcat/common/lib (tomcat 5)或tomcat/lib (tomcat 6)中的库(jar)。
  • Settings in the global server.xml, web.xml, tomcat-users.xml
  • 全局服务器中的设置。xml、web。xml,tomcat-users.xml
  • OS provided things, such as stdin/stdout/stderr, network sockets, devices, files, etc.
  • OS提供了诸如stdin/stdout/stderr、网络套接字、设备、文件等。
  • The logging system.
  • 日志系统。
  • Java system properties (System.getProperty(), System.setProperty())
  • Java系统属性(system . getproperty()、system . setproperty ()))
  • I suspect... static variables? I'm not sure if the ClassLoader design would prevent this or not.
  • 我怀疑…静态变量?我不确定这个类加载器的设计是否能阻止它。
  • Memory. This is the most common problem: one servlet can deny others availability by consuming all memory.
  • 内存。这是最常见的问题:一个servlet可以通过消耗所有内存来拒绝其他的可用性。
  • CPU - especially with multi-threaded apps. On the HotSpot JVM, each Java thread is actually an OS-level thread, which are expensive and you don't want more than a few thousand of them.
  • CPU——尤其是多线程应用程序。在HotSpot JVM上,每个Java线程实际上都是一个操作系统级别的线程,非常昂贵,您不需要超过几千个。

Doubtless there are more.

无疑有更多。

Many of these things are protected by a security manager, if you're using one.

如果您正在使用安全管理器,那么这些东西中的许多都受到安全管理器的保护。

#3


2  

I believe the isolation is in the class loader. Even if two applications use the same class name and package, their class loader will load the one deployed with the application.

我认为隔离是在类装入器中。即使两个应用程序使用相同的类名和包,它们的类加载程序也将加载应用程序部署的类加载程序。

#1


15  

The short answer is that the servlet container isolates the applications by using a separate classloader for each application - classes loaded by separate classloaders (even when from the same physical class files) are distinct from each other. However, classloaders share a common parent classloader and the container may provide a number of other container-wide resources, so the applications are not completely isolated from each other.

简而言之,servlet容器通过为每个应用程序使用单独的类加载器来隔离应用程序——由单独的类加载器(即使来自相同的物理类文件)加载的类彼此不同。然而,类装入器共享一个公共的父类装入器,容器可能提供许多其他容器范围的资源,因此应用程序之间并不是完全隔离的。

For example, if two applications share some common code by each including the same jar in their war, then each application will load their own instance of the classes from the jar and a static variable (e.g. a singleton) of a class in one application will be distinct from the static variable of the same class in the other application.

例如,如果两个应用程序共享一些常见的代码由每个包括相同的jar的战争,那么每个应用程序将从jar装载自己的类的实例和一个类的静态变量(例如,一个单例)在一个应用程序将不同于同一类的静态变量在另一个应用程序。

Now, take for example, that the applications try to use java.util.Logger (and presumably don't include their own instance of the Logger classes in their war files). Each application's own classloader will not find the class in the war file, so they will defer to their parent classloader, which is probably the shared, container-wide classloader. The parent classloader will load the Logger class and both applications will then be sharing the same Logger class.

现在,以应用程序试图使用java.util为例。日志记录器(大概不会在它们的war文件中包含它们自己的日志记录器类实例)。每个应用程序自己的类加载器将不会在war文件中找到类,因此它们将遵从它们的父类加载器,它可能是共享的、容器范围的类加载器。父类加载器将加载Logger类,并且两个应用程序将共享相同的Logger类。

#2


5  

Servlets in the same container will share some resources. I think it should be possible to deploy the same web application twice in the same container provided that you give each a different name and they don't collide on a particular resource. This would theoretically be the same as deploying two different servlets which just happen to have the same implementation, which we do all the time.

同一个容器中的servlet将共享一些资源。我认为应该可以在同一个容器中部署相同的web应用程序两次,前提是您给每个应用程序一个不同的名称,并且它们不会在特定的资源上发生冲突。这在理论上与部署两个不同的servlet是相同的,而这两个servlet恰好具有相同的实现,我们一直都是这样做的。

Some shared resources, off the top of my head (and I'm not an expert so don't quote any of this!):

一些共享的资源,在我脑海中浮现(我不是专家,所以不要引用这些!)

  • Libraries (jars) in tomcat/common/lib (Tomcat 5) or tomcat/lib (Tomcat 6).
  • tomcat/common/lib (tomcat 5)或tomcat/lib (tomcat 6)中的库(jar)。
  • Settings in the global server.xml, web.xml, tomcat-users.xml
  • 全局服务器中的设置。xml、web。xml,tomcat-users.xml
  • OS provided things, such as stdin/stdout/stderr, network sockets, devices, files, etc.
  • OS提供了诸如stdin/stdout/stderr、网络套接字、设备、文件等。
  • The logging system.
  • 日志系统。
  • Java system properties (System.getProperty(), System.setProperty())
  • Java系统属性(system . getproperty()、system . setproperty ()))
  • I suspect... static variables? I'm not sure if the ClassLoader design would prevent this or not.
  • 我怀疑…静态变量?我不确定这个类加载器的设计是否能阻止它。
  • Memory. This is the most common problem: one servlet can deny others availability by consuming all memory.
  • 内存。这是最常见的问题:一个servlet可以通过消耗所有内存来拒绝其他的可用性。
  • CPU - especially with multi-threaded apps. On the HotSpot JVM, each Java thread is actually an OS-level thread, which are expensive and you don't want more than a few thousand of them.
  • CPU——尤其是多线程应用程序。在HotSpot JVM上,每个Java线程实际上都是一个操作系统级别的线程,非常昂贵,您不需要超过几千个。

Doubtless there are more.

无疑有更多。

Many of these things are protected by a security manager, if you're using one.

如果您正在使用安全管理器,那么这些东西中的许多都受到安全管理器的保护。

#3


2  

I believe the isolation is in the class loader. Even if two applications use the same class name and package, their class loader will load the one deployed with the application.

我认为隔离是在类装入器中。即使两个应用程序使用相同的类名和包,它们的类加载程序也将加载应用程序部署的类加载程序。