? ? ? ?在一個(gè)主機(jī)啟動(dòng)多個(gè)服務(wù)器進(jìn)程,讓這些進(jìn)程監(jiān)聽同一個(gè)端口號(hào)是不可能的 ,這是因?yàn)榉?wù)器的套接字文件描述符不相同,一個(gè)socket一個(gè)描述符只能用一個(gè)端口,所以在node.JS中想多進(jìn)程監(jiān)聽同一個(gè)端口,之前的做法是主進(jìn)程監(jiān)聽主端口,然后將請求分別代理到不同端口的子進(jìn)程上,缺點(diǎn)是每創(chuàng)建一個(gè)socket需要用掉一個(gè)描述符,要知道進(jìn)程描述符和系統(tǒng)描述符有數(shù)量限制的。ps:node底層對于每個(gè)端口都設(shè)置了一個(gè)選項(xiàng),這個(gè)選項(xiàng)的含義是服務(wù)器套接字可以被不同進(jìn)程復(fù)用的。只有系統(tǒng)級的描述表引用計(jì)數(shù)為0了才釋放
? ? ? node為了解決這個(gè)問題加了一個(gè)進(jìn)程間發(fā)送句柄的功能,send()方法不僅可以發(fā)送信息還可以發(fā)送句柄,句柄(文件描述符)其實(shí)是指針,指向內(nèi)核中的文件信息,句柄對象可以是服務(wù)器、套接字(任何具有底層_handle成員的東西)。send()包括handle和message,如果message.cmd的值為NODE_HANDLE,取出message.type的值創(chuàng)建對應(yīng)的對象,然后監(jiān)聽句柄。進(jìn)程之間只是傳遞信息,并不是傳遞對象,具體底層原理以傳遞socket為例:參考文章父子進(jìn)程之間,在同一地址下的 socket 傳遞時(shí),各自都額外維護(hù)一個(gè)關(guān)聯(lián)列表存儲(chǔ)這些 socket 信息和ChildProcess實(shí)例,并且父進(jìn)程中的net#Server類實(shí)例自己保存下所有父進(jìn)程關(guān)聯(lián)列表。在調(diào)用net.Server#getConnections這類方法時(shí),遍歷列表中的ChildPorcess實(shí)例發(fā)送內(nèi)部消息,子進(jìn)程列表中的對應(yīng)項(xiàng)收到內(nèi)部消息并處理返回,父進(jìn)程中再結(jié)合返回結(jié)果和對應(yīng)著這個(gè)ChildProcess類實(shí)例維護(hù)的 socket 信息,保證功能的正確性。
個(gè)人理解,僅保存學(xué)習(xí)