1. Release it中稳定模式的一些理解

         这些模式就像设计模式一样,在我们的系统中不是看你使用了多少模式,或者说是否严格的遵守了这些模式,模式能解决的是大部分通用的情景,但是在实际应用时也要看上下文。

         Why bother this? 我们系统不是孤立存在,他依赖着很多服务(一个完全不依赖任何资源、服务的系统,几乎是不存在的,当然你可以举出反例,但我觉得这个系统的存在也没有太多意义),很多时候他和这些服务工作的很好但是如果你对他们没有任何防范的话,某天他会让你尝到苦头。

         在Release it! 一书中举出一些模式以防止某些经常发生的问题再次发生(本书作者提到自己所解决过的线上故障都是新问题,是因为他从不让同一个错误重复发生),的确是经验之谈,这里说下个人的理解。

         使用超时

         网络通常是不可靠的,我们的应用不能永远等待一个不知道何时才能响应的服务,我们对每个依赖和服务设置超时时间,如果在这个超时时间之内服务还不响应的话,就放弃,让应用继续服务,一方面我们已经尽了最大努力,一方面防止因为无尽的等待以至于因为不断的有新的请求发起导致连接资源耗尽,应用挂住。

         断路器

         大家都应该知道断路器是怎么工作的,当某个电器因为短路或者其他某些原因使得线路过热而断掉电源,然后可以重新开启电源,使得其他电器正常工作,而你接下来的事情就是检查那个有问题的电器。 同样,我们的系统也是如此,当某一个子系统出现问题或者在几次尝试确定失败之后,应该停止使用这个子系统,使得不会影响整个系统。

         防水壁

         就像轮船的防水舱一样,我们系统应当在漏水时仍然不会沉船。 防水壁这个我个人感觉和断路器有点类似,但是作者似乎对于防水壁更强调的是物理系统需要分区,在某个物理系统出现问题时,要使得其他物理系统不受影响,以保证整个系统继续工作。而且分区的主要手段就是冗余物理设备。

         稳定状态

         主要是说尽量不要没事干在线上机器上做些事情,然后举了些常见场景,例如数据清理以及日志文件、内存cache的问题。

         快速失败

         前面说的使用超时是面向服务消费方,即调用者的建议,而这个主要是面向服务提供方的,如果服务方的系统能够在可能发现失败前,立即回复失败的响应。这样调用方就不会一直等待服务方了(但是在为了保护自己,在不确定服务方是否采用了快速失败的模式,你最好还是设置超时)。但是如何预先知道将会失败呢,作者举了个简单的例子:当一个请求到来时,发现连接池没有可用的连接,应当立即拒绝这个连接请求。

         握手

         我们都知道TCP/IP协议的三次握手,主要是用来协调两台设备之间的通信,但是http协议以及RMI,CORBA等等很多通信协议本身都没有做好握手的工作,握手的好处在于一方忙时,另一方能知道他忙,会在后面不再做请求,或者间隔一个设置的时间再作尝试。 幸好看到作者强调了下底层协议最好需要握手,即通信很昂贵的时候,否则个人觉得握手有点鸡肋。

        Test Harness(这个不知道怎么翻译合适)

        集成测试只是证明在系统规约里明确好的正常情况是否ok,但是无法跳出规约进行测试,test harness是一种接近于边界或者说极端情况下对整个系统进行极限测试的方法,发现系统的漏洞和问题,其目的就像是一名恶意的黑客,极尽所能使得系统崩溃或者发生异常行为。

        解耦中间件

        从统一进程里编程语言里的方法调用到进程间通信到远程方法调用再到消息队列最终到不同时间不同地点不同进程间的通信,这是一个解耦的过程,越是解耦的设计,越能减少级联失败的发生。

        我说一下自己曾经就碰到过的问题,准确的说是我制造了这个问题: 在一个项目里我负责编写一个java库以供java前端开发人员访问后台的某个提供http服务的引擎,我使用了HttpClient来请求这个http服务,在这个整个开发过程中,一切都很顺利,然后就交付上线了。不幸的事情发生了,当天晚上前端就匆忙打电话通知我,坏事发生了:日志里显示有大量的读超时异常抛出,线上机器全部被挂住,初始大家以为后台服务有问题导致超时,但是后来dump了下java 堆栈信息,发现大量线程被Block住,查看了代码发现我写的某处有线程安全问题,使得连接并没有正确放回连接池,导致在连接池全部耗尽,新的请求获取不到连接,但是这并不足以使得机器全部挂住,后来一个有经验的开发指出,httpclient连接池默认的获取连接的超时时间是永久等待,这使得不断来到的新请求永久的等待可用的连接,吃不会放弃,等待队列中堆积了成千上万的请求,最终机器挂住。