在大型网络结构中,或流量大的网站上,负载均衡是必备的。

用于实现流量负载、高可用

负载均衡常用的是NGINX、HAProxy、F5等。

而我们的Node.JS开发,实现一个负载均衡,是不那么困难的。

本文将实现一个负载均衡系统,而且是一个高端的动态负载均衡系统。

它将备以下功能:

1、动态添加负载;

2、自动、随机选择负载。

使用效果:

1、添加负载:

密码的设置是为了安全使用,防止被非法添加负载。

目标指的就是负载。

比如通过这里操作三次,即添加三个负载。

2、访问效果,负载见效:

图中的序号,显示的是使用的负载序号,可见不同的负载已启用。

在现实实用时,如果添加的是不同机器,不同服务器,则这个序号可能代表的是机器号等。

完整代码:

本项目由两个文件组成,一个主程序blance.JS用于实现负载均衡,一个网页文件blance.HTML,用于添加负载。

blance.JS代码:

//*****************************************/
// Blance
// 
// Auther: WangLiwen
//*****************************************/

//三方模块
var express = require("express")();
var http_proxy = require("http-proxy");
var body_parser = require("body-parser");

//端口
var port = 8090;
//密码
var password = "pass";

//调试开关
var debug = true;
//代理
var proxy = http_proxy.createProxyServer({});
//存放目标
var pool = [];

//监听
express.listen(port);
console.log("blance server at port:",port);

proxy.on("error",function(err,req,res){
    try{
        res.end("error");
    }catch(e){
        console.log(e.message);
    }
});

//body-parser
express.use(body_parser.urlencoded({extended: true}));

//注册
express.post("/register_blance",function(req,res,next){

    //密码,用于校验
    if(req.body.password == password){

        //添加到负载均衡池
        pool.push(req.body.target);

        console.log("add blance:",req.body.target);

        res.end("blance added!");
    }else{
        console.log("register blance error: password error!");
        console.log("error!");
    }
    
    return;
});

//反注册
express.post("/unregister_blance",function(req,res,next){
    //密码,用于校验
    if(req.body.password == password){

        //遍历
        for(i=0; i<pool.length; i++){

            //匹配
            if(pool[i] == req.body.target){

                //删除
                delete pool[i];
                pool.splice(i,1);

                console.log("remove blance:",req.body.target);

                res.end("blance removed!")
            }
        }
    }else{
        console.log("unregister blance error: password error!");
        res.end("error!")
    }
    return;
});

//随机访问负载
express.use(function(req,res,next){

    if(pool.length == 0){
        console.log("error: blance pool is null.")
        return;
    }
    //随机数
    var rnd = random_number(0,pool.length - 1);

    //访问
    proxy.web(req, res, {target: pool[rnd], selfHandleResponse : false, changeOrigin:false} );

    console.log("blance visit: ",rnd, pool[rnd],",url:",req.url);

    //next();
})

//范围内随机数
function random_number(min,max){
    var range = max - min;
    var rand = Math.random();
    var num = min + Math.round(rand * range);
    return num;
}

blance.HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style></style>
</head>
<body>
    <form action="http://localhost:8090/register_blance" method="post">
        
        <div>密码:<input type="password" name="password"></div>
        <div>目标<input type="text" name="target"></div>
        <div><input type="submit" name="" value="提交"></div>
    </form>
</body>
</html>

由代码中可知,这是一个DEMO,虽如此,但它与ShareWAF的商用负载均衡系统原理、实现基本一致,它是一个完整的负载均衡系统。