当出现未被程序捕捉的异常时, 整个服务将会终止. 即使有的异常被捕捉, 但是无法返回有效的失败响应, 只能通过返回服务超时也会影响产品的体验. 总的解决方案是 try…catch 捕获程序中的同步异常, 异步异常分为多种情况
- Promise不需要使用try…catch,直接使用.catch()
- Generator 可以直接使用co 函数库来使用try…catch
- async 和 await 可以直接使用try…catch
- 回调函数可以通过 domain 模块来捕捉异常. (domain 模块正在被弃用, 谨慎使用)
- process.on(‘uncaughtException’, function(e) { … }) 捕捉未被程序捕捉的异常, 需要注意的是 ‘uncaughtException’ 异常会丢失当前环境的堆栈信息, 导致 Node 不能进行内存回收, 也就是说每一次的 uncaughtException 都有可能导致内存泄漏, 为了防止内存泄漏, 需要优雅的退出程序.
- 对比之下 process.on(‘unhandledRejection’, function(e){ … }), 捕捉的是未被 catch 的 promise 内的异常, 也就是 promise 内的 reject. 不同的是 unhandledRejection 并不会直接使程序退出, 只是会抛出 UnhandledPromiseRejectionWarning: …
因为 domain 即将被弃用, 就不重点研究了, 感兴趣的可以看一下相关的参考文章: https://nodejs.org/api/domain.html# https://cnodejs.org/topic/516b64596d38277306407936
# uncaughtException
为了防止 uncaughtException 导致内存泄漏, 当捕捉到 uncaughtException 时, 应该重启服务.
|
|
- Node 所有连接都被释放后进程会自动结束, 所以不需要在 server.close 方法的回调函数中退出进程
- 强制退出机制, 用户连接有可能因为某些原因无法释放,在这种情况下应该强制退出整个进程。
- timer.unref(): 如果不使用 unref 方法,那么即使 server 的所有连接都关闭,Node 也会保持运行直到 timer 的回调函数被调用。unref 可以创建一个"不保持程序运行"的计时器。
- 处理异常时要小心的把异常处理逻辑用 try/catch 包住,避免处理异常时抛出新的异常
# 和 cluster 一起使用
|
|