1. 程式人生 > >使用Nodejs 的http-proxy 模組做代理伺服器的嘗試

使用Nodejs 的http-proxy 模組做代理伺服器的嘗試

我今天突然想到一個問題,如果使用nginx 作為nodejs 的代理伺服器,那麼如果nodejs的應用需要進行升級的話,如何實現熱更新。

  第一種辦法:使用nodejs搭建一個代理伺服器,通過對請求的監聽來判斷當前的nodejs服務例項的工作情況(有多少未處理完的請求)來過濾請求,比如我有三個服務例項,1,2,3,我現在想進行升級,需要對服務進行重啟,但是三個例項不能同時重啟,這個時候,就需要這個代理伺服器進行一個判定,通過這個代理伺服器,可以看到每個例項當前的在處理的請求數量,同時也可以指定哪個程序進行斷後,哪些 程序進行結束通話,當然結束通話的步驟是:先由代理伺服器切斷請求,不在給該程序傳送新的請求,同時,代理伺服器隨時監聽這些被“判死刑”的程序的請求數量的數量,如果沒有請求的掛起,那就重啟。當這些程序重啟完成以後,這個斷後的程序按照以上的步驟進行重啟。 代理伺服器的核心程式碼如下。

var http = require('http'),
    httpProxy = require('http-proxy');

//
// Create a proxy server with latency
//
var proxy = httpProxy.createProxyServer();

var reqNum  = 0; // 快取目前請求的數量



proxy.on("proxyRes",()=>{
    reqNum --;
    console.log("完成一個請求,當前的剩餘的請求數量是 "+reqNum);
})
proxy.on("proxyReq",()=>{
    reqNum++;
    console.log("接收到一個請求,當前的請求數量是 "+reqNum);
})

//
// Create your server that makes an operation that waits a while
// and then proxies the request
//
http.createServer(function (req, res) {
    // This simulates an operation that takes 500ms to execute
    setTimeout(function () {
        proxy.web(req, res, {
            target: 'http://localhost:9008'
        },(e)=>{
           console.log("proxy error call back ");
           console.log(e);
        });
    }, 10);
}).listen(8008);

//
// Create your target server
//
http.createServer(function (req, res) {
    setTimeout(()=>{
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
        res.end();
    },10*1000)
}).listen(9008);

第二種辦法:更改nginx的配置檔案,比如,我的nginx代理了 82、81 這兩個內部的服務程式,現在我想升級,這兩個服務都需要重啟,做法可以是這樣的,再重啟兩個程序,埠分別是 83,,84。 同時更改nginx的配置檔案,分別代理 83,84,但是更改完成之後需要平滑重啟。這種方式比較上面的簡單很多,也不用自己寫程式實現。

總結:我還是回到了程式設計師的思維,一想到什麼事情,首先得第一反應就是自己能不能開發一個程式來解決問題,沒思考現有的程式、工具是否能夠完成這個事情。雖然在思考如何實現的過程中,我也能學習很多的東西,比如http-proxy的使用,但是這不應該是我的第一個反應,而是其次的反應。