欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Node.js配合Nginx實(shí)現(xiàn)高負(fù)載網(wǎng)絡(luò)

 更新時(shí)間:2015年06月28日 11:27:47   投稿:goldensun  
這篇文章主要介紹了使用Node.js配合Nginx實(shí)現(xiàn)高負(fù)載網(wǎng)絡(luò),Node的異步加上Nginx的反向代理在性能上實(shí)在是給力!需要的朋友可以參考下

 在搭建高吞吐量web應(yīng)用這個(gè)議題上,NginX和Node.js可謂是天生一對(duì)。他們都是基于事件驅(qū)動(dòng)模型而設(shè)計(jì),可以輕易突破Apache等傳統(tǒng)web服務(wù)器的C10K瓶頸。預(yù)設(shè)的配置已經(jīng)可以獲得很高的并發(fā),不過(guò),要是大家想在廉價(jià)硬件上做到每秒數(shù)千以上的請(qǐng)求,還是有一些工作要做的。

這篇文章假定讀者們使用NginX的HttpProxyModule來(lái)為上游的node.js服務(wù)器充當(dāng)反向代理。我們將介紹Ubuntu 10.04以上系統(tǒng)sysctl的調(diào)優(yōu),以及node.js應(yīng)用與NginX的調(diào)優(yōu)。當(dāng)然,如果大家用的是Debian系統(tǒng),也能達(dá)到同樣的目標(biāo),只不過(guò)調(diào)優(yōu)的方法有所不同而已。

網(wǎng)絡(luò)調(diào)優(yōu)

如果不先對(duì)Nginx和Node.js的底層傳輸機(jī)制有所了解,并進(jìn)行針對(duì)性?xún)?yōu)化,可能對(duì)兩者再細(xì)致的調(diào)優(yōu)也會(huì)徒勞無(wú)功。一般情況下,Nginx通過(guò)TCP socket來(lái)連接客戶(hù)端與上游應(yīng)用。

我們的系統(tǒng)對(duì)TCP有許多門(mén)限值與限制,通過(guò)內(nèi)核參數(shù)來(lái)設(shè)定。這些參數(shù)的默認(rèn)值往往是為一般的用途而定的,并不能滿(mǎn)足web服務(wù)器所需的高流量、短生命的要求。


這里列出了調(diào)優(yōu)TCP可供候選的一些參數(shù)。為使它們生效,可以將它們放在/etc/sysctl.conf文件里,或者放入一個(gè)新配置文件,比如/etc/sysctl.d/99-tuning.conf,然后運(yùn)行sysctl -p,讓內(nèi)核裝載它們。我們是用sysctl-cookbook來(lái)干這個(gè)體力活。

需要注意的是,這里列出來(lái)的值是可以安全使用的,但還是建議大家研究一下每個(gè)參數(shù)的含義,以便根據(jù)自己的負(fù)荷、硬件和使用情況選擇一個(gè)更加合適的值。

復(fù)制代碼 代碼如下:
net.ipv4.ip_local_port_range='1024 65000'
net.ipv4.tcp_tw_reuse='1'
net.ipv4.tcp_fin_timeout='15'
net.core.netdev_max_backlog='4096'
net.core.rmem_max='16777216'
net.core.somaxconn='4096'
net.core.wmem_max='16777216'
net.ipv4.tcp_max_syn_backlog='20480'
net.ipv4.tcp_max_tw_buckets='400000'
net.ipv4.tcp_no_metrics_save='1'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_syn_retries='2'
net.ipv4.tcp_synack_retries='2'
net.ipv4.tcp_wmem='4096 65536 16777216'
vm.min_free_kbytes='65536'

重點(diǎn)說(shuō)明其中幾個(gè)重要的。

復(fù)制代碼 代碼如下:
net.ipv4.ip_local_port_range

