node.js运行js_在生产中,永远不要直接针对Node.js运行。 也许。

node.js运行js

Sometimes I wonder if I know much of anything at all.

有时我想知道我是否一无所知。

Just a few weeks ago I was talking to a friend who mentioned off-hand, “you would never run an application directly against Node in production”.

就在几周前,我正在和一个朋友聊天,后者提到了“您永远不会在生产环境中直接针对Node运行应用程序”。

I nodded vigorously to signal that I also would never ever run against Node in production because…hahaha….everyone knows that. But I didn’t know that! Should I have known that?!?? AM I STILL ALLOWED TO PROGRAM?

我大力点头表示我永远不会在生产中与Node竞争,因为……哈哈哈……大家都知道。 但是我不知道! 我应该知道吗? 我仍然可以参加程序吗?

If I was to draw a Venn Diagram of what I know vs what I feel like everyone else knows, it would look like this…

如果我要绘制一个维恩图,说明我所知道的vs其他人都知道的感觉,它将看起来像这样……

By the way, that tiny dot gets smaller the older I get.

顺便说一下,这个小点随着我年龄的增长而变小。

There is a better diagram created by Alicia Liu that kind of changed my life. She says that it’s more like this…

刘慧卿(Alicia Liu)创建的更好的图表改变了我的生活。 她说这更像是……

I love this diagram so much because I want it to be true. I don’t want to spend the rest of my life as a tiny, shrinking blue dot of insignificance.

我非常喜欢这个图,因为我希望它是真实的。 我不想把余生都当作一个微小的,逐渐缩小的无意义的蓝点。

SO DRAMATIC. Blame Pandora. I don’t control what gets played next while I’m writing this article and Dashboard Confessional is a helluva drug.

如此戏剧性。 怪潘多拉。 在撰写本文时,我无法控制接下来要播放的内容,而Dashboard Confessional就是一种毒品。

Well, assuming that Alicia’s diagram is true, I would like to share with you what I now know about running Node apps in production. Perhaps our relative Venn Diagrams don’t overlap on this subject.

好吧,假设Alicia的图表是正确的,我想与您分享我现在对在生产环境中运行Node应用程序的了解。 也许我们相对的维恩图在这个问题上并不重叠。

First off, let’s address the statement “never run apps directly against Node in production”.

首先,让我们解决“永远不要在生产环境中直接针对Node运行应用程序”这一说法。

切勿在生产中直接针对Node运行 (Never run directly against Node in production)

Maybe. But maybe not. Let’s talk about the reasoning behind this statement. First, let’s look at why not.

也许。 但也许不是。 让我们讨论一下该语句背后的原因。 首先,让我们看看为什么不这样做。

Say we have a simple Express server. The simplest Express server I can think of…

假设我们有一台简单的Express服务器。 我能想到的最简单的Express服务器...

const express = require("express");
const app = express();
const port = process.env.PORT || 3000;

