hello~親愛的看官老爺們大家好~最近身體抱怨,只好宅居家中天天啃書,將 Java
基礎啃完一大部分。通過學習新語言,算是對以前 Node
底層部分一知半解的知識,有了較為全面的瞭解,因而有了這個可愛的小故事。
故事主要是簡單地講述何謂 Node
高效能,或者更應該說的是它低消耗,即同樣硬體條件下能承載更多請求,由於能力所限,難免有錯,還望不吝賜教。下面開始講故事~希望你們喜歡:)
背景
某天,CPU 大表弟與 CPU 小表妹來到閘道器大表哥家做客,三人決定玩過家家打發時間。然而大表哥家並沒有對應的玩具,於是,他們就地取材,找出了些玩具,並作出瞭如下規定:
- 小熊玩偶是服務員,負責紀錄客人,傳遞訂單和提供菜品等服務。
- 能上發條,到一定時間就會敲鼓的機器人是廚師。收到服務員送來的訂單後上發條,上一半表示做雪糕,上全部表示煮湯,敲鼓後說明菜做好了。
- 有一張名為資源的小桌子(最多容納10只玩偶),只要是工作的服務員或廚師,就得放在小桌子上,反之則離開桌子。
- 這是一間福利快餐店,客人不入店不給錢,服務更多客人才是目標,而客人則由閘道器大表哥看心情生成(即可能偶爾很多,偶爾根本就沒有)。
設定完成,三人可以正式開始玩過家家啦!
各自的設計
大表弟選擇提供 VIP 服務,每個客人來都提供一隻小熊服務員為他服務,當客人來時只需在不同的小熊上身上貼上上當前客人的編號與菜式即可。
小表妹則用了不同的方案,她覺得大表弟的太浪費資源小桌子的位置了,只需要為所有客人都提供一個常駐的小熊服務員即可,客人來時在小熊那記錄好不同客人的編號與菜式,多放廚師才能服務更多的客人。
在這樣的場景下,你認為哪個設計更好呢?
相信大家都會認為小表妹的設計會更好。由於資源小桌子面積有限,表弟的設計,同時只能服務 5 位客人(5 只小熊與 5 只機器人);而表妹的設計則能服務 9 位客人(1 只小熊與 9 只機器人)。而從客人等待的時間上說,是相差無幾的(慢的是廚師,而不是服務員)。
現在讓我們回到程式設計的世界,廚師上發條炒菜即 I/O
操作,一般是新開一個執行緒。可以看到,CPU
很快,但 I/O
很慢(可以想象到,必然是表弟表妹在等待發條機器人敲鼓)。 表弟的設計其實是粗略的 Java
模型,每個請求到來之際則開出一個新執行緒(新的小熊)進行處理,碰到 I/O
操作則原地等待,但仍佔著資源。而表妹的設計則是粗略的 Node
模型,無論多少個請求到來,均只有一個執行執行緒(只有唯一一隻小熊)。當等待一個請求的 I/O
操作結果時,可以處理另一個請求的的 I/O
操作結果,能更充分地利用資源。
簡而言之,在相同的硬體資源下(伺服器配置、頻寬等),Node
能用更少的資源(執行緒)處理相同數量的請求。也就是說,同樣的硬體資源下 Node
能承載更多的請求。單個請求的響應時間也不會比 Java
慢。
不同的規則
表弟為此結果憤憤不平,於是他提議修改一下規則。如果客人要吃的是雪糕,那麼用做一道加法作業題取代上發條的廚師如何。表妹表示同意,之後歡聲笑語中打出GG。因為她發現,只要有客人點了雪糕,她就得停下來數手指,什麼都幹不了。而可惡的表弟雖然也是數手指,但只要有煮湯的請求,他能先停下來,新找一隻小熊玩偶傳遞訂單後再回去數手指,處理客人訂單比她快。
如果說之前的規矩是 I/O
密集型的話,那麼修改後處理雪糕訂單就是 CPU
密集型了。可以看到,一旦 Node
涉及較為耗時的運算,處理請求的速度將直線下降。即使是不同的請求(如煮湯的),由於只有一個執行執行緒,都得等待運算完成後才能處理。而 Java
則不一樣,儘管還是得等待運算結果,但由於它自身是多執行緒的,阻塞了做雪糕請求,並不影響煮湯請求的響應。忽略語言本身的運算能力,Node
的模型導致它在處理 CPU
密集型業務時不如 Java
。
值得一提的是,不用過分擔心運算的問題。伺服器的 CPU
相當快,正常業務邏輯,就算是套了兩三層迴圈也不是特別大的問題,不一定就是效能瓶頸,不要未發現問題而先優化。一般而言,不涉及圖形運算或大資料處理等業務,Node
處理起來還是沒問題的。
小結
至此,煮家家的故事就講得差不多了,希望讓你明白到為何 Node
在處理 I/O
密集型業務時,顯現出極高的效能,或者說更低的消耗。小故事有部分細節尚未展示出來,比如不為每個新請求建立執行緒,可以省下執行緒建立與銷燬的開銷。儘管可以通過執行緒池解決,但 Node
在負荷大量請求的情況下,較少地切換執行緒,減少上下文切換帶來的開銷,也是它高效能的一個原因。
但要注意,使用任何一種語言編寫的伺服器,在效能到達瓶頸之前,響應請求的速度都不會顯著地快於其他語言。所謂 Node
高效能,其實更應該說的是它的低消耗。
而最後一點,Javascript
是單執行緒,但 Node
是多執行緒,它採用多程式的方式充分利用 CPU
。這點不少同學都有點糊塗的~
感謝各位看官大人看到這裡,知易行難,希望本文對你有所幫助~謝謝!