6分钟看懂 Node.js 武功精髓
本篇來自【北媽的小北鼻】寫手聯盟?
小北鼻作者:鬧鬧
閱讀大約需要6分鐘
1
為什么要學習Node.js?
Node.js是目前非?;馃岬募夹g,可是作為一個前端開發人員,為什么要學Node.js?
說Node.js優劣的文章,網上一大堆,在這兒就不過多描述了。技術是服務于業務的,學技術最終目的就是為了更高的收入,咱們就是這么俗,那就從以下兩點來看看,為什么要學Node.js
從工作上來說
首先第一點,很多大公司都在用Node.js,并且很多大廠的招聘“高級前端工程師”也明確提出了要掌握Node.js,所以學習Node.js成了我們前端開發者想要獲得高薪,繞不過去的坎。
從現在的招聘信息來看,全棧是一個大趨勢,兩個前端技術相同的人,如果其中一個人懂后端開發,那么不管是他的薪酬待遇還是入職概率,都比另一個人要高的多。
當前端工程師了解服務端的開發之后,在與后臺開發的溝通,將大大的提高溝通效率,從而提高開發效率。在這不得不說,公司真是個小機靈鬼。
所以,市場逼著我們這些前端開發者要學習服務端開發。
再從投入/回報上看
Node.js是基于JavaScript語言和V8引擎的Web服務器項目,我們可以直接使用JavaScript來搭架服務器。
快樂的是,作為前端開發,我們的看家本領就是JavaScript,學習Node簡直不要太輕松,這樣是大大的降低了我們學習后端開發的難度。
而且在Node環境下,通過模塊化的JavaScript代碼,加上函數式編程,并且無需考慮瀏覽器兼容性問題,直接使用最新的ECMAScript 6標準,可以完全滿足工程上的需求。
在Node.js中,模塊化,構建,輔助工具,調優,架構調整,這些東西是無處不在的。在Node環境中的編程思想,同時也能提高我們前端開發的質量,這樣相輔相成,讓我們能更快速的提高自己!
所以,學習Node無疑是快速掌握全棧技術的最好途徑
悄悄的告訴你,學Node.js還有一個很大的好處,就是能更清楚的知道,服務器是怎么運作的,所以就算是做后臺的,學習Node.js也是妙不可言。
2
Node.js的特點
在說Node.js解決了什么問題,如何解決痛點之前,有必要先說一下Node.js的特性
Node.js是一個Javascript運行環境
依賴于Chrome V8引擎進行代碼解釋
事件驅動
非阻塞I/O
輕量、可伸縮,適于實時數據交互應用
單進程,單線程
這些特點,不能一條一條的來看,而是要綜合起來一起看
我認為其中有個最重要的一點,那就是事件驅動。這也是為什么Node.js采用JavaScript單線程語言,來做到非阻塞I/O,同時處理萬級的并發而不會造成I/O阻塞的原因。(后面會詳細說明)
其中V8引擎,是Node.js也是采用JavaScript的關鍵因素之一,因為它為JavaScript提供了在非瀏覽器運行環境,V8的高效也是導致Node.js高效的原因之一
3
Node.js解決了什么問題?
了解了Node.js的特性,再來看Node.js解決了什么問題,就更容易理解了
要學習一門新技術,那我們首先得知道他是要解決了什么別人解決不了或者是難解決的問題
不然我們一股腦的學了之后,它是用來干啥的都不知道,又怎么會知道在什么時候,應該選擇什么樣的技術來更優雅的寫BUG呢?
Node.js主要解決了以下兩個頭疼的事情
并發連接
I/O阻塞
什么是并發連接?有趣的例子
并發這東西,可是吹牛必備啊,想必大家應該都知道并發是個什么玩意。但畢竟是入門文章,擔心有些人沒什么印象,這里還是簡單提一下。
并發(Concurrency):?是指在一個系統中,擁有多個計算,這些計算有同時執行的特性,而且他們之間有著潛在的交互。
看概念很難理解,其實并不復雜,比如“我們吃飯吃到一半,電話來了,我們停了下來接了電話,接完后繼續吃飯,這說明支持并發。”
用程序來解釋就是一群用戶同時來訪問我們的網站/程序。
一般我們在處理并發的時候,都是盡可能的做到讀寫分離,或者分布式部署不同的服務器,或者直接簡短粗暴的提升我們單機服務器的性能。
可這樣做要么是苦逼了程序員,要么就是苦逼了公司的錢包。
我要是公司老板,能不出服務器這個錢就肯定不出,畢竟不管是升級服務器還是擴張服務器,那都是一筆不小的錢啊。
那就只能苦逼一下員工了咯~可我們又不想這么苦逼,這時候用Node.js就能幫我們省不少麻煩。
那Node.js又是怎樣處理高并發的呢?
在這里容我先賣個關子,看完I/O阻塞之后,再來看看Node.js是怎樣處理的。
什么是I/O阻塞?
先說說I/O是什么
I/O是input/output(輸入/輸出)
知道I/O之后,接下來的阻塞就很容易理解了。
形象的說,我在餐廳吃飯,就這一個座位,我點完餐后,坐在這享受美食。
然而這時候來了個路人甲,點餐后想坐下吃飯,而這時候我還沒吃完呢,想讓我讓位置給你?不存在的
路人甲只能在旁邊眼巴巴的看著我吃。得等我吃完,走了之后,他才能坐下來吃飯。而這等待的過程呢,就可以叫做阻塞。
這樣做明顯非常不合理嘛
那Node.js是怎么來解決I/O阻塞的呢?
Node.js遇到I/O事件,并不會先處理,而是先放在事件隊列中,主線程依然繼續往下執行,利用異步操作來處理事件隊列中的事情。
作為一個干貨文章,怎么能少的了圖呢?沒圖你怎么理解?
來看看從用戶請求到服務器返回數據,Node.js為了應對并發,都做了些啥玩意
我想你現在肯定是懵逼的,那繼續剛才吃飯的例子從頭道來~~~
我跟路人甲同時進入餐館。老板坐在板凳上等著客人光顧。
我跟路人甲同時找到老板說“老板!我要來一份雞腿!”,這時候老板不樂意了,文明點餐,請取號排隊!
我跟路人甲先后取號坐好后(肯定是我拿的1號,路人甲拿的2號啦,畢竟主角光環在這頂著)
老板喊來了服務員小A、小B
老板吩咐“小A啊~去招待1號主角點餐入座點餐”
接著又吩咐“小B啊~去招待2號路人甲入座點餐”
吩咐完后,老板繼續坐板凳上等著新的客人關顧……
此時小A、小B分別就帶著我跟路人甲去入座點餐
當我或者路人甲吃完飯結賬離開時,老板都會對我們說“慢走~~~謝謝惠顧,下次再來!”
故事說完,咱們來按照故事解釋一下程序的運作
我跟路人甲就是用戶。
老板,就是這個程序的主線程。
服務員小A,小B就是線程池里的子線程。
我跟路人甲同時找到老板點餐,這就是用戶的并發請求。
老板管理整個餐廳的運作,發現我們的請求是I/O阻塞呀,所以讓我們排隊取號。這也就是Node.js中維護的事件隊列。
我們點餐之后的入座就餐還有上菜,這些I/O阻塞的事情,都是由服務員來提供服務,老板并不參與其中。
在我們用餐完畢的時候,會通知老板我們要結賬離開,結賬離開這個動作就是事件執行完畢后的一個回調函數。
此時老板就會跟我們說“慢走~~~謝謝惠顧,下次再來!”,也就是事件執行完后回調函數的一個操作,并且將線程釋放回線程池。
現在再回過頭去看圖,是不是清晰的多了。
總結以下:
1、每個Node.js進程只有一個主線程在執行程序代碼。
2、當用戶的網絡請求或者其它的異步操作到來時,Node.js都會把它放到“事件隊列”之中,并不會立即執行它,代碼就不會被阻塞,主線程繼續往下走,直到主線程代碼執行完畢。
3、當主線程代碼執行完畢完成后,通過事件循環機制,從“事件隊列”的開頭取出一個事件,從線程池中分配一個線程去執行這個事件,接下來繼續取出第二個事件,再從線程池中分配一個線程去執行,一直執行到事件隊列的尾部。期間主線程不斷的檢查事件隊列中是否有未執行的事件,直到事件隊列中所有事件都執行完,此后每當有新的事件加入到事件隊列中,都會通知主線程按順序取出交代碼循環處理。當有事件執行完畢后,會通知主線程,主線程執行回調,線程歸還給線程池。
以Java、C#為例,在Java、C#中也有辦法實現并行請求(利用子線程),但NodeJS通過回調函數(Callback)和異步機制,把I/O阻塞處理的更優雅(說人話就是用Code實現起來更簡單易懂,并且性能更好)。
說到這里,你可能就會問
說好的Node.js是單線程的呢?那Node.js怎么又創建子線程了呢?怎么就跟Java、C#中的線程不一樣了呢?怎么就更優雅了呢?
那就來解釋一波
Node.js使用異步IO和事件驅動(回調函數)來解決這個問題。
一般來說,高并發解決方案會提供多線程模型,為每個業務邏輯提供一個線程,通過系統線程切換來來彌補同步I/O調用的時間開銷。
像PHP,是一個請求一個線程,假如一個線程需要2M內存,那么同時有512個請求,就需要1G的內存,那同時有5120個請求,就需要10G內存,現在內存這么貴的情況下,想想都恐怖。。。
而Node.js使用的是單線程模型,對所有I/O都采用異步的請求方式,在Node.js執行的時候維護著一個事件隊列,程序在執行時進入事件循環等待下一個事件到來,每個異步I/O請求完成后都會被推送到事件隊列中的等待執行。
Node.js是因為是基于JavaScript的特性,所以單線程的,但是,單線程只局限于JavaScript部分,Node.js核心還是用C/C++語言編寫的,文章開頭就說到過,它只是給JavaScript提供了一個運行環境而已,它是JavaScript語言的解釋器。
我們所看到的Node.js單線程只是一個js主線程,本質上的異步操作還是由線程池完成的,Node.js將所有的阻塞操作都交給了內部的線程池去實現,本身只負責不斷的往返調度,并沒有進行真正的I/O操作,從而實現異步非阻塞I/O,這便是Node.js單線程和事件驅動的精髓之處了。
所以它跟Java、PHP、C#這些后臺語言的實現的線程不一樣的。
關于更優雅呢,主要就是實現起來更容易。比如說在Java、C#中實現多線程的時候,總是要注意線程安全,這里要Lock,那里也要Lock。
一個不注意就得加班熬夜好幾個通宵才能找出問題所在……
而Node.js卻是利用單線程執行,Node.js官方也是說不需要鎖。但是不需要鎖,不代表你可以亂來,不需要鎖的是代碼function,而不是你的資源!?這點要分清楚。
4
搭建我們第一個Node.js服務器
看了這么多基礎性的內容,枯燥、乏味,沒勁,看的想睡覺。
現在動手操作一波,刺激一下自己的腎上腺素,一起來搭建一個超簡單的Node.js服務器
//引用http模塊 ? ?const http=require('http'); ? ? ?//創建一個服務 ? ?//request:服務器接收的請求數據 ? ?//response:服務器發出的數據 ? ?let server=http.createServer((request, response)=>{ ? ? ?//判斷接收到的url ? ? ?switch(request.url){ ? ? ? ?case '/hello': ? ? ? ? ?response.write('hi'); ? ? ? ? ?break; ? ? ? ?case '/word': ? ? ? ? ?response.write('gun'); ? ? ? ? ?break; ? ? ? ?case '/bb.html': ? ? ? ? ?response.write ('<html><head></head><body>Talk is cheap,show me the code</body></html>'); ? ? ? ? ?break; ? ? ?} ? ? ?//關閉 ? ? ?response.end(); ? ?}); ? ?//服務器監聽的端口,填寫端口地址時,注意端口地址不能與其它應用程序沖突 ? ?server.listen(8000);
寫完代碼了,咋執行啊?
問的非常好!
這是今天的回家作業,自己想去。 鬧鬧狠狠的說到!
寫手聯盟介紹
北媽的小北鼻~寫手聯盟?開始試運行,歡迎廣大粉絲前來付費投稿,我要在一年時間培養出來一批優秀的貢獻者和牛逼干貨寫手,而且是有薪水的,文章入了我的法眼,就會給錢,你增長了能力,也變現賺了錢。
有興趣加我私人微信聯系。
熱門閱讀:
1、我為何一直強調外包公司別去?|?
2、北媽每日一題:經典面試題~我要燒繩子?|?
3、你為啥不敢裸辭??|?
每天只想聽你們說:小北最帥!
長按掃碼關注我
前端你別鬧
總結
以上是生活随笔為你收集整理的6分钟看懂 Node.js 武功精髓的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科大星云诗社动态20210120
- 下一篇: 科大星云诗社动态20210118