// viewed at http://localhost:3000
app.get("/", function(req, res) {
  res.send("Again I Go Unnoticed");
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

We would run this with a start script in the package.json file.

我们将使用package.json文件中的启动脚本来运行它。

"scripts": {
  "dev": "npx supervisor index.js",
  "start": "node index.js"
}

There are sort of two problems here. The first is a development problem and the second is a production problem.

这里有两个问题。 第一个是发展问题,第二个是生产问题。

The development problem is that when we change the code, we have to stop and start the application to get our changes picked up.

开发的问题是,当我们更改代码时,我们必须停止并启动应用程序才能获取我们的更改。

To solve that, we usually use some sort of Node process manager like supervisor or nodemon. These packages will watch our project and restart our server whenever we make changes. I usually do that like this…

为了解决这个问题,我们通常使用某种类型的Node进程管理器,例如supervisornodemon 。 每当我们进行更改时,这些软件包将监视我们的项目并重新启动服务器。 我通常这样做

"scripts": {  "dev": "npx supervisor index.js",  "start": "node index.js"}

Then I run npm run dev. Note that I’m running npx supervisor here which allows me to use the supervisor package without having to install it. I ❤️ 2019. Mostly.

然后我运行npm run dev 。 请注意,我在这里运行npx supervisor ,这使我无需安装即可使用supervisor软件包。 我❤️2019.主要是。

Our other problem is that we’re still running directly against Node and we already said that was bad and now we’re about to find out why.

我们的另一个问题是我们仍然直接针对Node运行,我们已经说过这很糟糕,现在我们将找出原因。

I’m going to add another route here that attempts to read a file from disk that does not exist. This is an error that could easily show up in any real-world application.

我将在此处添加另一条尝试从不存在的磁盘读取文件的路由。 这是一个错误,很容易在任何实际应用程序中出现。

const express = require("express");
const app = express();
const fs = require("fs");
const port = process.env.PORT || 3000;

// viewed at http://localhost:3000
app.get("/", function(req, res) {
  res.send("Again I Go Unnoticed");
});

app.get("/read", function(req, res) {
  // this does not exist
  fs.createReadStream("my-self-esteem.txt");
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

If we run this directly against Node with npm start and navigate to the read endpoint, we get an error because that file doesn’t exist.

如果我们使用npm start在Node上直接运行此文件并导航到read端点,则会收到错误消息,因为该文件不存在。

Which — no big deal right? It’s one error. It happens.

哪个-没什么大不了的? 这是一个错误。 它发生了。

NO. Big deal. If you go back to your terminal you will see that the application is completely down.

没有。 大事了 如果返回到终端,您将看到该应用程序已完全关闭。

Which means if you go back to the browser and try to go to the root URL of the site, you get the same error page. One error in one method took the application down for everyone.

这意味着,如果您返回浏览器并尝试转到该站点的根URL,则会得到相同的错误页面。 一种方法的一个错误使每个人都无法使用该应用程序。

That’s bad. Like really bad. This is one of the main reasons why people say “never run directly against Node in production”.

那很糟。 真的很糟糕。 这是人们说“从不直接与生产中的Node对抗”的主要原因之一。

OK. So if we can’t run against Node in production, what is the right way to run Node in production?

好。 因此,如果我们不能在生产中与Node竞争,那么在生产中运行Node的正确方法是什么?

生产节点的选项 (Options for production Node)

We’ve got a few options.

我们有一些选择。

One of them would be to simply use something like supervisor or nodemon in production the same way we are using them in dev. That would work, but these tools are a little on the lightweight side. A better option is something called pm2.

其中之一就是像在开发人员中使用它们一样,在生产中简单使用诸如supervisornodemon类的东西。 可以,但是这些工具在轻量级方面有点不足。 更好的选择是称为pm2的东西。

pm2救援 (pm2 the rescue)

pm2 is a Node process manager that has lots of bells and whistles. Just like everything else “JavaScript”, you install it (globally) from npm — or you can just use npx again. I don’t want to tell you how to live your life.

pm2是一个Node进程管理器,它有很多麻烦。 就像其他所有“ JavaScript”一样,您可以从npm (全局)安装它-或者可以再次使用npx 。 我不想告诉你如何过生活。

There are a lot of ways to run your app with pm2. The simplest way is to just call pm2 start on your entry point.

有很多方法可以通过pm2运行您的应用程序。 最简单的方法是只在您的入口点调用pm2 start

"scripts": {
  "start": "pm2 start index.js",
  "dev": "npx supervisor index.js"
},

And you’ll see something like this in the terminal…

然后您会在终端中看到类似的内容……

That’s our process running in the background monitored by pm2. If you visit the read endpoint and crash the application, pm2 will automatically restart it. You won’t see any of that in the terminal because it’s running in the background. If you want to watch pm2 do its thing, you gotta run pm2 log 0. The 0 is the ID of the process we want to see logs for.

那就是我们的过程在pm2监视下在后台运行。 如果您访问read端点并使应用程序崩溃,则pm2将自动重新启动它。 您不会在终端中看到任何内容,因为它在后台运行。 如果您想观看pm2的工作,则必须运行pm2 log 00是我们要查看其日志的进程的ID。

There we go! You can see pm2 restart the application when it goes down because of our unhandled error.

好了! 您会看到pm2由于我们未处理的错误而在应用程序关闭时重新启动了它。

We can also pull out our dev command and have pm2 watch files for us and restart on any changes.

我们还可以拉出dev命令并为我们准备pm2监视文件,并在进行任何更改时重新启动。

"scripts": {
  "start": "pm2 start index.js --watch",
  "dev": "npx supervisor index.js"
},

Note that because pm2 runs things in the background, you can’t just ctrl+c your way out of a running pm2 process. You have to stop it by passing the ID or the name.

请注意,因为pm2在后台运行,所以您不能仅按ctrl+c退出正在运行的pm2进程。 您必须通过传递ID或名称来停止它。

pm2 stop 0

pm2 stop 0

pm2 stop index

pm2 stop index

Also, note that pm2 retains a reference to the process so you can restart it.

另外,请注意pm2保留了对该过程的引用,因此您可以重新启动它。

If you want to delete that process reference, you need to run pm2 delete. You can stop and delete a process in one command with delete.

如果要删除该流程引用,则需要运行pm2 delete 。 您可以使用delete在一个命令中停止和删除进程。

pm2 delete index

pm2 delete index

We can also use pm2 to run multiple processes of our application. pm2 will automatically balance the load across those instances.

我们还可以使用pm2来运行应用程序的多个进程。 pm2将自动在这些实例之间平衡负载。

pm2 fork模式下的多个进程 (Multiple processes with pm2 fork mode)

pm2 has a ton of configuration options and those are contained in an “ecosystem” file. To create one, run pm2 init. You’ll get something like this…

pm2具有大量的配置选项,这些选项都包含在“生态系统”文件中。 要创建一个,运行pm2 init 。 你会得到这样的东西...

module.exports = {
  apps: [
    {
      name: "Express App",
      script: "index.js",
      instances: 4,
      autorestart: true,
      watch: true,
      max_memory_restart: "1G",
      env: {
        NODE_ENV: "development"
      },
      env_production: {
        NODE_ENV: "production"
      }
    }
  ]
};

I’m going to ignore the “deploy” section in this article because I have no idea what it does.

我将忽略本文的“部署”部分,因为我不知道它的作用。

The “apps” section is where you define the apps you want pm2 to run and monitor. You can run more than one. A lot of these configuration settings are probably self-explanatory. The one that I want to focus on here is the instances setting.

在“应用程序”部分,您可以定义要让pm2运行和监视的应用程序。 您可以运行多个。 这些配置设置中有很多可能是不言自明的。 我要在这里重点介绍的是实例设置。

pm2 can run multiple instances of your application. You can pass in a number of instances that you want to run and pm2 will spin up that many. So if we wanted to run 4 instances, we could have the following configuration file.

pm2可以运行您的应用程序的多个实例。 您可以传入许多要运行的实例,而pm2会增加很多实例。 因此,如果我们要运行4个实例,我们可以拥有以下配置文件。

module.exports = {
  apps: [
    {
      name: "Express App",
      script: "index.js",
      instances: 4,
      autorestart: true,
      watch: true,
      max_memory_restart: "1G",
      env: {
        NODE_ENV: "development"
      },
      env_production: {
        NODE_ENV: "production"
      }
    }
  ]
};

Then we just run it with pm2 start.

然后我们仅使用pm2 start运行它。

pm2 is now running in “cluster” mode. Each of these processes is running on a different CPU on my machine, depending on how many cores I have. If we wanted to run a process for each core without knowing how many cores we have, we can just pass the max parameter to the instances value.

pm2现在以“群集”模式运行。 这些进程中的每一个都在我的计算机上的不同CPU上运行,具体取决于我拥有多少个内核。 如果我们想为每个内核运行一个进程而又不知道我们有多少个内核,则可以将max参数传递给instances值。

{
   ...
   instances: "max",
   ...
}

Let’s find out how many cores I’ve got in this machine.

让我们找出这台机器上有多少个内核。

8 CORES! Holy crap. I’m gonna install Subnautica on my Microsoft issued machine. Don’t tell them I said that.

8码! 哇靠。 我要在Microsoft发行的计算机上安装Subnautica。 别跟他们说

The good thing about running processes on separate CPU’s is that if you have a process that runs amok and takes up 100% of the CPU, the others will still function. If you pass in more instances than you have cores, pm2 will double up processes on CPU’s as necessary.

在单独的CPU上运行进程的好处是,如果您有一个运行amok并占用100%CPU的进程,其他进程仍然可以运行。 如果传递的实例数多于核心数,则pm2将在必要时使CPU上的进程加倍。

You can do a WHOLE lot more with pm2, including monitoring and otherwise wrangling those pesky environment variables.

您可以使用pm2做更多的事情,包括监视和处理那些讨厌的环境变量

One other item of note: if for some reason you want pm2 to run your npm start script, you can do that by running npm as the process and passing the -- start. The space before the “start” is super important here.

值得注意的另外一个项目:如果由于某种原因,你想PM2运行您的npm start脚本,您可以通过运行NPM的过程和传递这样做-- start 。 在这里,“开始”之前的空间非常重要。

pm2 start npm -- start

In Azure AppService, we include pm2 by default in the background. If you want to use pm2 in Azure, you don’t need to include it in your package.json file. You can just add an ecosystem file and you’re good to go.

Azure AppService中 ,默认情况下在后台包含pm2。 如果要在Azure中使用pm2,则无需将其包含在package.json文件中。 您只需添加一个生态系统文件就可以了。

OK! Now that we’ve learned all about pm2, let’s talk about why you may not want to use it and it might indeed be ok to run directly against Node.

好! 既然我们已经了解了pm2的全部知识,那么让我们讨论一下为什么您可能不想使用它,并且直接针对Node运行确实可以。

直接在生产中针对Node运行 (Running directly against Node in production)

I had some questions on this so I reached out to Tierney Cyren who is part of the enormous orange circle of knowledge, especially when it comes to Node.

我对此有一些疑问,因此我联系了蒂尔尼·塞伦 ( Tierney Cyren) ,他是庞大的橙色知识圈的一部分,尤其是在涉及Node时。

Tierney pointed out a few drawbacks to using Node based process managers like pm2.

Tierney指出了使用基于节点的流程管理器(例如pm2)的一些缺点。

The main reason is that you shouldn’t use Node to monitor Node. You don’t want to use the thing that you are monitoring to monitor that thing. It’s kind of like you asking my teenage son to supervise himself on a Friday night: Will that end badly? It might, and it might not. But you’re about to find out the hard way.

主要原因是您不应该使用Node来监视Node。 您不想使用要监视的事物来监视该事物。 就像您在星期五晚上要求我的十几岁的儿子监督自己:结局会很糟糕吗? 可能会,也可能不会。 但是您将发现困难的方法。

Tierney recommends that you not have a Node process manager running your application at all. Instead, have something at a higher level which watches multiple separate instances of your application. For example, an ideal setup would be if you had a Kubernetes cluster with your app running on separate containers. Kubernetes can then monitor those containers and if any of them go down, it can bring them back and report on their health.

Tierney建议您完全没有运行应用程序的Node进程管理器。 取而代之的是,在更高级别上监视某些应用程序的单独实例。 例如,如果您有一个Kubernetes集群,并且您的应用程序在单独的容器上运行,则是理想的设置。 然后,Kubernetes可以监视这些容器,如果其中任何一个发生故障,它可以将其带回并报告其运行状况。

In this case, you can run directly against Node because you are monitoring at a higher level.

在这种情况下,您可以直接在Node上运行,因为您需要进行更高级别的监视。

As it turns out, Azure is already doing this. If we don’t push a pm2 ecosystem file to Azure, it will start the application with our package.json file start script and we can run directly against Node.

事实证明,Azure已经在这样做。 如果我们不将pm2生态系统文件推送到Azure,它将使用我们的package.json文件启动脚本启动该应用程序,我们可以直接在Node上运行。

"scripts": {
  "start": "node index.js"
}

In this case, we are running directly against Node and it’s OK. If the application were to crash, you’ll notice that it comes back. That’s because in Azure, your app runs in a container. Azure is orchestrating the container in which your app is running and knows when it faceplants.

在这种情况下,我们直接针对Node运行,没关系。 如果应用程序崩溃了,您会注意到它又回来了。 这是因为在Azure中,您的应用程序在容器中运行。 Azure正在协调您的应用程序在其中运行的容器,并知道它何时面世。

But you still only have one instance here. It takes the container a second to come back online after it crashes meaning that there could be a few seconds of downtime for your users.

但是您在这里仍然只有一个实例。 崩溃后,该容器需要一秒钟才能恢复在线状态,这意味着您的用户可能会有几秒钟的停机时间。

Ideally, you would want more than one container running. The solution to this would be to deploy multiple instances of your application to multiple Azure AppService sites and then use Azure Front Door to load balance the apps behind a single IP address. Front Door will know when a container is down and will route traffic to other healthy instances of your application.

理想情况下,您需要运行多个容器。 解决方案是将应用程序的多个实例部署到多个Azure AppService站点,然后使用Azure Front Door在单个IP地址后面对应用程序进行负载平衡。 前门将知道何时容器发生故障,并将流量路由到应用程序的其他正常实例。

Azure Front Door Service | Microsoft AzureDeliver, protect and track the performance of your globally distributed microservice applications with Azure Front Door…azure.microsoft.com

Azure前门服务| Microsoft Azure 使用Azure前门交付,保护和跟踪全球分布式微服务应用程序的性能… azure.microsoft.com

系统的 (systemd)

Another suggestion that Tierney had is to run Node with systemd. I don’t understand too much (or anything at all) about systemd and I’ve already messed this phrasing up once already, so I’ll let Tierney say it in his own words…

Tierney的另一个建议是使用systemd运行Node。 我对systemd不太了解(或一点也不了解),我已经把这个措辞弄乱了,所以让蒂尔尼用他自己的话说……

This option is only possible if you have access to Linux in your deployment and you control the way that Node is started on a service level. If you’re running your Node.js process in a long-running Linux VM, like Azure VMs, you’re in a good place to run Node.js with systemd. If you are just deploying your files to a service like Azure AppService or Heroku or running inside of a containerized environment like Azure Container Instances, you should probably steer clear of this option.
仅当您可以在部署中访问Linux并在服务级别控制Node的启动方式时,此选项才可用。 如果您在运行时间较长的Linux VM(例如Azure VM)中运行Node.js进程,那么您将是使用systemd运行Node.js的好地方。 如果您只是将文件部署到Azure AppService或Heroku之类的服务,或者在Azure容器实例之类的容器化环境中运行,则可能应该避免使用此选项。

Running Your Node.js App With Systemd - Part 1You've written the next great application, in Node, and you are ready to unleash it upon the world. Which means you can…nodesource.com

使用Systemd运行Node.js应用程序-第1部分 您已经在Node中编写了下一个出色的应用程序,并准备将其释放给全世界。 这意味着您可以… nodesource.com

Node.js工作线程 (Node.js Worker Threads)

Tierney also wants you to know that Worker Threads are coming in Node. This will allow you to start your app on multiple “workers” (threads) thusly negating the need for something like pm2. Maybe. I don’t know. I didn’t really read the article.

Tierney还希望您知道Node中即将出现工作线程。 这将使您可以在多个“工作者”(线程)上启动应用程序,从而无需使用pm2之类的东西。 也许。 我不知道。 我没有真正读过这篇文章。

Node.js v11.14.0 DocumentationThe worker_threads module enables the use of threads that execute JavaScript in parallel. To access it: const worker =…nodejs.org

Node.js v11.14.0文档 利用worker_threads模块可以使用并行执行JavaScript的线程。 要访问它:const worker =… nodejs.org

成年 (Be an Adult)

Tierney’s last suggestion was to just handle the error and write some tests like an adult. But who has time for that?

Tierney的最后建议是仅处理错误并像成年人一样编写一些测试。 但是谁有时间呢?

微小的圆圈 (The tiny circle abides)

Now you know most of what is in the tiny blue circle. The rest is just useless facts about emo bands and beer.

现在,您知道了蓝色小圆圈中的大部分内容。 剩下的就是关于情绪乐队和啤酒的无用事实。

For more information on pm2, Node and Azure, check out the following resources…

有关pm2,Node和Azure的更多信息,请查看以下资源…

翻译自: https://www.freecodecamp.org/news/you-should-never-ever-run-directly-against-node-js-in-production-maybe-7fdfaed51ec6/

node.js运行js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值