10.6 屏蔽异常
减少必须处理异常的地方的第二个技术是异常屏蔽(exception masking)。通过这种方法,可以在系统的低层检测和处理一个异常情况,这样高层的软件就无需了解该情况。异常屏蔽在分布式系统中特别常见。例如,在网络传输协议(如TCP)中,数据包可能因为各种原因被丢弃,如损坏和拥塞。TCP通过在它的实现中重发丢失的数据包来掩盖数据包的丢失,因此所有的数据最终都能通过,而客户没有意识到丢包。
一个更有争议的屏蔽例子发生在NFS网络文件中。如果一个NFS文件服务器崩溃或因任何原因无法响应,客户就会一次又一次地向服务器重新发出请求,直到问题最终得到解决。客户端上的低级别文件系统代码并不向调用的应用程序报告任何异常。正在进行的操作(以及应用程序)只是挂起,直到操作能够成功完成。如果挂起的时间超过了很短的时间,NFS客户端就会在用户的控制台打印出“NFS服务器xyzzy没有响应,仍在尝试”这样的信息。
NFS用户经常抱怨他们的应用程序在等待NFS服务器恢复正常运行时挂起。许多人建议,NFS应该用一个异常来中止操作,而不是挂起。然而,报告异常会使事情变得更糟,而不是更好。如果一个应用程序失去了对其文件的访问,它能做的并不多。一种可能性是应用程序重试文件操作,但这仍然会挂起应用程序,并且在NFS层的一个地方执行重试更容易,而不是在每个应用程序的每个文件系统调用中执行(编译器不应该担心这个!)。另一个选择是让应用程序中止并向其调用者返回错误。调用者不太可能知道该做什么,因此它们也会中止,从而导致用户的工作环境崩溃。当文件服务器停机时,用户仍然无法完成任何工作,而且一旦文件服务器恢复正常,他们将不得不重新启动他们的所有应用程序。
因此,最好的选择是让NFS屏蔽错误并挂起应用程序。采用这种方法,应用程序不需要任何代码来处理服务器问题,一旦服务器恢复正常,它们就可以无缝地恢复。如果用户厌倦了等待,他们总是可以手动中止应用程序。
异常屏蔽并不是在所有情况下都有效,但在它有效的情况下,它是一个强大的工具。它的结果是使类更深,因为它减少了类的接口(用户需要注意的异常更少),并以屏蔽异常的代码形式增加了功能。异常屏蔽是一个下拉复杂性的例子。
Last updated