• <abbr id="chdyf"></abbr>
    <ruby id="chdyf"><acronym id="chdyf"><meter id="chdyf"></meter></acronym></ruby>
    <bdo id="chdyf"></bdo>
    <dfn id="chdyf"><menu id="chdyf"></menu></dfn>
    1. <menuitem id="chdyf"></menuitem><strong id="chdyf"><menu id="chdyf"></menu></strong>

      <rt id="chdyf"><menu id="chdyf"></menu></rt>
      成人小说一区二区三区,伊人精品成人久久综合全集观看,久久HEZYO色综合,中文字幕精品人妻熟女,影音先锋成人网站,我要看免费一级毛片,中国女人做爰A片,中文字幕av久久爽Av

      NodeJS服務(wù)總是崩潰的解決辦法

      2020-3-23    seo達(dá)人

      許多人都有這樣一種映像,NodeJS比較快; 但是因?yàn)槠涫菃尉€(xiàn)程,所以它不穩(wěn)定,有點(diǎn)不安全,不適合處理復(fù)雜業(yè)務(wù); 它比較適合對(duì)并發(fā)要求比較高,而且簡(jiǎn)單的業(yè)務(wù)場(chǎng)景。 

      在Express的作者的TJ Holowaychuk的 告別Node.js一文中列舉了以下罪狀: 

      Farewell NodeJS (TJ Holowaychuk) 

      ?   you may get duplicate callbacks 
      ?   you may not get a callback at all (lost in limbo) 
      ?   you may get out-of-band errors 
      ?   emitters may get multiple “error” events 
      ?   missing “error” events sends everything to hell 
      ?   often unsure what requires “error” handlers 
      ?   “error” handlers are very verbose 
      ?   callbacks suck 

      其實(shí)這幾條主要吐嘈了兩點(diǎn): node.js錯(cuò)誤處理很扯蛋,node.js的回調(diào)也很扯蛋。

       

       

      事實(shí)上呢?

       


      事實(shí)上NodeJS里程確實(shí)有“脆弱”的一面,單線(xiàn)程的某處產(chǎn)生了“未處理的”異常確實(shí)會(huì)導(dǎo)致整個(gè)Node.JS的崩潰退出,來(lái)看個(gè)例子, 這里有一個(gè)node-error.js的文件: 

       

      var http = require('http');
      
      var server = http.createServer(function (req, res) {
      
        //這里有個(gè)錯(cuò)誤,params 是 undefined
        var ok = req.params.ok;
      
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World
      ');
      });
      
      server.listen(8080, '127.0.0.1');
      
      console.log('Server running at http://127.0.0.1:8080/');


      啟動(dòng)服務(wù),并在地址欄測(cè)試一下發(fā)現(xiàn) http://127.0.0.1:8080/  不出所料,node崩潰了 


       

      $ node node-error
      Server running at http://127.0.0.1:8080/
      
      c:githubscript
      ode-error.js:5
        var ok = req.params.ok;
                           ^
      TypeError: Cannot read property 'ok' of undefined
          at Server.<anonymous> (c:githubscript
      ode-error.js:5:22)
          at Server.EventEmitter.emit (events.js:98:17)
          at HTTPParser.parser.onIncoming (http.js:2108:12)
          at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
          at Socket.socket.ondata (http.js:1966:22)
          at TCP.onread (net.js:525:27)



       

      怎么解決呢?


      其實(shí)Node.JS發(fā)展到今天,如果連這個(gè)問(wèn)題都解決不了,那估計(jì)早就沒(méi)人用了。 

       

      使用uncaughtException


      我們可以u(píng)ncaughtException來(lái)全局捕獲未捕獲的Error,同時(shí)你還可以將此函數(shù)的調(diào)用棧打印出來(lái),捕獲之后可以有效防止node進(jìn)程退出,如: 

       

      process.on('uncaughtException', function (err) {
        //打印出錯(cuò)誤
        console.log(err);
        //打印出錯(cuò)誤的調(diào)用棧方便調(diào)試
        console.log(err.stack);
      });


      這相當(dāng)于在node進(jìn)程內(nèi)部進(jìn)行守護(hù), 但這種方法很多人都是不提倡的,說(shuō)明你還不能完全掌控Node.JS的異常。 

       

      使用 try/catch


      我們還可以在回調(diào)前加try/catch,同樣確保線(xiàn)程的安全。 

       

      var http = require('http');
      
      http.createServer(function(req, res) {
        try {
          handler(req, res);
        } catch(e) {
          console.log('
      ', e, '
      ', e.stack);
          try {
            res.end(e.stack);
          } catch(e) { }
        }
      }).listen(8080, '127.0.0.1');
      
      console.log('Server running at http://127.0.0.1:8080/');
      
      var handler = function (req, res) {
        //Error Popuped
        var name = req.params.name;
      
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello ' + name);
      };


      這種方案的好處是,可以將錯(cuò)誤和調(diào)用棧直接輸出到當(dāng)前發(fā)生的網(wǎng)頁(yè)上。 

       

      集成到框架中


      標(biāo)準(zhǔn)的HTTP響應(yīng)處理會(huì)經(jīng)歷一系列的Middleware(HttpModule),最終到達(dá)Handler,如下圖所示: 

      \ 


      這 些Middleware和Handler在NodeJS中都有一個(gè)特點(diǎn),他們都是回調(diào)函數(shù),而回調(diào)函數(shù)中是唯一會(huì)讓Node在運(yùn)行時(shí)崩潰的地方。根據(jù)這個(gè) 特點(diǎn),我們只需要在框架中集成一處try/catch就可以相對(duì)完美地解決異常問(wèn)題,而且不會(huì)影響其它用戶(hù)的請(qǐng)求request。 

      事實(shí)上現(xiàn)在的NodeJS WEB框架幾乎都是這么做的,如 OurJS開(kāi)源博客所基于的 WebSvr 

      就有這么一處異常處理代碼: 

       

      Line: 207
      
        try {
          handler(req, res);
        } catch(err) {
          var errorMsg
            = '
      '
            + 'Error ' + new Date().toISOString() + ' ' + req.url
            + '
      '
            + err.stack || err.message || 'unknow error'
            + '
      '
            ;
      
          console.error(errorMsg);
          Settings.showError
            ? res.end('<pre>' + errorMsg + '</pre>')
            : res.end();
        }


      那么不在回調(diào)中產(chǎn)生的錯(cuò)誤怎么辦?不必?fù)?dān)心,其實(shí)這樣的node程序根本就起不起來(lái)。 

      此外node自帶的 cluster 也有一定的容錯(cuò)能力,它跟nginx的worker很類(lèi)似,但消耗資源(內(nèi)存)略大,編程也不是很方便,OurJS并沒(méi)有采用此種設(shè)計(jì)。 

       

      守護(hù)NodeJS進(jìn)程和記錄錯(cuò)誤日志


      現(xiàn) 在已經(jīng)基本上解決了Node.JS因異常而崩潰的問(wèn)題,不過(guò)任何平臺(tái)都不是100%可靠的,還有一些錯(cuò)誤是從Node底層拋出的,有些異常 try/catch和uncaughtException都無(wú)法捕獲。之前在運(yùn)行ourjs的時(shí)侯,會(huì)偶爾碰到底層拋出的文件流讀取異常,這就是一個(gè)底層 libuv的BUG,node.js在0.10.21中進(jìn)行了修復(fù)。 

      面對(duì)這種情況,我們就應(yīng)該為nodejs應(yīng)用添加守護(hù)進(jìn)程,讓NodeJS遭遇異常崩潰以后能馬上復(fù)活。 

      另外,還應(yīng)該把這些產(chǎn)生的異常記錄到日志中,并讓異常永遠(yuǎn)不再發(fā)生。 

       

      使用node來(lái)守護(hù)node


      node-forever 提供了守護(hù)的功能和LOG日志記錄功能。 

      安裝非常容易 

       

      [sudo] npm install forever


      使用也很簡(jiǎn)單 

       

      $ forever start simple-server.js
      $ forever list
        [0] simple-server.js [ 24597, 24596 ]


      還可以看日志 

       

      forever -o out.log -e err.log my-script.js


       

      使用shell啟動(dòng)腳本守護(hù)node


      使用node來(lái)守護(hù)的話(huà)資源開(kāi)銷(xiāo)可能會(huì)有點(diǎn)大,而且也會(huì)略顯復(fù)雜,OurJS直接在開(kāi)機(jī)啟動(dòng)腳本來(lái)進(jìn)程線(xiàn)程守護(hù)。 

      如在debian中放置的 ourjs 開(kāi)機(jī)啟動(dòng)文件: /etc/init.d/ourjs 

      這個(gè)文件非常簡(jiǎn)單,只有啟動(dòng)的選項(xiàng),守護(hù)的核心功能是由一個(gè)無(wú)限循環(huán) while true; 來(lái)實(shí)現(xiàn)的,為了防止過(guò)于密集的錯(cuò)誤阻塞進(jìn)程,每次錯(cuò)誤后間隔1秒重啟服務(wù) 

       

      WEB_DIR='/var/www/ourjs'
      WEB_APP='svr/ourjs.js'
      
      #location of node you want to use
      NODE_EXE=/root/local/bin/node
      
      while true; do
          {
              $NODE_EXE $WEB_DIR/$WEB_APP config.magazine.js
              echo "Stopped unexpected, restarting 
      
      "
          } 2>> $WEB_DIR/error.log
          sleep 1
      done


       

      錯(cuò)誤日志記錄也非常簡(jiǎn)單,直接將此進(jìn)程控制臺(tái)當(dāng)中的錯(cuò)誤輸出到error.log文件即可: 2>> $WEB_DIR/error.log  這一行, 2 代表 Error。

      日歷

      鏈接

      個(gè)人資料

      存檔