摘要:模式,單實(shí)例多進(jìn)程,常用于多語(yǔ)言混編,比如等,不支持端口復(fù)用,需要自己做應(yīng)用的端口分配和負(fù)載均衡的子進(jìn)程業(yè)務(wù)代碼。就是我們需要一個(gè)調(diào)度者,保證所有后端服務(wù)器都將性能充分發(fā)揮,從而保持服務(wù)器集群的整體性能最優(yōu),這就是負(fù)載均衡。
Node.js是從純前端走向更高階層的前端,以及全棧工程師的唯一快速途徑
簡(jiǎn)單的說(shuō)Node.js 就是運(yùn)行在服務(wù)端的 JavaScript
Node.js 是一個(gè)基于Chrome JavaScript 運(yùn)行時(shí)建立的一個(gè)平臺(tái)
Node.js是一個(gè)事件驅(qū)動(dòng)I/O服務(wù)端JavaScript環(huán)境,基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非???,性能非常好
如果你是一個(gè)前端程序員,你不懂得像PHP、Python或Ruby等動(dòng)態(tài)編程語(yǔ)言,然后你想創(chuàng)建自己的服務(wù),那么Node.js是一個(gè)非常好的選擇Node.js 是運(yùn)行在服務(wù)端的 JavaScript,如果你熟悉Javascript,那么你將會(huì)很容易的學(xué)會(huì)Node.js
當(dāng)然,如果你是后端程序員,想部署一些高性能的服務(wù),那么學(xué)習(xí)Node.js也是一個(gè)非常好的選擇
Node.JS適合運(yùn)用在高并發(fā)、I/O密集、少量業(yè)務(wù)邏輯的場(chǎng)景 Node.js的模塊組成如下: Node.js的運(yùn)行機(jī)制V8引擎解析JavaScript腳本
解析后的代碼,調(diào)用Node API
libuv庫(kù)負(fù)責(zé)Node API的執(zhí)行。它將不同的任務(wù)分配給不同的線程,形成一個(gè)EventLoop(事件循環(huán)),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給V8引擎。
V8引擎再將結(jié)果返回給用戶。
事件循環(huán)(Event Loop)Nodejs 執(zhí)行之后會(huì)初始化一個(gè)事件循環(huán),執(zhí)行代碼程序(這些程序可能會(huì)造成異步調(diào)用、定時(shí)器或者process.nextTick()),然后開始執(zhí)行事件循環(huán)。
事件循環(huán)的執(zhí)行循序:
上邊的每一個(gè)模塊都是事件循環(huán)的一個(gè)階段,每個(gè)階段都有一個(gè)要執(zhí)行的回調(diào)的FIFO隊(duì)列。雖然每個(gè)階段都不同,一般來(lái)說(shuō),當(dāng)事件執(zhí)行到一個(gè)階段,先執(zhí)行這個(gè)階段特有的操作,然后操作這個(gè)階段的隊(duì)列,當(dāng)隊(duì)列執(zhí)行完或者達(dá)到了回調(diào)上限,事件循環(huán)就會(huì)執(zhí)行下一個(gè)階段。
各個(gè)階段執(zhí)行的任務(wù)如下:
timers 階段: 這個(gè)階段執(zhí)行setTimeout和setInterval預(yù)定的callback;
I/O callbacks 階段: 執(zhí)行除了close事件的callbacks、被timers設(shè)定的callbacks、setImmediate()設(shè)定的callbacks這些之外的callbacks;
idle, prepare 階段: 僅node內(nèi)部使用;
poll 階段: 獲取新的I/O事件, 適當(dāng)?shù)臈l件下node將阻塞在這里;
check 階段: 執(zhí)行setImmediate() 設(shè)定的callbacks;
close callbacks 階段: 執(zhí)行socket.on("close", ...)這些 callback
process.nextTick()不屬于上面的任何一個(gè)phase,它在每個(gè)phase結(jié)束的時(shí)候都會(huì)運(yùn)行。也可以認(rèn)為,nextTick在下一個(gè)異步方法的事件回調(diào)函數(shù)調(diào)用前執(zhí)行。
TIPS: Node.js中的事件循環(huán)機(jī)制不會(huì)掉頭,只會(huì)由上往下,循環(huán)執(zhí)行。完整的一次執(zhí)行機(jī)制可以這樣描述
在Node.js中,絕大部分API都是異步的,有一個(gè)很形象的故事描述了JAVA和Node.js的區(qū)別,JAVA是一個(gè)餐廳100個(gè)服務(wù)員對(duì)應(yīng)100客戶,Node.js是一個(gè)服務(wù)員玩命干,也對(duì)應(yīng)100個(gè)客戶,上菜的速度很大一部分取決于廚師的做菜速度Node.js的單線程并不是真正的單線程,只是開啟了單個(gè)線程進(jìn)行業(yè)務(wù)處理(cpu的運(yùn)算),同時(shí)開啟了其他線程專門處理I/O。當(dāng)一個(gè)指令到達(dá)主線程,主線程發(fā)現(xiàn)有I/O之后,直接把這個(gè)事件傳給I/O線程,不會(huì)等待I/O結(jié)束后,再去處理下面的業(yè)務(wù),而是拿到一個(gè)狀態(tài)后立即往下走,這就是“單線程”、“異步I/O”。
I/O操作完之后呢?Node.js的I/O 處理完之后會(huì)有一個(gè)回調(diào)事件,這個(gè)事件會(huì)放在一個(gè)事件處理隊(duì)列里頭,在進(jìn)程啟動(dòng)時(shí)node會(huì)創(chuàng)建一個(gè)類似于While(true)的循環(huán),它的每一次輪詢都會(huì)去查看是否有事件需要處理,是否有事件關(guān)聯(lián)的回調(diào)函數(shù)需要處理,如果有就處理,然后加入下一個(gè)輪詢,如果沒(méi)有就退出進(jìn)程,這就是所謂的“事件驅(qū)動(dòng)”。這也從Node的角度解釋了什么是”事件驅(qū)動(dòng)”。
在node.js中,事件主要來(lái)源于網(wǎng)絡(luò)請(qǐng)求,文件I/O等,根據(jù)事件的不同對(duì)觀察者進(jìn)行了分類,有文件I/O觀察者,網(wǎng)絡(luò)I/O觀察者。事件驅(qū)動(dòng)是一個(gè)典型的生產(chǎn)者/消費(fèi)者模型,請(qǐng)求到達(dá)觀察者那里,事件循環(huán)從觀察者進(jìn)行消費(fèi),主線程就可以馬不停蹄的只關(guān)注業(yè)務(wù)不用再去進(jìn)行I/O等待。
優(yōu)點(diǎn): Node 公開宣稱的目標(biāo)是 “旨在提供一種簡(jiǎn)單的構(gòu)建可伸縮網(wǎng)絡(luò)程序的方法”。我們來(lái)看一個(gè)簡(jiǎn)單的例子,在 Java和 PHP 這類語(yǔ)言中,每個(gè)連接都會(huì)生成一個(gè)新線程,每個(gè)新線程可能需要2MB的配套內(nèi)存。在一個(gè)擁有8GBRAM的系統(tǒng)上,理論上最大的并發(fā)連接數(shù)量是4,000個(gè)用戶。隨著您的客戶群的增長(zhǎng),如果希望您的Web應(yīng)用程序支持更多用戶,那么,您必須添加更多服務(wù)器。所以在傳統(tǒng)的后臺(tái)開發(fā)中,整個(gè)Web應(yīng)用程序架構(gòu)(包括流量、處理器速度和內(nèi)存速度)中的瓶頸是:服務(wù)器能夠處理的并發(fā)連接的最大數(shù)量。這個(gè)不同的架構(gòu)承載的并發(fā)數(shù)量是不一致的。
而Node的出現(xiàn)就是為了解決這個(gè)問(wèn)題:更改連接到服務(wù)器的方式。在Node 聲稱它不允許使用鎖,它不會(huì)直接阻塞 I/O 調(diào)用。Node在每個(gè)連接發(fā)射一個(gè)在 Node 引擎的進(jìn)程中運(yùn)行的事件,而不是為每個(gè)連接生成一個(gè)新的 OS 線程(并為其分配一些配套內(nèi)存)。
缺點(diǎn):如上所述,nodejs的機(jī)制是單線程,這個(gè)線程里面,有一個(gè)事件循環(huán)機(jī)制,處理所有的請(qǐng)求。在事件處理過(guò)程中,它會(huì)智能地將一些涉及到IO、網(wǎng)絡(luò)通信等耗時(shí)比較長(zhǎng)的操作,交由worker-threads去執(zhí)行,執(zhí)行完了再回調(diào),這就是所謂的異步IO非阻塞吧。但是,那些非IO操作,只用CPU計(jì)算的操作,它就自己扛了,比如算什么斐波那契數(shù)列之類。它是單線程,這些自己扛的任務(wù)要一個(gè)接著一個(gè)地完成,前面那個(gè)沒(méi)完成,后面的只能干等。因此,對(duì)CPU要求比較高的CPU密集型任務(wù)多的話,就有可能會(huì)造成號(hào)稱高性能,適合高并發(fā)的node.js服務(wù)器反應(yīng)緩慢。
Node.js高并發(fā)使用Nginx+pm2,pm2中可以開啟多線程負(fù)載均衡,模式分兩種:pm2簡(jiǎn)介: PM2是node進(jìn)程管理工具,可以利用它來(lái)簡(jiǎn)化很多node應(yīng)用管理的繁瑣任務(wù),如性能監(jiān)控、自動(dòng)重啟、負(fù)載均衡等,而且使用非常簡(jiǎn)單。
下面就對(duì)PM2進(jìn)行入門性的介紹,基本涵蓋了PM2的常用的功能和配置。
fork模式,單實(shí)例多進(jìn)程,常用于多語(yǔ)言混編,比如php、python等,不支持端口復(fù)用,需要自己做應(yīng)用的端口分配和負(fù)載均衡的子進(jìn)程業(yè)務(wù)代碼。
缺點(diǎn)就是單服務(wù)器實(shí)例容易由于異常會(huì)導(dǎo)致服務(wù)器實(shí)例崩潰。
cluster模式,多實(shí)例多進(jìn)程,但是只支持node,端口可以復(fù)用,不需要額外的端口配置,0代碼實(shí)現(xiàn)負(fù)載均衡。
優(yōu)點(diǎn)就是由于多實(shí)例機(jī)制,可以保證服務(wù)器的容錯(cuò)性,就算出現(xiàn)異常也不會(huì)使多個(gè)服務(wù)器實(shí)例同時(shí)崩潰。
共同點(diǎn),由于都是多進(jìn)程,都需要消息機(jī)制或數(shù)據(jù)持久化來(lái)實(shí)現(xiàn)數(shù)據(jù)共享。
pm2部署,默認(rèn)開啟負(fù)載均衡:npm i pm2 -g
$ pm2 start app.js # 啟動(dòng)app.js應(yīng)用程序
$ pm2 start app.js -i 4 # cluster mode 模式啟動(dòng)4個(gè)app.js的應(yīng)用實(shí)例 # 4個(gè)應(yīng)用程序會(huì)自動(dòng)進(jìn)行負(fù)載均衡
pm2 start app.js -i max 根據(jù)你的cpu數(shù)量最大化啟動(dòng)多線程進(jìn)行負(fù)載均衡
如果要停止所有應(yīng)用,可以pm2 stop all
查看進(jìn)程狀態(tài) pm2 list
pm2真心很好很強(qiáng)大,可以在線熱更新代碼,更多的指令需要上官網(wǎng)看
pm2和Nginx配合pm2 + nginx
無(wú)非就是在nginx上做個(gè)反向代理配置,直接貼配置。
upstream my_nodejs_upstream { server 127.0.0.1:3001; } server { listen 80; server_name my_nodejs_server; root /home/www/project_root; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_max_temp_file_size 0; proxy_pass http://my_nodejs_upstream/; proxy_redirect off; proxy_read_timeout 240s; }
特別說(shuō)明,我們不建議使用Node.js作為底層服務(wù)器,更多時(shí)候作為中間件和接入層使用,例如Electron開發(fā)跨平臺(tái)應(yīng)用
Nginx開啟多線程,負(fù)載均衡
負(fù)載均衡的作用負(fù)載均衡:分?jǐn)偟蕉鄠€(gè)操作單元上進(jìn)行執(zhí)行,和它的英文名稱很匹配。就是我們需要一個(gè)調(diào)度者,保證所有后端服務(wù)器都將性能充分發(fā)揮,從而保持服務(wù)器集群的整體性能最優(yōu),這就是負(fù)載均衡。
負(fù)載均衡這里面涉及的東西相對(duì)也是比較多的,理論就不說(shuō)太多了,網(wǎng)上,書上很多,今天我們就利用Nginx服務(wù)器來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的負(fù)載均衡 負(fù)載均衡算法源地址哈希法:根據(jù)獲取客戶端的IP地址,通過(guò)哈希函數(shù)計(jì)算得到一個(gè)數(shù)值,用該數(shù)值對(duì)服務(wù)器列表的大小進(jìn)行取模運(yùn)算,得到的結(jié)果便是客服端要訪問(wèn)服務(wù)器的序號(hào)。采用源地址哈希法進(jìn)行負(fù)載均衡,同一IP地址的客戶端,當(dāng)后端服務(wù)器列表不變時(shí),它每次都會(huì)映射到同一臺(tái)后端服務(wù)器進(jìn)行訪問(wèn)。
輪詢法:將請(qǐng)求按順序輪流地分配到后端服務(wù)器上,它均衡地對(duì)待后端的每一臺(tái)服務(wù)器,而不關(guān)心服務(wù)器實(shí)際的連接數(shù)和當(dāng)前的系統(tǒng)負(fù)載。
隨機(jī)法:通過(guò)系統(tǒng)的隨機(jī)算法,根據(jù)后端服務(wù)器的列表大小值來(lái)隨機(jī)選取其中的一臺(tái)服務(wù)器進(jìn)行訪問(wèn)。
加權(quán)輪詢法:不同的后端服務(wù)器可能機(jī)器的配置和當(dāng)前系統(tǒng)的負(fù)載并不相同,因此它們的抗壓能力也不相同。給配置高、負(fù)載低的機(jī)器配置更高的權(quán)重,讓其處理更多的請(qǐng);而配置低、負(fù)載高的機(jī)器,給其分配較低的權(quán)重,降低其系統(tǒng)負(fù)載,加權(quán)輪詢能很好地處理這一問(wèn)題,并將請(qǐng)求順序且按照權(quán)重分配到后端。
加權(quán)隨機(jī)法:與加權(quán)輪詢法一樣,加權(quán)隨機(jī)法也根據(jù)后端機(jī)器的配置,系統(tǒng)的負(fù)載分配不同的權(quán)重。不同的是,它是按照權(quán)重隨機(jī)請(qǐng)求后端服務(wù)器,而非順序。
最小連接數(shù)法:由于后端服務(wù)器的配置不盡相同,對(duì)于請(qǐng)求的處理有快有慢,最小連接數(shù)法根據(jù)后端服務(wù)器當(dāng)前的連接情況,動(dòng)態(tài)地選取其中當(dāng)前積壓連接數(shù)最少的一臺(tái)服務(wù)器來(lái)處理當(dāng)前的請(qǐng)求,盡可能地提高后端服務(wù)的利用效率,將負(fù)責(zé)合理地分流到每一臺(tái)服務(wù)器。
下載Nginx,找到config文件夾下面的nginx.conf,修改下面配置文件
每個(gè)
upstream test{ server 11.22.333.11:6666 weight=1; server 11.22.333.22:8888 down; server 11.22.333.33:8888 backup; server 11.22.333.44:5555 weight=2; } //down 表示單前的server臨時(shí)不參與負(fù)載. //weight 默覺(jué)得1.weight越大,負(fù)載的權(quán)重就越大 //backup: 其他全部的非backup機(jī)器down或者忙的時(shí)候,請(qǐng)求backup機(jī)器。所以這臺(tái)機(jī)器壓力會(huì)最輕nginx命令匯總 :
nginx 服務(wù)器重啟命令,關(guān)閉 nginx -s reload :修改配置后重新加載生效 nginx -s reopen :重新打開日志文件 nginx -t -c /path/to/nginx.conf 測(cè)試nginx配置文件是否正確 關(guān)閉nginx: nginx -s stop :快速停止nginx quit :完整有序的停止nginx 其他的停止nginx 方式: ps -ef | grep nginx kill -QUIT 主進(jìn)程號(hào) :從容停止Nginx kill -TERM 主進(jìn)程號(hào) :快速停止Nginx pkill -9 nginx :強(qiáng)制停止Nginx 啟動(dòng)nginx: nginx -c /path/to/nginx.conf 平滑重啟nginx: kill -HUP 主進(jìn)程號(hào)在開啟Nginx多線程負(fù)載均衡和部署pm2負(fù)載均衡后的架構(gòu)圖:
第一種,Node.js作為底層服務(wù)器,直接操作數(shù)據(jù)庫(kù)的方式:
第二種,Node.js作為中間件,訪問(wèn)底層服務(wù)器的方式:
高并發(fā)下性能對(duì)比,Apache、Nginx 與 Node.js 之爭(zhēng)高并發(fā)下的性能測(cè)試對(duì)比:
參考文章 : 巨頭終極對(duì)決,Apache、Nginx 與 Node.js 之爭(zhēng)
所有的測(cè)試都在本地運(yùn)行:
英特爾酷睿 i7-2600k,四核八線程的機(jī)器
Gentoo Linux 是用于測(cè)試的操作系統(tǒng)
用于基準(zhǔn)測(cè)試的工具:ApacheBench,2.3 <$Revision: 1748469 $>
測(cè)試包括一系列基準(zhǔn),從 1000 到 10000 個(gè)請(qǐng)求以及從 100 到 1000 個(gè)的并發(fā)請(qǐng)求——結(jié)果相當(dāng)令人驚訝。
高并發(fā)測(cè)試結(jié)果對(duì)比:Apache、Nginx 與 Node 的對(duì)比:請(qǐng)求負(fù)載的性能(每 100 位并發(fā)用戶)
Apache、Nginx 與 Node 的對(duì)比:用戶負(fù)載能力(每 1000 個(gè)請(qǐng)求)
壓力測(cè)試
我們可以從結(jié)果中得到什么?
從以上結(jié)果判斷,似乎 Nginx 可以在最少的時(shí)間內(nèi)完成最多請(qǐng)求,換句話來(lái)說(shuō),Nginx 是最快的 HTTP 服務(wù)器。
還有一個(gè)相當(dāng)驚人的事實(shí)是,在特定的用戶并發(fā)數(shù)和請(qǐng)求數(shù)下,Node.js 可以比 Nginx 和 Apache 更快。
但當(dāng)請(qǐng)求的數(shù)量在并發(fā)測(cè)試中增加的時(shí)候,Nginx 將重回領(lǐng)先的位置,這個(gè)結(jié)果可以讓那些陷入 Node.js 的遐想的人清醒一下。
和 Apache、Nginx 不同的是,Node.js 似乎對(duì)用戶的并發(fā)數(shù)不太敏感,尤其是在集群節(jié)點(diǎn)。如圖所示,集群節(jié)點(diǎn)在 0.1 秒左右保持一條直線,而 Apache 和 Nginx 都有大約 0.2 秒的波動(dòng)。
基于上述統(tǒng)計(jì)可以得出的結(jié)論是:網(wǎng)站比較小,其使用的服務(wù)器就無(wú)所謂。然而,隨著網(wǎng)站的受眾越來(lái)越多,HTTP 服務(wù)器的影響變得愈加明顯。
當(dāng)涉及到每臺(tái)服務(wù)器的原始速度的底線的時(shí)候,正如壓力測(cè)試所描述的,我的感覺(jué)是,性能背后最關(guān)鍵的因素不是一些特定的算法,而實(shí)際上是運(yùn)行的每臺(tái)服務(wù)器所用的編程語(yǔ)言。
由于 Apache 和 Nginx 都使用了 C 語(yǔ)言—— AOT 語(yǔ)言(編譯型語(yǔ)言),而 Node.js 使用了 JavaScript ——這是一種 JIT 語(yǔ)言(解釋型語(yǔ)言)。這意味著 Node.js 在執(zhí)行程序的過(guò)程中還有額外的工作負(fù)擔(dān)。
這意味著我不能僅僅基于上面的結(jié)果來(lái)下結(jié)論,而要做進(jìn)一步校驗(yàn),正如你下面看到的結(jié)果,當(dāng)我使用一臺(tái)經(jīng)過(guò)優(yōu)化的 Node.js 服務(wù)器與流行的 Express 框架時(shí),我得到幾乎相同的性能結(jié)論。
全面考慮
逝者如斯夫,如果沒(méi)有服務(wù)的內(nèi)容,HTTP 服務(wù)器是沒(méi)什么用的。因此,在比較 we服務(wù)器的時(shí)候,我們必須考慮的一個(gè)重要的部分就是我們希望在上面運(yùn)行的內(nèi)容。
雖然也有其它的功能,但是 HTTP 服務(wù)器最廣泛的使用就是運(yùn)行網(wǎng)站。因此,為了看到每臺(tái)服務(wù)器的性能的實(shí)際效果,我決定比較一下世界上使用最廣泛的 CMS(內(nèi)容管理系統(tǒng))WordPress 和 Ghost —— 內(nèi)核使用了 JavaScript 的一顆冉冉升起的明星。
基于 JavaScript 的 Ghost 網(wǎng)頁(yè)能否勝過(guò)運(yùn)行在 PHP 和 Apache / Nginx 上面的 WordPress 頁(yè)面?
這是一個(gè)有趣的問(wèn)題,因?yàn)?Ghost 具有操作工具單一且一致的優(yōu)點(diǎn)——無(wú)需額外的封裝,而 WordPress 需要依賴 Apache / Nginx 和 PHP 之間的集成,這可能會(huì)導(dǎo)致顯著的性能缺陷。
除此之外,PHP 距 Node.js 之間還有一個(gè)顯著的性能落差,后者更佳,我將在下面簡(jiǎn)要介紹一下,可能會(huì)出現(xiàn)一些與初衷大相徑庭的結(jié)果。
PHP 與 Node.js 的對(duì)決
為了比較 WordPress 和 Ghost,我們必須首先考慮一個(gè)影響到兩者的基本組件。
基本上,WordPress 是一個(gè)基于 PHP 的 CMS,而 Ghost 是基于 Node.js(JavaScript)的。與 PHP 不同,Node.js 有以下優(yōu)點(diǎn):
非阻塞的 I/O
事件驅(qū)動(dòng)
更新穎、更少的殘舊代碼
由于有大量的測(cè)評(píng)文章解釋和演示了 Node.js 的原始速度超過(guò) PHP(包括 PHP 7),我不會(huì)再進(jìn)一步闡述這個(gè)主題,請(qǐng)你自行用谷歌搜索相關(guān)內(nèi)容。
因此,考慮到 Node.js 的性能優(yōu)于 PHP,一個(gè) Node.js 的網(wǎng)站的速度要比 Apache / Nginx 和 PHP 的網(wǎng)站快嗎?
WordPress 和 Ghost 對(duì)決
當(dāng)比較 WordPress 和 Ghost 時(shí),有些人會(huì)說(shuō)這就像比較蘋果和橘子,大多數(shù)情況下我同意這個(gè)觀點(diǎn),因?yàn)?WordPress 是一個(gè)完全成熟的 CMS,而 Ghost 基本上只是一個(gè)博客平臺(tái)。
然而,兩者仍然有共同競(jìng)爭(zhēng)的市場(chǎng),這兩者都可以用于向世界發(fā)布你的個(gè)人文章。
制定一個(gè)前提,我們?cè)趺幢容^兩個(gè)完全基于不同的代碼來(lái)運(yùn)行的平臺(tái),包括風(fēng)格主題和核心功能。
事實(shí)上,一個(gè)科學(xué)的實(shí)驗(yàn)測(cè)試條件是很難設(shè)計(jì)的。然而,在這個(gè)測(cè)試中我對(duì)更接近生活的情景更感興趣,所以 WordPress 和 Ghost 都將保留其主題。因此,這里的目標(biāo)是使兩個(gè)平臺(tái)的網(wǎng)頁(yè)大小盡可能相似,讓 PHP 和 Node.js 在幕后斗智斗勇。
由于結(jié)果是根據(jù)不同的標(biāo)準(zhǔn)進(jìn)行測(cè)量的,最重要的是尺度不一樣,因此在圖表中并排顯示它們是不公平的。因此,我改為使用表:
Node、Nginx、Apache 以及運(yùn)行 WordPress 和 Ghost 的比較。前兩行是 WordPress,底部的兩行是 Ghost
Node、Nginx、Apache 以及運(yùn)行 WordPress 和 Ghost 的比較。前兩行是 WordPress,底部的兩行是 Ghost
正如你所見,盡管事實(shí)上 Ghost(Node.js)正在加載一個(gè)更小的頁(yè)面(你可能會(huì)驚訝 1kb 可以產(chǎn)生這么大的差異),它仍然比同時(shí)使用 Nginx 和 Apache 的 WordPress 要慢。
此外,使用 Nginx 代理作為負(fù)載均衡器來(lái)接管每個(gè) Node 服務(wù)器的請(qǐng)求實(shí)際上會(huì)提升還是降低性能?
那么,根據(jù)上面的表格,如果說(shuō)它產(chǎn)生什么效果的話,它造成了更慢的效果——這是一個(gè)合理的結(jié)果,因?yàn)轭~外封裝一層理所當(dāng)然會(huì)使其變得更慢。當(dāng)然,上面的數(shù)字也表明這點(diǎn)差異可以忽略不計(jì)。
但是上表中最重要的一點(diǎn)是,即使 Node.js 比 PHP 快,HTTP 服務(wù)器的作用也可能超過(guò)某個(gè) web 平臺(tái)使用的編程語(yǔ)言的重要性。
當(dāng)然,另一方面,如果加載的頁(yè)面更多地依賴于服務(wù)器端的腳本處理,那么我懷疑結(jié)果可能會(huì)有點(diǎn)不同。
最后,如果一個(gè) web 平臺(tái)真的想在這場(chǎng)競(jìng)賽里擊敗 WordPress,從這個(gè)比較中得出的結(jié)論就是,要想性能占優(yōu),必須要定制一些像 PHP-FPM 的工具,它將直接與 JavaScript 通信(而不是作為服務(wù)器來(lái)運(yùn)行),因此它可以完全發(fā)揮 JavaScript 的力量來(lái)達(dá)到更好的性能。
Node.js的生態(tài)圈匯總:Node.js遵循commonJS規(guī)范,要說(shuō)它的生態(tài)圈,第一個(gè)肯定是webpack,用不好Node.js的人肯定用不好webpack,所以說(shuō)Node.js的一個(gè)突破初級(jí)前端工程師的好學(xué)習(xí)方向
express koa koa2 egg一系列的Node.js框架,在Restful架構(gòu)下使用,完成常規(guī)的一些http,ajax請(qǐng)求響應(yīng)
GraphQL,GraphQL 是一種 API 所使用的查詢語(yǔ)言,不止Node.js有,其他語(yǔ)言也有,不止可以查詢,還可以多數(shù)據(jù)庫(kù)CRUD操作,解決了一部分RestFul架構(gòu)帶來(lái)的問(wèn)題
mongodb,非關(guān)系型數(shù)據(jù)庫(kù),輕量級(jí)別數(shù)據(jù)庫(kù),目前Node.js配合使用的比較多的數(shù)據(jù)庫(kù),在Node.js中我們一般使用 mongoose這個(gè)庫(kù)來(lái)配合使用
sqlite,SQLite是一個(gè)進(jìn)程內(nèi)的庫(kù),實(shí)現(xiàn)了自給自足的、無(wú)服務(wù)器的、零配置的、事務(wù)性的 SQL 數(shù)據(jù)庫(kù)引擎。它是一個(gè)零配置的數(shù)據(jù)庫(kù),這意味著與其他數(shù)據(jù)庫(kù)一樣,您不需要在系統(tǒng)中配置。就像其他數(shù)據(jù)庫(kù),SQLite 引擎不是一個(gè)獨(dú)立的進(jìn)程,可以按應(yīng)用程序需求進(jìn)行靜態(tài)或動(dòng)態(tài)連接。SQLite 直接訪問(wèn)其存儲(chǔ)文件。
Electron,跨平臺(tái)桌面開發(fā),可以使用Node.js的API,V8的環(huán)境也被打包在內(nèi)。
C++插件,Node.js的V8環(huán)境就是C++寫的,自然也是可以使用C++插件
Redis,數(shù)據(jù)緩存層,Redis支持主從同步。數(shù)據(jù)可以從主服務(wù)器向任意數(shù)量的從服務(wù)器上同步,從服務(wù)器可以是關(guān)聯(lián)其他從服務(wù)器的主服務(wù)器。這使得Redis可執(zhí)行單層樹復(fù)制。存盤可以有意無(wú)意的對(duì)數(shù)據(jù)進(jìn)行寫操作。由于完全實(shí)現(xiàn)了發(fā)布/訂閱機(jī)制,使得從數(shù)據(jù)庫(kù)在任何地方同步樹時(shí),可訂閱一個(gè)頻道并接收主服務(wù)器完整的消息發(fā)布記錄。同步對(duì)讀取操作的可擴(kuò)展性和數(shù)據(jù)冗余很有幫助。
SSR, 以React為例,在中間層對(duì)代碼進(jìn)行注水,在客戶端對(duì)代碼脫水,實(shí)現(xiàn)部分首屏SSR,優(yōu)化首屏渲染時(shí)間。
websocket通訊等
puppeteer爬蟲
總結(jié)一下Node.jsNode.js在目前前端的開發(fā)中,是一項(xiàng)不可或缺的技能,它也是讓我們走向真正全棧工程師的路不那么陡峭
Node.js適用場(chǎng)景,非密集型計(jì)算型
Node.js最核心的部分不止是RestFul架構(gòu)的那一套接受請(qǐng)求,返回?cái)?shù)據(jù)。還有文件IO,流,Buffer,redis層這一類的操作
Node.js配合Nginx進(jìn)行負(fù)載均衡,不僅能提升性能,更能替后端真正減輕很多負(fù)擔(dān),完成許多特定的需求。
Node.js在做接入層,比如Electron中,可以調(diào)用很多Node API,完成渲染進(jìn)程不能做的事情,例如文件io,buffer操作等
今天由于時(shí)間有限,很多東西都沒(méi)有細(xì)化下去寫,可能還是有不少漏掉的,以后都會(huì)慢慢補(bǔ)上,走過(guò)路過(guò),點(diǎn)點(diǎn)贊,咱們永遠(yuǎn)都是A
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/54005.html
摘要:模式,單實(shí)例多進(jìn)程,常用于多語(yǔ)言混編,比如等,不支持端口復(fù)用,需要自己做應(yīng)用的端口分配和負(fù)載均衡的子進(jìn)程業(yè)務(wù)代碼。就是我們需要一個(gè)調(diào)度者,保證所有后端服務(wù)器都將性能充分發(fā)揮,從而保持服務(wù)器集群的整體性能最優(yōu),這就是負(fù)載均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
摘要:模式,單實(shí)例多進(jìn)程,常用于多語(yǔ)言混編,比如等,不支持端口復(fù)用,需要自己做應(yīng)用的端口分配和負(fù)載均衡的子進(jìn)程業(yè)務(wù)代碼。就是我們需要一個(gè)調(diào)度者,保證所有后端服務(wù)器都將性能充分發(fā)揮,從而保持服務(wù)器集群的整體性能最優(yōu),這就是負(fù)載均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
摘要:調(diào)用通過(guò)注冊(cè)表調(diào)用到實(shí)例,透過(guò)的,調(diào)用到中的,最后通過(guò),調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語(yǔ)法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對(duì)于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問(wèn)題和優(yōu)化...
摘要:調(diào)用通過(guò)注冊(cè)表調(diào)用到實(shí)例,透過(guò)的,調(diào)用到中的,最后通過(guò),調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語(yǔ)法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對(duì)于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問(wèn)題和優(yōu)化...
閱讀 1372·2021-11-24 09:39
閱讀 1361·2021-11-04 16:12
閱讀 2704·2021-09-24 09:47
閱讀 3350·2021-09-01 10:50
閱讀 1490·2019-08-30 15:55
閱讀 1438·2019-08-30 15:43
閱讀 656·2019-08-30 11:08
閱讀 3591·2019-08-23 18:33