使用NodeJS实现负载均衡后的服务器文件同步

为了减少服务器的负载,针对IIS使用ServerFarm做了负载均衡,ServerFarm实质上是个消息分发模块。

不过ServerFarm有个不好的问题,所有对该服务器的访问都会被ServerFarm分发,没办法指定特定的端口(目前还没找到解决办法,望各位大神不吝赐教)。负载均衡之后一个紧急的问题就是服务器端的文件部署。

目前实现服务器端文件下载部署的死路有如下几个:

  • 通过SVN或者TFS等源代码管理器,设置源代码的自动下载,达到文件统一部署的目的;
  • 使用NodeJS在每个服务器添加一个端口监听,自己写一个文件下载服务,下载部署提交之后,调用Post请求每个服务器的监听端口,NodeJS在接收到请求之后,从文件服务器下载相应的文件。

对比两种思路,第一种虽然有可用的程序,但是无法达到自定义的目的,包括下载失败的提醒,下载日志的分发。所以采用了第二张思路。第二个思路主要分为两步,建立文件下载服务和创建端口监听

  1. 文件下载服务比较简单,在文件下载服务器添加一个网站,写一个文件上传的页面,将服务器文件上传至网站的特定目录(ServerFiles),这里就不再提供代码了;
  2. 创建端口监听:包括使用http.get从URL获取文件,由于文件都是zip压缩的,然后调用unzipper进行解压缩,指定解压缩的存放路径,最后删掉zip文件。当然,在下载过程中也可以对每一步添加日志记录,并且在下载之后对服务器的管理员添加消息分发。由于是服务器端的文件部署,为了防止意外,还可以在下载服务中添加回滚处理。由于只是做了个一个简单的下载部署,代码中没有包含这些,大家凑合着看哈。
    const http = require('http'); 
    const unzip = require('unzipper');
    const filedeployserver = "http://FileServer:xxxx/ServerFiles/";
    
    var download = function (url, dest, cb) {
        var fs = require('fs');
        var file = fs.createWriteStream(dest);
        var request = http.get(url, function (response) {
            //下载文件保存
            response.pipe(file);
            cb(`download ${dest} succ`);
            //将文件进行解压缩
            fs.createReadStream(dest).pipe(unzip.Extract({ path: '..\\Bin\\' }));
            cb(`unzip ${dest} succ`);
            file.on('finish', function () {
                //删除zip文件
                fs.unlink(dest, (err) => {
                    if (err) throw err;
                    cb(`delete ${dest} succ`);
                });
                file.close();
            });
        }).on('error', function (err) {
            //出现下载失败
            //
            fs.unlink(dest, (err) => {
                if (err) cb(`delete error: ${err.message} `);
            });
            cb(`download error: ${err.message} `);
        });
    };
    const server = http.createServer((req, res) => {
        if (req.method === 'POST') {
    
            collectRequestData(req, result => {
                if (result != undefined) {
                    var strs = result.replace(new RegExp('"', 'g'), '').split(",");
                    for (var i in strs) {
                        download(filedeployserver + strs[i], '..\\Bin\\' + strs[i],
                            function (result) {
                                var dt = new Date();
                                console.log(`${dt.toLocaleString()} ${result}`);
                            })
                    }
                }
                console.log(`download all files succes`);
                res.end(`download all files succes`);
            });
        }
        else {
            res.end(`
                <!doctype html>
                <html>
                <title>fileupload</title>
                <body>
                    <form action="/" method="post">
                        <input type="text" name="fname" /><br />
                        <input type="text" name="url" /><br />
                        <input type="file" name="photo" /><br />
                        <button>commit</button>
                    </form>
                </body>
                </html>
            `);
        }
    });
    server.listen(3000);
    
    function collectRequestData(request, callback) {
        const FORM_URLENCODED = 'application/json';
        if (request.headers['content-type'] === FORM_URLENCODED) {
            let body = '';
            request.on('data', chunk => {
                body += chunk.toString();
            });
            request.on('end', () => {
                callback(body);
            });
        }
        else {
            callback(null);
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_42757710/article/details/81565334
今日推荐