后端系统开发之异常情况处理

智者千虑,必有一失。异常情况总是存在的,我们考虑不到全部场景。美剧《越狱》中精心策划一切的男主也做不到,例如男主意外烫伤导致纹身地图被毁。面对异常我们通常有两种选择,要么让它core掉,要么继续处理。

 

程序core掉的方法可以通过glog的FATAL级别日志,或者调用abort函数等方式终止程序。core掉的好处是很明显的,它能将严重的错误及时暴露出来,以便及早处理。后端系统通常都设计有容错冗余机制,一个进程core掉,其服务功能会自动由同组的其他进程来承担(failover),因此没有必要让“生病的程序带病工作”。

 

在计算机术语中,故障转移(英语:failover),即当活动的服务或应用意外终止时,快速启用冗余或备用的服务器、系统、硬件或者网络接替它们工作。(摘自维基百科:https://zh.wikipedia.org/wiki/故障转移)

 

什么情况下应该让程序主动core掉?最常见的情况是程序初始化资源失败的情况。例如创建日志失败、解析配置文件失败、绑定服务端口失败、创建内存池或对象池失败等,这些属于程序运行中必须使用的公共资源,一般是全局变量或单例形式,缺少这些资源程序无法提供正常功能。

 

但凡事总有例外,如果资源是可降级的,并非必不可少的,这个时候不应core掉,而应该记录错误日志,继续运行。还有一种情况可以考虑core掉,当系统资源不足时,例如内存资源耗尽,new返回NULL。或者socket描述符、线程数达到系统最大限制时,这时可以考虑让程序主动core掉,给它一次重生的机会,也可以让程序“带着伤病”继续运行。

 

哪些异常情况程序不能core而应该继续工作?有些异常情况是程序事先要考虑周全的,网络编程时,要判断消息是否合法,主动关闭错误或非法的连接。举个例子,针对网络爬虫流量、非法请求、非法参数,程序要有应对之策,而且绝对不能core掉,否则可能会出现大面积服务不可用这种尴尬情况。

 

在调用数学函数时,需要满足函数定义域要求,例如求平方根sqrt、求对数log等,需要保证参数值为非负数。在进行除法运算和求余运算时,需要保证被除数不为0。

 

使用系统调用或调用函数时,需要判断返回值,不能假定一定调用成功。使用指针时要非常小心,判断是否为NULL、小心内存泄漏和多次delete,尽可能使用智能指针而不是原生指针。最重要的一点,要遵循C++编程规范,在设计和实现过程中保持对技术应有的敬畏之心。

 

最后,简单说下C++语言的异常处理,C++的异常处理try..catch最好别用,真正的C++工程代码里很少使用异常。例如google protobuf的ParseFromArray在Java会抛异常,而C++版本是不抛异常的。写了属于画蛇添足。


金句分享

情商不高的例子有哪些?

对陌生人毕恭毕敬,对亲近的人随意发怒。

——来自知乎网友

解读:不要对身边的人发怒。

 

posted @ 2019-03-24 16:41  张巩武  阅读(902)  评论(1编辑  收藏  举报