為了替上游的應(yīng)用服務(wù)下游的客戶(hù)端,NginX必須打開(kāi)兩條TCP連接,一條連接客戶(hù)端,一條連接應(yīng)用。在服務(wù)器收到很多連接時(shí),系統(tǒng)的可用端口將很快被耗盡。通過(guò)修改net.ipv4.ip_local_port_range參數(shù),可以將可用端口的范圍改大。如果在/var/log/syslog中發(fā)現(xiàn)有這樣的錯(cuò)誤: “possible SYN flooding on port 80. Sending cookies”,即表明系統(tǒng)找不到可用端口。增大net.ipv4.ip_local_port_range參數(shù)可以減少這個(gè)錯(cuò)誤。

復(fù)制代碼 代碼如下:
net.ipv4.tcp_tw_reuse

當(dāng)服務(wù)器需要在大量TCP連接之間切換時(shí),會(huì)產(chǎn)生大量處于TIME_WAIT狀態(tài)的連接。TIME_WAIT意味著連接本身是關(guān)閉的,但資源還沒(méi)有釋放。將net_ipv4_tcp_tw_reuse設(shè)置為1是讓內(nèi)核在安全時(shí)盡量回收連接,這比重新建立新連接要便宜得多。

復(fù)制代碼 代碼如下:
net.ipv4.tcp_fin_timeout

這是處于TIME_WAIT狀態(tài)的連接在回收前必須等待的最小時(shí)間。改小它可以加快回收。
如何檢查連接狀態(tài)

使用netstat:

復(fù)制代碼 代碼如下:
netstat -tan | awk '{print $6}' | sort | uniq -c

或使用ss:

復(fù)制代碼 代碼如下:
ss -s

NginX

隨著web服務(wù)器的負(fù)載逐漸升高,我們就會(huì)開(kāi)始遭遇NginX的某些奇怪限制。連接被丟棄,內(nèi)核不停報(bào)SYN flood。而這時(shí),平均負(fù)荷和CPU使用率都很小,服務(wù)器明明是可以處理更多連接的狀態(tài),真令人沮喪。

經(jīng)過(guò)調(diào)查,發(fā)現(xiàn)有非常多處于TIME_WAIT狀態(tài)的連接。這是其中一個(gè)服務(wù)器的輸出:

復(fù)制代碼 代碼如下:
ss -s
Total: 388 (kernel 541)
TCP:   47461 (estab 311, closed 47135, orphaned 4, synrecv 0, timewait 47135/0), ports 33938

Transport Total     IP        IPv6
*          541       -         -       
RAW        0         0         0       
UDP        13        10        3       
TCP        326       325       1       
INET       339       335       4       
FRAG       0         0         0


有47135個(gè)TIME_WAIT連接!而且,從ss可以看出,它們都是已經(jīng)關(guān)閉的連接。這說(shuō)明,服務(wù)器已經(jīng)消耗了絕大部分可用端口,同時(shí)也暗示我們,服務(wù)器是為每個(gè)連接都分配了新端口。調(diào)優(yōu)網(wǎng)絡(luò)對(duì)這個(gè)問(wèn)題有一點(diǎn)幫助,但是端口仍然不夠用。

經(jīng)過(guò)繼續(xù)研究,我找到了一個(gè)關(guān)于上行連接keepalive指令的文檔,它寫(xiě)道:

  •     設(shè)置通往上游服務(wù)器的最大空閑?;钸B接數(shù),這些連接會(huì)被保留在工作進(jìn)程的緩存中。

有趣。理論上,這個(gè)設(shè)置是通過(guò)在緩存的連接上傳遞請(qǐng)求來(lái)盡可能減少連接的浪費(fèi)。文檔中還提到,我們應(yīng)該把proxy_http_version設(shè)為"1.1",并清除"Connection"頭部。經(jīng)過(guò)進(jìn)一步的研究,我發(fā)現(xiàn)這是一種很好的想法,因?yàn)镠TTP/1.1相比HTTP1.0,大大優(yōu)化了TCP連接的使用率,而Nginx默認(rèn)用的是HTTP/1.0。

按文檔的建議修改后,我們的上行配置文件變成這樣:

復(fù)制代碼 代碼如下:
upstream backend_nodejs {
  server nodejs-3:5016 max_fails=0 fail_timeout=10s;
  server nodejs-4:5016 max_fails=0 fail_timeout=10s;
  server nodejs-5:5016 max_fails=0 fail_timeout=10s;
  server nodejs-6:5016 max_fails=0 fail_timeout=10s;
  keepalive 512;
}

