2016-08-18 38 views
0

我建立節點JSNode.js的HTTP代理集羣內的工人

var cluster = require("cluster"), 
    http = require("http"), 
    express = require('express'), 
    port = parseInt(process.argv[2]||8001), 
    servers = ['http://127.0.0.1:800821', 'http://127.0.0.1:800831'];; 

if (cluster.isMaster) { 

    console.log('Master ' + process.pid + ' has started.'); 
    var numWorkers = require('os').cpus().length; 

    console.log('Master cluster setting up ' + numWorkers + ' workers...'); 

    for(var i = 0; i < 1; i++) { 
     cluster.fork(); 
    } 

    cluster.on('online', function(worker) { 
     console.log('Worker ' + worker.process.pid + ' is online'); 
    }); 

    cluster.on('exit', function(worker, code, signal) { 
     console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal); 
     console.log('Starting a new worker'); 
     cluster.fork(); 
    }); 
} else { 
    var httpProxy = require('http-proxy'); 
    var proxy = httpProxy.createProxyServer(); 
    var count = 0; 
    // Workers share the TCP connection in this server 
    var app = express(); 
    app.get('/', function (req, res) { 
     console.log('Cluster => ' + process.pid); 
     loadBalanceProxy(req,res); 
    }).listen(port); 

    var currentServer = 1; 
    function loadBalanceProxy(req, res){ 
     var cur = currentServer%servers.length; 
     currentServer++; 
     var target = servers[cur]; 
     console.log("Proxy => " + target); 
     proxy.web(req, res, { 
      target: target 
     }); 
    } 
} 

http.createServer(function (req, res) { 
    res.writeHead(200, { 'Content-Type': 'text/plain' }); 
    res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2)); 
    res.end(); 
}).listen(800831); 

http.createServer(function (req, res) { 
    res.writeHead(200, { 'Content-Type': 'text/plain' }); 
    res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2)); 
    res.end(); 
}).listen(800821); 

一個示例代碼在此示例中,我想創建一個集羣內的工人代理服務器,這給了我錯誤bind EADDRINUSE null:800831 我想知道可以在集羣工作者內部創建http-proxy。如果我不能,那麼解決方案之間的負載平衡機器?

+0

不能使用nginx的或HAProxy的? – Hosar

回答

0

我在集羣內創建了一個代理反向exemple proxy reverse,並且我在另一個文件中創建了3個服務器,它適用於我(不要忘記單獨運行服務器,例如在Windows上啓動服務器的4釐米,1釐米代理和其他(3 CMD)的服務器)

// var https = require('https'); scure 
 
var http = require('http'); 
 
var proxy = require('http-proxy'); 
 

 
var cluster = require('cluster'); 
 

 
var fs = require('fs'); 
 
var request = require('request'); 
 
// const numCPUs = require('os').cpus().length; 
 
