异常处理是程序运行时必须要注意的地方。当出现异常时,应在第一时间注意到并迅速解决。大部分程序员都不敢保证自己的代码百分比是正确的,所以在写代码的时候应该提前预防异常,尽量保证在异常发生的时候给用户一个友好的提醒,以免造成服务挂。请求超时,可以记录并上报异常信息,方便后期排查和解决。1、同步代码的异常捕获和处理同步代码中的异常可以使用try{}catch结构进行捕获和处理。try{thrownewError('errormessage');}catch(e){console.error(e.message);}可以正常捕获。2、异步代码try/catch接口的错误处理使用try{}catch结构捕获处理异步代码有什么作用?try{setTimeout(()=>{thrownewError('errormessage');})}catch(e){console.error('erroris:',e.message);}然而并没有捕获到异步错误.如何处理进程的uncaughtException事件中的异步错误?首先,换个思路,因为异常没有提前准备,你无法控制它发生在什么地方,所以从更高的角度,比如监控应用进程的错误异常,从而捕捉到意想不到的错误异常和确保应用程序不会崩溃调。process.on('uncaughtException',(e)=>{console.error('进程错误是:',e.message);});上面的代码监听了进程的uncaughtException事件,可以捕获包括异步错误信息在内的整个进程,从而保证应用程序不会崩溃。但是新的问题接踵而至,因为异常发生后,当异常发生时,对应的执行栈直接被打断,在进程捕获到的异常事件下,v8引擎的垃圾回收功能无法按照正常进程工作,然后开始出现内存泄漏问题。与异常相比,内存泄漏也是一个不容忽视的严重问题,process.on('uncaughtException')方法很难保证不会造成内存泄漏。所以当异常捕获时,显式手动kill掉进程,重启node进程,既保证了内存释放,又保证了以后服务正常可用。process.on('uncaughtException',(e)=>{console.error('processerroris:',e.message);process.exit(1);restartServer();//重启服务});但是上面的做法有点直白,大家难免会有疑惑。单进程单实例部署下重启进程后一段时间内服务无法正常使用怎么办?这显然是不合理的。使用域模块domainmodule将多个不同的IO操作视为一个组。注册事件并回调域。当发生错误事件或抛出错误时,会通知领域对象,上下文不会丢失,程序错误不会导致程序立即退出,这一点与process.on('uncaughtException')不同.Domain模块可分为隐式绑定和显式绑定:隐式绑定:自动将领域上下文中定义的变量绑定到领域对象显式绑定:绑定领域上下文中未定义的变量,在代码const中绑定到领域对象domain=require('domain');constd=domain.create();d.on('error',(err)=>{console.log('err',err.message);console.log(needSend.message);});constneedSend={message:'一些需要传递给错误处理的信息'};d.add(needSend);functionexecute(){try{setTimeout(()=>{thrownewError('错误信息');});}catch(e){console.error('错误是:',e.message);}};d.run(执行);domin的一个明显优点就是可以在出错的时候传递一些信息给错误处理函数,可以做一些上报上报等处理工作。最起码能保证重启后的服务。可以选择将上下文传入,做一些后续处理。例如,当服务发生错误时,可以将用户请求堆栈信息发送到下游,通知用户服务异常,而不是让用户等到请求自动超时。...d.add(res);...d.on('error',(err)=>{console.log('err',err.message);res.end('发生异常服务器,请稍后重试!');});但是和process.on('uncaughtException')一样,很难保证不会造成内存泄露。另外根据官方文档,domain模块处理过时状态,但是没有其他方案可以完全替代domain模块,不过我现在的node10版本还是可以用的,应该不用担心关于域模块暂时过时。3、上述多进程模式加异常捕获重启的方法并不能完美解决问题。想一想如何防止异常发生后崩溃,捕获到异常后不造成内存泄漏,重启释放缓存又不会造成服务不可用?更好的解决方案是以多进程(集群)模式部署应用程序。当某个进程异常捕获时,可以做一些报告并重新启动以释放内存。这时候其他请求被接受后,其他进程仍然可以对外提供服务,当然前提是你的申请不能多到数不过来。下面是集群和域的结合,以多进程的方式保证服务可用。同时可以传递错误信息进行上报,并保留错误的上下文,并在不让用户请求超时的情况下将请求返回给用户。手动杀死异常进程并重启。constcluster=require('cluster');constos=require('os');consthttp=require('http');constdomain=require('domain');constd=domain.create();if(cluster.isMaster){constcpuNum=os.cpus().length;for(leti=0;i