我還按它的建議修改了server一節(jié)的proxy設(shè)置。同時(shí),加了一個(gè) p roxy_next_upstream來(lái)跳過(guò)故障的服務(wù)器,調(diào)整了客戶(hù)端的 keepalive_timeout,并關(guān)閉訪(fǎng)問(wèn)日志。配置變成這樣:

復(fù)制代碼 代碼如下:
server {
  listen 80;
  server_name fast.gosquared.com;

  client_max_body_size 16M;
  keepalive_timeout 10;

  location / {
    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    proxy_set_header   Connection "";
    proxy_http_version 1.1;
    proxy_pass http://backend_nodejs;
  }

  access_log off;
  error_log /dev/null crit;
}

采用新的配置后,我發(fā)現(xiàn)服務(wù)器們占用的socket 降低了90%?,F(xiàn)在可以用少得多的連接來(lái)傳輸請(qǐng)求了。新的輸出如下:

復(fù)制代碼 代碼如下:
ss -s

Total: 558 (kernel 604)
TCP:   4675 (estab 485, closed 4183, orphaned 0, synrecv 0, timewait 4183/0), ports 2768

Transport Total     IP        IPv6
*          604       -         -       
RAW        0         0         0       
UDP        13        10        3       
TCP        492       491       1       
INET       505       501       4

Node.js

得益于事件驅(qū)動(dòng)式設(shè)計(jì)可以異步處理I/O,Node.js開(kāi)箱即可處理大量的連接和請(qǐng)求。雖然有其它一些調(diào)優(yōu)手段,但這篇文章將主要關(guān)注node.js的進(jìn)程方面。

Node是單線(xiàn)程的,不會(huì)自動(dòng)使用多核。也就是說(shuō),應(yīng)用不能自動(dòng)獲得服務(wù)器的全部能力。

實(shí)現(xiàn)Node進(jìn)程的集群化

我們可以修改應(yīng)用,讓它fork多個(gè)線(xiàn)程,在同一個(gè)端口上接收數(shù)據(jù),從而實(shí)現(xiàn)負(fù)載的跨越多核。Node有一個(gè)cluster模塊,提供了實(shí)現(xiàn)這個(gè)目標(biāo)所必需的所有工具,但要將它們加入應(yīng)用中還需要很多體力活。如果你用的是express,eBay有一個(gè)叫cluster2的模塊可以用。

防止上下文切換

當(dāng)運(yùn)行多個(gè)進(jìn)程時(shí),應(yīng)該確保每個(gè)CPU核同一時(shí)間只忙于一個(gè)進(jìn)程。一般來(lái)說(shuō),如果CPU有N個(gè)核,我們應(yīng)該生成N-1個(gè)應(yīng)用進(jìn)程。這樣可以確保每個(gè)進(jìn)程都能得到合理的時(shí)間片,而剩下的一個(gè)核留給內(nèi)核調(diào)度程序運(yùn)行其它任務(wù)。我們還要確保服務(wù)器上基本不執(zhí)行除Node.js外的其它任務(wù),防止出現(xiàn)CPU的爭(zhēng)用。

我們?cè)?jīng)犯過(guò)一個(gè)錯(cuò)誤,在服務(wù)器上部署了兩個(gè)node.js應(yīng)用,然后每個(gè)應(yīng)用都開(kāi)了N-1個(gè)進(jìn)程。結(jié)果,它們互相之間搶奪CPU,導(dǎo)致系統(tǒng)的負(fù)荷急升。雖然我們的服務(wù)器都是8核的機(jī)器,但仍然可以明顯地感覺(jué)到由上下文切換引起的性能開(kāi)銷(xiāo)。上下文切換是指CPU為了執(zhí)行其它任務(wù)而掛起當(dāng)前任務(wù)的現(xiàn)象。在切換時(shí),內(nèi)核必須掛起當(dāng)前進(jìn)程的所有狀態(tài),然后裝載和執(zhí)行另一個(gè)進(jìn)程。為了解決這個(gè)問(wèn)題,我們減少了每個(gè)應(yīng)用開(kāi)啟的進(jìn)程數(shù),讓它們公平地分享CPU,結(jié)果系統(tǒng)負(fù)荷就降了下來(lái):

