2010-06-25 80 views
14

使用2個Web服務器,單例類會有2個實例嗎?使用2個Web服務器,單例類會有2個實例嗎?

+0

@大衛這是一個公平的問題,如果你沒有這樣的事情,你可能一點集羣網絡服務器共享JVM專家。事實上,如果存在這樣的系統,我一點也不會感到驚訝,儘管我懷疑它們是否被普遍使用。 – 2010-06-25 14:07:29

+0

@大衛L:再說,這可能是誰在學習設計模式和還不知道一個Singleton – 2010-06-25 14:09:30

回答

18

這兩個Web服務器都將具有不同的應用程序進程實例,無論是.net還是java。所以是的,這兩個服務器將有你的單身類的個人實例。

無論這兩臺Web服務器是兩臺不同的物理機器,即使它們位於同一臺服務器上,它們也將完全在不同的進程上運行。每個進程都會將其對象與任何其他進程分開加載到內存中。

specifically in case of asp.net - 即使在單個Web服務器中,每個站點也會導致單獨的Singleton類實例。由於asp.net工作進程中的每個站點都被加載到單獨的應用程序域中,因此兩個域之間不會互相干擾。所以在asp.net的情況下,即使具有單個asp.net工作進程的單個web服務器也可能會有多個單例類的實例,每個實例都與另一個單獨分離。

+0

大答案的「陷阱」初學者有用的問題/答案。很高興看到您將工作流程涵蓋到了每個請求都獨立於其他請求的事實上。很多開發人員都忘記了這一點。 – NotMe 2010-06-25 14:22:57

+0

每個請求或每個網站?每個網站可能都有自己的應用程序域,但這聽起來像是你說每個Web請求?困惑。 – Blankman 2010-06-25 15:17:04

+0

是的。我糾正了答案。類加載器的 – 2010-06-25 15:24:37

0

「2 Web服務器」是什麼意思? 靜態字段(單身)的作用域爲應用程序域(在.net中)。

因此,如果你的兩個Web服務器運行在兩個獨立的應用程序域,那麼是的,否則不。

0

事實上,你可能在一個Web服務器中有2個單例調用實例,如果它是部署了兩次的Web應用程序的一部分。

在Java中,類加載器是類身份的一部分。您可以使用不同的類加載器加載相同的類兩次,並且所有靜態字段將存在兩次。 C#有一個類似的機制。

+0

你的意思是像Tomcat的容器是否正確? (對於Web應用程序) – Blankman 2010-06-25 15:15:22

+0

@Blankman:不,我指的是類java.lang.ClassLoader。像tomcat這樣的容器爲他們部署的每個應用程序使用不同的類加載器,從而防止它們互相干擾;每個應用程序都可以有單獨類的單獨實例,每個應用程序可以使用同一類的不同版本。 – 2010-06-25 15:34:26

-1

作爲這個問題的擴展,特別是.NET web應用程序,您還需要注意SessionState處理。假設會話不是「粘性」(一旦會話建立,用戶就停留在一個Web服務器上),則需要將SessionState更改爲進程外。這可以是ASP.NET會話狀態服務器或SQL Server,但要記住的關鍵是SessionState不會自動在服務器之間共享,除非通過離開進程來共享。而且,你放入SessionState的任何東西都需要可序列化;將[Serializable]屬性添加到您在SessionState中使用的任何類。

+0

不完全的話題在這裏... – NotMe 2010-06-25 14:23:47

+1

不上話題,表示同意,但它很可能是下一個問題,他會遇到。 – 2010-06-25 14:31:04

0

有可能創建一個Web服務器,它將複用所有內容 - 連接,偵聽套接字,甚至是接口。它仍然是這個類的一個實例,只有一個線程,並且還有一個非常小的內存佔用。需要注意的是,儘管從大多數實際的角度來看它看起來像兩臺服務器,但它仍然只有一臺服務器(如果它崩潰,它會崩潰整個...)

這種方法不像多但是,由於在硬件上更輕,開發人員處理起來更加困難 - 您必須在所有內容之間進行顯式複用,並在非阻塞調用中處理所有連接。如果您產生了一些額外的線程,則操作系統會從您手中奪走大量工作,從而使您可以更輕鬆地編寫功能更豐富的服務器。

當然即使在一個獨立的任務的第二服務器的單個線程服務器產卵仍然是可能的,只是由用戶/管理員/誰再次執行二進制,具有不同的配置。它需要一些漂亮的花式程序來防止這種情況的發生。

0

這就是爲什麼JSP/Servlet的提供「會議」和「應用」數據的想法。這些應該在多服務器環境中的服務器之間共享。