var numCPUs = 4; 
 

 
if (cluster.isMaster) { 
 

 
    for (var i = 0; i < numCPUs; i++) { 
 

 
    cluster.fork(); 
 

 
    } 
 
    cluster.on('fork', (worker) => { 
 
    console.log('worker ' + worker.process.pid); 
 
    }); 
 

 
    cluster.on('exit', function(worker, code, signal) { 
 
    console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal); 
 
    console.log('Starting a new worker'); 
 
    cluster.fork(); 
 
    }); 
 

 
} else { 
 
    startProxyReverse(); 
 

 
} 
 

 
function startProxyReverse() { 
 

 
    http.globalAgent.maxSockets = 10240; 
 

 
    // Define the servers to load balance. 
 
    var servers = [{ 
 
    host: '127.0.0.1', 
 
    port: 8001 
 
    }, { 
 
    host: '127.0.0.1', 
 
    port: 8003 
 
    }, { 
 
    host: '127.0.0.1', 
 
    port: 8002 
 
    }]; 
 
    var failoverTimer = []; 
 

 
    // load the SSL cert 
 
    // var ca = [ 
 
    // fs.readFileSync('./certs/PositiveSSLCA2.crt'), 
 
    // fs.readFileSync('./certs/AddTrustExternalCARoot.crt') 
 
    // ]; 
 
    // var opts = { 
 
    // ca : ca, 
 
    // key : fs.readFileSync('./certs/example_wild.key'), 
 
    // cert : fs.readFileSync('./certs/STAR_example_com.crt') 
 
    // }; 
 

 
    // Create a proxy object for each target. 
 
    var proxies = servers.map(function(target) { 
 
    return new proxy.createProxyServer({ 
 
     target: target 
 
     // ws : true, 
 
     // xfwd : true, 
 
     // ssl : opts, 
 
     // down : false 
 
    }); 
 
    }); 
 

 
    /** 
 
    * Select a random server to proxy to. If a 'server' cookie is set, use that 
 
    * as the sticky session so the user stays on the same server (good for ws fallbacks). 
 
    * @param {Object} req HTTP request data 
 
    * @param {Object} res HTTP response 
 
    * @return {Number}  Index of the proxy to use. 
 
    */ 
 
    var selectServer = function(req, res) { 
 
    var index = -1; 
 
    var i = 0; 
 

 
    // Check if there are any cookies. 
 
    if (req.headers && req.headers.cookie && req.headers.cookie.length > 1) { 
 
     var cookies = req.headers.cookie.split('; '); 
 

 
     for (i = 0; i < cookies.length; i++) { 
 
     if (cookies[i].indexOf('server=') === 0) { 
 
      var value = cookies[i].substring(7, cookies[i].length); 
 
      if (value && value !== '') { 
 
      index = value; 
 
      break; 
 
      } 
 
     } 
 
     } 
 
    } 
 

 
    // Select a random server if they don't have a sticky session. 
 
    if (index < 0 || !proxies[index]) { 
 
     index = Math.floor(Math.random() * proxies.length); 
 
    } 
 

 
    // If the selected server is down, select one that isn't down. 
 
    if (proxies[index].options.down) { 
 
     index = -1; 
 

 
     var tries = 0; 
 
     while (tries < 5 && index < 0) { 
 
     var randIndex = Math.floor(Math.random() * proxies.length); 
 
     if (!proxies[randIndex].options.down) { 
 
      index = randIndex; 
 
     } 
 

 
     tries++; 
 
     } 
 
    } 
 

 
    index = index >= 0 ? index : 0; 
 

 
    // Store the server index as a sticky session. 
 
    if (res) { 
 
     res.setHeader('Set-Cookie', 'server=' + index + '; path=/'); 
 
    } 
 

 
    return index; 
 
    }; 
 

 
    /** 
 
    * Fired when there is an error with a request. 
 
    * Sets up a 10-second interval to ping the host until it is back online. 
 
    * There is a 10-second buffer before requests start getting blocked to this host. 
 
    * @param {Number} index Index in the proxies array. 
 
    */ 
 
    var startFailoverTimer = function(index) { 
 
    if (failoverTimer[index]) { 
 
     return; 
 
    } 
 

 
    failoverTimer[index] = setTimeout(function() { 
 
     // Check if the server is up or not 
 
     request({ 
 
     url: 'http://' + proxies[index].options.target.host + ':' + proxies[index].options.target.port, 
 
     method: 'HEAD', 
 
     timeout: 10000 
 
     }, function(err, res, body) { 
 
     failoverTimer[index] = null; 
 

 
     if (res && res.statusCode === 200) { 
 
      proxies[index].options.down = false; 
 
      console.log('Server #' + index + ' is back up.'); 
 
     } else { 
 
      proxies[index].options.down = true; 
 
      startFailoverTimer(index); 
 
      console.log('Server #' + index + ' is still down.'); 
 
     } 
 
     }); 
 
    }, 10000); 
 
    }; 
 

 
    // Select the next server and send the http request. 
 
    var serverCallback = function(req, res) { 
 
    console.log('Process ' + process.pid + ' is listening to all incoming requests'); 
 
    var proxyIndex = selectServer(req, res); 
 
    console.log(proxyIndex); 
 
    var proxy = proxies[proxyIndex]; 
 
    proxy.web(req, res); 
 

 
    proxy.on('error', function(err) { 
 
     startFailoverTimer(proxyIndex); 
 
    }); 
 
    }; 
 
    console.log('create server'); 
 
    // var server = http.createServer(opts, serverCallback); scure server 
 
    var server = http.createServer(serverCallback); 
 
    // http.createServer(serverCallback).listen(8000); 
 

 

 
    // Get the next server and send the upgrade request. 
 
    // server.on('upgrade', function (req, socket, head) { 
 
    // var proxyIndex = selectServer(req); 
 
    // var proxy = proxies[proxyIndex]; 
 
    // proxy.ws(req, socket, head); 
 

 
    // proxy.on('error', function (err, req, socket) { 
 
    // socket.end(); 
 
    // startFailoverTimer(proxyIndex); 
 
    // }); 
 
    // }); 
 
    server.listen(8000); 
 
    // server.listen(443); scure port 
 
    // var proxi = proxy.createServer(); 
 

 
    // http.createServer(function (req, res) { 
 

 
    // var target = { 
 
    // target : servers.shift() 
 
    // }; 
 
    // console.log('Process ' + process.pid + ' is listening to all incoming requests'); 
 

 
    // console.log('balancing request to: ', target); 
 
    // proxi.web(req, res, target); 
 

 

 
    // servers.push(target.target); 
 
    // }).listen(8000); 
 

 
}