七天学会NodeJS(四)一边读取一边输出响应、守护进程(child process、spawn)、功能-性能-稳定性-代码部署

本文介绍了如何使用NodeJS开发一个静态文件合并服务器,包括从功能实现到性能优化、稳定性增强的四个迭代过程。在第二次迭代中,服务器实现了边读取边输出响应以提高性能。第三次迭代引入了守护进程,确保服务在异常时能自动重启,增强了服务稳定性。第四次迭代关注代码部署和服务器控制,提供了简单的部署目录和服务控制脚本。
摘要由CSDN通过智能技术生成

七天学会NodeJS(四)一边读取一边输出响应、守护进程(child process、spawn)、功能-性能-稳定性-代码部署

总结:

  • 合并静态文件示例

    • 本章小结

    • process补充

      • SIGKILL 是告诉进程要立即终止的信号,理想情况下,其行为类似于 process.exit()

      • SIGTERM 是告诉进程要正常终止的信号。它是从进程管理者(如 upstartsupervisord)等发出的信号。

      • 可以从程序内部另一个函数中发送此信号:

        process.kill(process.pid, 'SIGTERM')
        

        或从另一个正在运行的 Node.js 程序、或从系统中运行的其他任何的应用程序(能知道要终止的进程的 PID)。

    • Child Process

      • 官方文档: http://nodejs.org/api/child_process.html
      • 使用child_process模块可以创建和控制子进程。
      • 该模块提供的API中最核心的是.spawn,其余API都是针对特定使用场景对它的进一步封装,算是一种语法糖。
        • 使用.spawn(exec, args, options)方法,创建子进程,该方法支持三个参数。
        • 第一个参数是执行文件路径,可以是执行文件的相对或绝对路径,也可以是根据PATH环境变量能找到的执行文件名。
        • 第二个参数中,数组中的每个成员都按顺序对应一个命令行参数。
        • 第三个参数可选,用于配置子进程的执行环境与行为。
    • 第一次迭代(功能

      • 服务器会首先分析URL,得到请求的文件的路径和类型(MIME)。

        • 使用命令行参数传递JSON配置文件路径,入口函数负责读取配置并创建服务器。
        • 入口函数完整描述了程序的运行逻辑,其中解析URL和合并文件的具体实现封装在其它两个函数里。
        • 解析URL时先将普通URL转换为了文件合并URL,使得两种URL的处理方式可以一致。
      • 然后,服务器会读取请求的文件,并按顺序合并文件内容。

        • 合并文件时使用异步API读取文件,避免服务器因等待磁盘IO而发生阻塞。
      • 最后,服务器返回响应,完成对一次请求的处理。

      • 逻辑缺陷:

         http://assets.example.com/foo/bar.js,foo/baz.js
        

        经过分析之后我们会发现问题出在/被自动替换/??这个行为上,而这个问题我们可以到第二次迭代时再解决。

    • 第二次迭代(性能

      • 第二版代码在检查了请求的所有文件是否有效之后,立即就输出了响应头,并接着一边按顺序读取文件一边输出响应内容。
      • 并且,在读取文件时,第二版代码直接使用了只读数据流来简化代码。
      • 服务器本身的功能和性能已经得到了初步满足
    • 第三次迭代(稳定性

      • 从工程角度上讲,没有绝对可靠的系统。即使第二次迭代的代码经过反复检查后能确保没有bug,也很难说是否会因为NodeJS本身,或者是操作系统本身,甚至是硬件本身导致我们的服务器程序在某一天挂掉。因此一般生产环境下的服务器程序都配有一个守护进程,在服务挂掉的时候立即重启服务。一般守护进程的代码会远比服务进程的代码简单,从概率上可以保证守护进程更难挂掉。如果再做得严谨一些,甚至守护进程自身可以在自己挂掉时重启自己,从而实现双保险。
      • 因此在本次迭代时,我们先利用NodeJS的进程管理机制,将守护进程作为父进程,将服务器程序作为子进程,并让父进程监控子进程的运行状态,在其异常退出时重启子进程。
      • 步骤
        • 把守护进程的代码保存为daemon.js,之后我们可以通过node daemon.js config.json启动服务,而守护进程会进一步启动和监控服务器进程
        • 让守护进程在接收到SIGTERM信号时终止服务器进程
        • 而在服务器进程这一端,同样在收到SIGTERM信号时先停掉HTTP服务再正常退出。
    • 第四次迭代(代码部署及服务器控制)

1. 大示例

学习讲究的是学以致用和融会贯通。至此我们已经分别介绍了NodeJS的很多知识点,本章作为最后一章,将完整地介绍一个使用NodeJS开发Web服务器的示例。

需求

我们要开发的是一个简单的静态文件合并服务器,该服务器需要支持类似以下格式的JS或CSS文件合并请求。

http://assets.example.com/foo/??bar.js,baz.js

在以上URL中,??是一个分隔符,之前是需要合并的多个文件的URL的公共部分,之后是使用,分隔的差异部分。因此服务器处理这个URL时,返回的是以下两个文件按顺序合并后的内容。

/foo/bar.js
/foo/baz.js

另外,服务器也需要能支持类似以下格式的普通的JS或CSS文件请求。

http://assets.example.com/foo/bar.js

以上就是整个需求。

第一次迭代

快速迭代是一种不错的开发方式,因此我们在第一次迭代时先实现服务器的基本功能。

设计

简单分析了需求之后,我们大致会得到以下的设计方案。

           +---------+   +-----------+   +----------+
request -->|  parse  |-->|  combine  |-->|  output  |--> response
           +---------+   +-----------+   +----------+

也就是说,服务器会首先分析URL,得到请求的文件的路径和类型(MIME)。然后,服务器会读取请求的文件,并按顺序合并文件内容。最后,服务器返回响应,完成对一次请求的处理

另外,服务器在读取文件时需要有个根目录,并且服务器监听的HTTP端口最好也不要写死在代码里,因此服务器需要是可配置的。

实现

根据以上设计,我们写出了第一版代码如下。

var fs = require('fs'),
    path = require('path'),
    http = require('http');

var MIME = {
   
    '.css': 'text/css',
    '.js': 'application/javascript'
};

//合并函数,服务器会读取请求的文件,并按顺序合并文件内容
function combineFiles(pathnames, callback) {
   
    var output = [];

    (function next(i, len) {
   
        if (i < len) {
   
            fs.readFile(pathnames[i], function (err, data) {
   
                if (err) {
   
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChrisP3616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值