2015628112206774.png (802×404)

請(qǐng)注意上圖,看系統(tǒng)負(fù)荷(藍(lán)線(xiàn))是如何降到CPU核數(shù)(紅線(xiàn))以下的。在其它服務(wù)器上,我們也看到了同樣的情況。既然總的工作量保持不變,那么上圖中的性能改善只能歸功于上下文切換的減少。

相關(guān)文章

  • Node.js的Koa實(shí)現(xiàn)JWT用戶(hù)認(rèn)證方法

    Node.js的Koa實(shí)現(xiàn)JWT用戶(hù)認(rèn)證方法

    本篇文章主要介紹了Node.js的Koa實(shí)現(xiàn)JWT用戶(hù)認(rèn)證方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 詳解一個(gè)基于套接字實(shí)現(xiàn)長(zhǎng)連接的express

    詳解一個(gè)基于套接字實(shí)現(xiàn)長(zhǎng)連接的express

    這篇文章主要介紹了詳解一個(gè)基于套接字實(shí)現(xiàn)長(zhǎng)連接的express,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • nodejs初步體驗(yàn)篇

    nodejs初步體驗(yàn)篇

    這篇文章主要介紹了nodejs初步體驗(yàn)篇的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • Node.js內(nèi)置模塊events事件監(jiān)聽(tīng)發(fā)射詳解

    Node.js內(nèi)置模塊events事件監(jiān)聽(tīng)發(fā)射詳解

    這篇文章主要為大家介紹了Node.js內(nèi)置模塊events事件監(jiān)聽(tīng)發(fā)射詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • nodejs 搭建簡(jiǎn)易服務(wù)器的圖文教程(推薦)

    nodejs 搭建簡(jiǎn)易服務(wù)器的圖文教程(推薦)

    下面小編就為大家?guī)?lái)一篇nodejs 搭建簡(jiǎn)易服務(wù)器的圖文教程(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Node.js操作MongoDB數(shù)據(jù)庫(kù)實(shí)例分析

    Node.js操作MongoDB數(shù)據(jù)庫(kù)實(shí)例分析

    這篇文章主要介紹了Node.js操作MongoDB數(shù)據(jù)庫(kù),結(jié)合實(shí)例形式分析了node.js連接MongoDB數(shù)據(jù)庫(kù)以及增刪改查等相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01
  • node.js平臺(tái)下的mysql數(shù)據(jù)庫(kù)配置及連接

    node.js平臺(tái)下的mysql數(shù)據(jù)庫(kù)配置及連接

    本文主要介紹了node.js平臺(tái)下的mysql數(shù)據(jù)庫(kù)配置及連接的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-03-03
  • Nodejs?Socket連接池及TCP?HTTP網(wǎng)絡(luò)模型詳解

    Nodejs?Socket連接池及TCP?HTTP網(wǎng)絡(luò)模型詳解

    這篇文章主要為大家介紹了Nodejs?Socket連接池及TCP?HTTP網(wǎng)絡(luò)模型,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 學(xué)習(xí)使用ExpressJS 4.0中的新Router的用法

    學(xué)習(xí)使用ExpressJS 4.0中的新Router的用法

    ExpressJS 4.0中提出了新的路由Router,提供了路由應(yīng)有的API,本文詳細(xì)的介紹了ExpressJS 4.0中的新Router的用法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-11-11
  • Node.js Sequelize如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫(xiě)分離

    Node.js Sequelize如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫(xiě)分離

    Sequelize是一個(gè)易于使用,支持多SQL方言(dialect)的對(duì)象-關(guān)系映射框架(ORM),這個(gè)庫(kù)完全采用JavaScript開(kāi)發(fā)并且能夠用在Node.JS環(huán)境中。它當(dāng)前支持MySQL, MariaDB, SQLite 和 PostgreSQL 數(shù)據(jù)庫(kù)。在Node.js中,使用 Sequelize操作數(shù)據(jù)庫(kù)時(shí),同樣支持讀寫(xiě)分離。
    2016-10-10

最新評(píng)論