简体   繁体   English

Node.js如何处理服务器的下拉?

[英]Node.js how to handle drop down of server?

On Node.js api there lots of if s and one can easily send request with some undefined var and crash the whole server until it re-starts again - something that could take up to 20 seconds. 在Node.js api上,有很多if和一个可以轻松地使用一些未定义的var发送请求,并使整个服务器崩溃,直到重新启动为止-这可能需要20秒钟。

I know that it should be checked if a variable is defined before working with it. 我知道应该在使用变量之前检查它是否已定义。 But its very easy to forget something and keep working with an undefined var. 但是,很容易忘记某些东西并继续使用未定义的var。

Is there a global definition to the server to avoid such of a drop down? 服务器是否有全局定义以避免这种下降?

In any application there are a lot of "ifs" and assumptions. 在任何应用程序中,都有很多“如果”和假设。 With JavaScript, being weakly typed and dynamic, you can really shoot yourself in the foot. 借助弱类型且动态的JavaScript,您可以真正使自己陷入困境。

But the same rules apply here as any other language. 但是,这里的规则与其他任何语言一样适用。 Practice defensive programming . 练习防御性编程 That is, cover all the bases in each function and statement block. 也就是说,覆盖每个函数和语句块中的所有基础。

You can also try out programming Nodejs with Typescript . 您也可以尝试使用TypescriptNode.js进行编程 It ads some static type checking and other nice features that help you miss your foot when you shoot. 它广告了一些静态类型检查和其他出色的功能,可帮助您在拍摄时错过双脚。 You can also use (I think) Flow to statically type check things. 您还可以使用(我认为) Flow来静态键入检查内容。 But these won't make you a better programmer. 但是这些不会使您成为更好的程序员。

One other suggestion is to design your system as a SOA . 另一种建议是将系统设计为SOA So that one portion going down doesn't necessarily affect others. 因此,下降的一部分并不一定会影响其他部分。 "Microservices" being a subset of that. “微服务”是其子集。

The easiest solution I could think of is implementing a cluster, in which only one process will go down, not the whole server. 我想到的最简单的解决方案是实现集群,在集群中,只有一个进程将崩溃,而不是整个服务器。 You could also make the process to go up again automatically. 您也可以使该过程自动重新启动。 See more here 在这里查看更多

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);

  // Fork workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}

First, defensive programming and extensive testing are your friends. 首先,防御性编程和广泛的测试是您的朋友。 Obviously, preventing an issue before it happens is much better than trying to react to it after it happens. 显然,在问题发生之前就进行预防要比在事件发生后做出反应要好得多。

Second, there is no foolproof mechanism for catching all exceptions at some high level and then putting your server back into a known, safe state. 其次,没有万无一失的机制可以在某种程度上捕获所有异常,然后将服务器恢复为已知的安全状态。 You just can't really do that in any complex server because you don't know what you were in the middle of when the exception happened. 您根本无法在任何复杂的服务器中真正做到这一点,因为您不知道发生异常时的状态。 People will often try to do this, but it's like proceeding with a wounded server that may have some messed up internals. 人们经常会尝试这样做,但这就像处理一台受伤的服务器,可能会使内部结构混乱一样。 It's not safe or advisable. 这是不安全或不明智的。 If a problem was not intercepted (eg exception caught or error detected) at the level where it occurred by code that knows how to properly handle that situation, then the only completely safe path forward is to restart your server. 如果在知道如何正确处理该情况的代码中未在发生问题的级别上拦截到问题(例如,捕获到异常或检测到错误),则唯一完全安全的转发路径是重新启动服务器。

So, if after implementing as much defensive programming as you possibly can and testing the heck out of it, you still want to prevent end-user downtime from a server crash/restart, then the best way to do that is to assume that a given server process will occasionally need to be restarted and plan for that. 因此,如果在实施了尽可能多的防御性编程并对其进行了测试之后,您仍然希望防止服务器崩溃/重新启动导致最终用户停机,那么最好的方法是假设给定服务器进程有时将需要重新启动并为此计划。

The simplest way to prevent end-user downtime when a server process restarts is to use clustering and thus have multiple server processes with some sort of load balancer that both monitors server processes and routes incoming connections among the healthy server processes. 防止服务器进程重新启动时最终用户停机的最简单方法是使用群集 ,从而使多个服务器进程具有某种负载均衡器,该负载均衡器既监视服务器进程,又在运行状况良好的服务器进程之间路由传入的连接。 When one server process is down, it is temporarily taken out of the rotation and other server processes can handle new, incoming connections. 当一个服务器进程关闭时,它将暂时退出循环,其他服务器进程可以处理新的传入连接。 When the failed server process is successfully restarted, it can be added back to the rotation and be used again for new requests. 成功启动失败的服务器进程后,可以将其重新添加到循环中,并再次用于新请求。 Clustering in this way can be done within a single server (multiple processes on the same server) or across servers (multiple servers, each with server processes on them). 以这种方式进行群集可以在单个服务器(同一服务器上的多个进程)内或跨服务器(多个服务器,每个服务器上都有服务器进程)完成。

In some cases, this same process can even be used to roll out a new version of server code without any system downtime (doing this requires additional planning). 在某些情况下,甚至可以使用相同的过程来推出新版本的服务器代码,而不会导致系统停机(这样做需要额外的计划)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM