zoukankan      html  css  js  c++  java
  • express-15 与生产相关的问题

    执行环境

    • Express支持执行环境的概念,它是一种在生产、开发或测试模式中运行应用程序的方法。实际上你可以按自己的想法创建很多种不同的环境。

      • 要记住,开发、生产和测试是“标准”环境,Express、Connect以及第三方中间件可能会基于这些环境做出决定。
      • 换句话说,如果你有一个“临时”环境,则无法让它自动集成生产环境的属性。
    • 尽管可以调用app.set('env', 'production')指定执行环境,但不建议这样做;

      • 因为那意味着不管什么情况,你的应用程序都会一直运行在那个环境中。
      • 更糟的是,它可能在一个环境中开始运行,然后切换到另一个环境。
      • 用环境变量NODE_ENV指定执行环境更好
    //通过调用`app.get('env')`让它报告一下它运行在哪种模式下:
    
    http.createServer(app).listen(app.get('port'), function(){ 
      console.log( 'Express started in ' + app.get('env') +
                    ' mode on http://localhost:' + app.get('port') +
                    '; press Ctrl-C to terminate.' );
    });
    
    
    • 如果现在启动服务器,将会看到它运行在开发模式下,因为如果你没有指定,开发模式就是默认模式。
    //试着把它放在生产模式下:
    
    $ export NODE_ENV=production
    $ node meadowlark.js
    
    • 如果用的是Unix/BSD系统或Cygwin,这里有个方便的语法,仅为一次命令执行期间设定环境:
    $ NODE_ENV=production node meadowlark.js
    
    • 如果在生产模式下启动Express,你可能会注意到有些组件不适合在生产模式下使用的警告信息。

    环境特定配置

    • 只是改变执行环境起不到太大的作用,尽管Express在生产模式下会输出更多警告到控制台中(比如告诉你被废弃的模块将来会被移除)。
    • 在生产模式下,视图缓存会默认启用;
    • 执行环境大体是一个可以利用的工具,可以轻松地决定应用程序在不同的环境下应该做何表现。
    • 尽量缩小开发、测试和生产环境之间的差异, 也就是说应该保守地使用这个功能。
    • 有些差异是不可避免的,比如,如果你的程序是高度数据库驱动的,你可能不想在开发期间干扰生产数据库,并且这是环境特定配置的良好候选用途。
    • 另外一个影响不大的领域是更加详细的日志。你想在开发时记录的很多东西都没必要在生产环境中记录。

    日志

    • 给程序添加一些日志。在开发环境中,会用Morgan npm install --save morgan ,它的输出是便于查看的彩色文本。
    • 在生产环境中,我们用express-logger npm install --save express-logger,它支持日志循环(每24小时复制一次,然后开始新的日志,防止日志文件无限制地增长)。
    //给程序文件添加日志支持:
    
    switch(app.get('env')){ 
      case 'development':
        // 紧凑的、彩色的开发日志
        app.use(require('morgan')('dev'));
        break;
      case 'production':
        // 模块'express-logger'支持按日志循环
        app.use(require('express-logger')({
            path: __dirname + '/log/requests.log'
        }));
        break;
    }
    

    如果想实际看看日志的循环功能,可以编辑node_modules/express-logger/logger.js,修改变量defaultInterval,比如从24小时改成10秒(记住,修改node_modules中的包只能是出于实验或学习目的)。

    扩展网站

    • 扩展通常意味着向上扩展或向外扩展。
      • 向上扩展是指让服务器变得更强:更快的CPU,更好的架构,更多内核,更多内存,等等。
      • 向外扩展只是意味着更多的服务器。
    • 随着云计算的流行和虚拟化的普及,服务器和计算能力的相关性变得越来越小,并且对于网站的扩展需求而言,向外扩展是成本收益率更高的办法。
    • 在用Node开发网站时,应该总是考虑向外扩展的可能性。

    在搭建一个设计好要向外扩展的网站时,最重要的是持久化。

    • 除非所有服务器都能访问到那个文件系统,否则不应该用本地文件系统做持久化。
    • 不过只读数据是个例外,比如日志和备份。
    • 比如,可以把表单提交的数据备份到本地普通文件中,以防数据库接连失效。一旦遇到数据库中断的情况,到每个服务器上收集文件虽然麻烦,但最起码不会造成破坏。

    用应用集群扩展

    • Node本身支持应用集群,它是一种简单的、单服务器形式的向外扩展。

    • 使用应用集群,可以为系统上的每个内核(CPU)创建一个独立的服务器(有更多的服务器而不是内核数不会提高程序的性能)。

    • 应用集群好在两个地方:

      • 第一,它有助于实现给定服务器性能的最大化(硬件或虚拟机);
      • 第二,它是一种在并行条件下测试程序的低开销方式。
    • 给网站添加集群支持。尽管在主程序文件中做这些工作的做法十分普遍,但我们准备创建第二个程序文件,用之前一直在用的非集群程序文件在集群中运行程序。为此我们必须先对meadowlark.js做些轻微的调整:

    function startServer() { 
      app.listen(process.env.PORT || 3000, function(){
        console.log( 'Express started in ' + app.get('env') +
            ' mode on http://localhost:' + app.get('port') +
            '; press Ctrl-C to terminate.' );
      }); 
    };
    
    if(require.main === module){
      // 应用程序直接运行;启动应用服务器
      startServer();
    } else {
      // 应用程序作为一个模块通过"require"引入: 导出函数 
      // 创建服务器
      module.exports = startServer;
    }
    
    //这样修改之后,meadowlark.js既可以直接运行(node meadowlark.js),也可以通过require语句作为一个模块引入。
    
    • 然后我们会创建一个新脚本,meadowlark_cluster.js:
    var cluster = require('cluster');
    
    function startWorker() {
      var worker = cluster.fork();
      console.log('CLUSTER: Worker %d started', worker.id);
    } 
    
    if(cluster.isMaster){
    
      require('os').cpus().forEach(function(){ 
        startWorker();
      });
    
      // 记录所有断开的工作线程。如果工作线程断开了,它应该退出,
      // 因此我们可以等待exit事件然后繁衍  一个新工作线程来代替它
      cluster.on('disconnect', function(worker){
          console.log('CLUSTER: Worker %d disconnected from the cluster.',
                      worker.id);
      });
      // 当有工作线程死掉(退出)时,创建一个工作线程代替它
      cluster.on('exit', function(worker, code, signal){
        console.log('CLUSTER: Worker %d died with exit code %d (%s)',
              worker.id, code, signal);
        startWorker();
      });
    
    } else {
    
            // 在这个工作线程上启动我们的应用服务器,参见meadowlark.js
            require('./meadowlark.js')();
    
    }
    
    • 在这个JavaScript执行时,它或者在主线程的上下文中(当用node meadowlark_cluster.js直接运行它时),或者在工作线程的上下文中(在Node集群系统执行它时)。
    • 属性cluster.isMaster和cluster.isWorker决定了运行在哪个上下文中。
    • 在我们运行这个脚本时,它是在主线程模式下执行的,并且我们用cluster.fork为系统中的每个CPU启动了一个工作线程。
    • 我们还监听了工作线程的exit事件,重新繁衍死掉的工作线程。最后,我们在else从句中处理工作线程的情况。既然我们将meadowlark.js配置为模块使用,只需要引入并立即调用它(记住,我们将它作为一个函数输出并启动服务器)。
    • 如果你用的是虚拟机(比如Oracle的VirtualBox),则必须将VM配置为多个CPU。虚拟机一般默认只有一个CPU。

    假定你在多核系统上,应该能看到一些工作线程启动了。如果你想看到不同工作线程处理不同请求的证据,在路由前添加下面这个中间件:

    app.use(function(req,res,next){
      var cluster = require('cluster');
      if(cluster.isWorker) console.log('Worker %d received request',
          cluster.worker.id);
    });
    
  • 相关阅读:
    swift 关于FDFullscreenPopGesture的右滑返回
    ios 根据 schemes 打开 app
    ios UITableView的style的区别与用法,以及分割线的显示与隐藏
    swift 导入 .a 和 .h 文件
    ios 11 SDK 新特性 使用
    cocoapods 安装中出的太多问题
    GCD
    View的原理
    android ViewPager左右滑动实现导航栏的背景随页面滑动而滑动
    Android中图像变换Matrix的原理、代码验证和应用
  • 原文地址:https://www.cnblogs.com/jinkspeng/p/4351146.html
Copyright © 2011-2022 走看看