C# 对于2个web服务器,单例类是否有2个实例?

C# 对于2个web服务器,单例类是否有2个实例?,c#,java,oop,C#,Java,Oop,对于2台web服务器,单例类是否有2个实例?是的,每个JVM甚至类加载器都有一个单例 请参阅本文(Java)。这两个web服务器都有各自的应用程序进程实例,无论是.net还是Java。因此,是,这两台服务器都有各自的singleton类实例 不管这两台web服务器是两台不同的物理机器,即使它们在同一台服务器上,它们肯定会在完全不同的进程上运行。每个进程将在内存中独立于任何其他进程加载其对象 特别是在asp.net的情况下- 即使在单个web服务器中,每个站点也会导致Singleton类的单独实例

对于2台web服务器,单例类是否有2个实例?

是的,每个JVM甚至类加载器都有一个单例


请参阅本文(Java)。

这两个web服务器都有各自的应用程序进程实例,无论是.net还是Java。因此,,这两台服务器都有各自的singleton类实例

不管这两台web服务器是两台不同的物理机器,即使它们在同一台服务器上,它们肯定会在完全不同的进程上运行。每个进程将在内存中独立于任何其他进程加载其对象

特别是在asp.net的情况下
- 即使在单个web服务器中,每个站点也会导致Singleton类的单独实例。因为asp.net工作进程中的每个站点都加载在单独的应用程序域中,所以没有两个域可以相互干扰对方的对象。因此,在asp.net的情况下,即使是具有单个asp.net工作进程的单个web服务器也可以/将具有多个单独的singleton类实例。您所说的“2个web服务器”是什么意思? 静态字段(在单例中)的作用域是应用程序域(在.net中)


因此,如果您的两个web服务器在两个独立的应用程序域中运行,那么是,否则不是。

事实上,如果一个web服务器是部署两次的web应用程序的一部分,那么您很可能在一个web服务器中有两个单例调用实例


在Java中,类加载器是类标识的一部分。您可以使用不同的类加载器加载同一个类两次,并且所有静态字段将存在两次。C#也有类似的机制。

作为这个问题的延伸,特别是对于.NET web应用程序,您还需要注意会话状态处理。假设会话不是“粘性的”(一旦会话建立,用户就停留在一台web服务器上),您需要将SessionState更改为out of process。这可以是ASP.NET会话状态服务器,也可以是SQL server,但要记住的关键一点是,会话状态不会自动在服务器之间共享,除非您通过退出进程来实现共享。此外,您在SessionState中输入的任何内容都需要可序列化;将[Serializable]属性添加到您在SessionState中使用的任何类中。

可以创建一个web服务器,该服务器将在连接、侦听套接字甚至接口上进行多路复用。它仍然是这个类的一个实例,只有一个线程,并且在这个实例之上还有一个非常小的内存占用。需要注意的是,虽然从最实际的角度来看,它看起来像两台服务器,但它仍然只是一台服务器(如果它崩溃,它会整个崩溃…)

不过,这种方法远不如多线程Web服务器流行,因为虽然硬件更轻,但开发人员更难处理——您必须在所有内容之间显式多路复用,并在非阻塞调用中处理所有连接。如果您产生了一些额外的线程,操作系统将从您身上带走大量的工作,使您能够更轻松地编写功能更丰富的服务器


当然,即使在单线程服务器中,也可以在单独的任务中生成第二台服务器,只要用户/admin/再次执行二进制文件的人使用不同的配置即可。需要一些非常花哨的编程来防止这种情况发生。

这就是为什么JSP/servlet提供了“会话”和“应用程序”数据的概念。这些应该在多服务器环境中跨服务器共享。

@David这是一个公平的问题,如果您不擅长这些事情,您可能会认为集群web服务器共享JVM。事实上,如果存在这样的系统,我一点也不会感到惊讶,尽管我怀疑它们是否普遍使用。@David M:此外,对于一个正在学习设计模式的初学者来说,这可能是一个有用的问题/答案,但他还不知道SingleTongerat答案的“gotchas”。很高兴看到您介绍了worker进程,每个请求都独立于其他请求。很多开发人员忘记了这一点。每个请求或每个网站?每个网站可能都有自己的应用程序域,但听起来像是在说每个web请求?困惑。不在主题上,同意,但这很可能是他将遇到的下一个问题。你所说的类加载器是指像tomcat这样的容器,对吗?@Blankman:不,我指的是java.lang.ClassLoader类。像tomcat这样的容器为它们部署的每个应用程序使用不同的类加载器,从而防止它们相互干扰;每个应用程序都可以有单独的单例类实例,并且每个应用程序可以使用同一类的不同版本。