【问题标题】:Monitor remote changes and automatically copy them locally监控远程更改并自动复制到本地
【发布时间】:2017-07-26 15:58:16
【问题描述】:

我有一个 Node.js 项目,它位于我们的客户端计算机本地,我希望能够监控远程位置以了解对两个文件(server.js 和 logging.js)的更改,自动停止节点服务器,将远程更改的文件复制到本地并使用新复制的本地文件重新启动服务器。

这将在我们的生产环境中用于部署冲刺结束测试的更改,这样我们就不必定期为我们的服务部门运行安装。

我尝试过使用 Forever 和 Nodemon,它们都乐于监视远程文件的更改,但只重新启动本地(未更改)副本,因此这些更改不会传播到本地副本。

我计划在生产环境中使用 Forever 来帮助解决我们偶尔遇到的本地服务器崩溃问题,因此理想情况下,任何解决方案都可以通过 Forever 的 -c 开关运行。我还使用他们的底层代码chokidar 进行了调查,但没有看到在更改时复制文件的能力。

我们的部署环境都是基于 Windows 的,所以我使用的是Forever-Win,但是,我们正在尝试使我们正在运行的应用程序与平台无关。

可能类似于:

forever start --watch \\server\share\server.js --watch \\server\share\logging.js -c [remote monitoring copy locally package name] server.js

我希望找到一个已经存在的 NPM 包,这样我就不必自己动手了。

This SO answer 与我要查找的内容接近,但他正在监视一个日志文件,而不是服务器本身。

This is another SO question这和我想解决的问题很相似。

【问题讨论】:

    标签: javascript node.js fs forever


    【解决方案1】:

    我们最终放弃了使用 Forever,我无法让它与 Nodemon 一起正常工作并同时观看远程目录。我们认为能够在命令上推送代码更改比在服务器崩溃时重新启动服务器更重要(这根本不会经常发生)。当我们进行代码推送时,无论如何服务器都会重新启动。

    我创建了一个名为 serverMon.js 的服务器监控文件,其中包含(请参阅下面的引文以获取我修改为自己使用的代码的链接):

    const fs = require('fs');
    const child_process = require('child_process');
    
    //production path
    var widgetPath = '\\\\server\\share\\sbSerialWidget\\';
    
    var widgetFiles = ['sbNodeLog.js', 'server.js'];
    var passedInFileName, infile, outfile;
    
    for(var i = 0; i < widgetFiles.length; i++){
        fs.createReadStream(widgetPath + widgetFiles[i]).pipe(fs.createWriteStream(widgetFiles[i]));
    }
    //spawn server.js passing it's stdio, stderr, stdout back through this node instance
    server = child_process.spawn('node', ['server.js'], {stdio: 'inherit'}, function (error, stdout, stderr) {
        if (error) {
            console.log(error.stack);
            console.log('Error code: ' + error.code);
            console.log('Server.js error received: ' + error.signal);
        }   
        console.log('Server.js STDOUT: ' + stdout);
        console.log('Server.js STDERR: ' + stderr);  
    });
    
    server.on('exit', function (code) {
        server.kill('SIGTERM');
        console.log('Child process exited with exit code '+code);
    });
    

    这由包含在 .VBS 文件中的 nodemon 脚本监视:

    CreateObject("Wscript.Shell").Run "nodemon serverMon.js --exitcrash --watch \\server\share\sbSerialWidget", 0, True

    这又由位于%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup 中的 CMD 脚本运行,因此它会在启动时启动 .VBS 脚本,因此我们的小串行小部件始终在后台运行:

    REM @echo off
    REM cls
    GOTO START
    
    :START
    IF EXIST "%ProgramFiles%\sbserialwidget\server.js" GOTO WIN32
    IF EXIST "%ProgramFiles(x86)%\sbSerialWidget\server.js" GOTO WIN64
    ECHO End start
    GOTO END
    
    :WIN32
    cls
    echo Inside 32 bit
    PUSHD "%ProgramFiles%"\sbserialwidget
    GOTO RUNVBS
    GOTO END
    
    :WIN64
    echo Inside 64 bit
    PUSHD "%ProgramFiles(x86)%"\sbSerialWidget
    GOTO RUNVBS
    GOTO END
    
    :RUNVBS
    echo Inside RUNVBS
    start runNodemon.vbs
    GOTO END
    
    :END
    popd
    EXIT
    

    我们最终在 Taskmanager 中运行了三个 node.exe 实例,一个运行 nodemon,它正在监视第二个 serverMon.js,同时监视远程文件的更改,然后第三个 server.js 启动为serverMon.js 的子进程。

    引用:
    Copying node files with streams and pipes

    Spawning a node child server

    【讨论】:

      【解决方案2】:

      你真的需要两件事:

      1. 将您的文件与某个远程位置同步
      2. 更改时重新启动服务器

      有几种方法可以做到。

      例如,您可以在您的服务器上托管一个 git 存储库并从某个远程位置推送到它以更新代码并触发将重新部署和重新启动服务器的 git 挂钩。

      或者您可以定期在您的服务器上运行一个脚本来检查远程存储库、更新本地存储库并重新启动服务器。

      或者您可以使用与更改的存储库挂钩的 CI 服务,运行测试并在测试通过时进行部署。

      请注意,在大多数情况下,我说的是代码仓库,而不仅仅是两个具有硬编码名称的文件,因为能够重构代码、添加文件等更具未来性。但您也可以rsync、scp 或 sftp 来复制文件。有很多方法可以做到这一点,但添加一些结构并使用一些经过测试的可扩展且易于长期维护的工具会很有用。

      无论您做什么,请记住一件事:确保您可以在运行之前验证您正在下载的内容。因此,除非您对所有内容进行了加密签名,否则切勿通过 HTTP 下载任何内容。并确保签名过程也是安全的。 Git 对此非常有用,因为您可以验证正在下载的内容。

      【讨论】:

        猜你喜欢
        • 2022-01-27
        • 2019-05-15
        • 2018-10-10
        • 2020-02-12
        • 2019-02-21
        • 2016-07-28
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        相关资源
        最近更新 更多