应该找到了问题的真正原因
根据故障期间的错误信息:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
找到了这三篇博文:
2. Interesting SQL Server Mirroring Problem
谈到的都是SQL Server数据库镜像引起的"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding." 尤其是第3篇中的一段文字:
As per the Connection Retry Algorithm for Mirroring, SqlClient code takes the connection timeout and multiplies it by 0.08 to determine the milliseconds to wait for first read (SniReadSync call). Now if this first SniReadSync fails due to a timeout (due to a slow response from the server), the connection is incorrectly set to a doomed state by the sqlClient .NET Provider and this causes the connection attempt to prematurely fail before the entire connection timeout expires.
联想到阿里云RDS与我们之前自己的物理服务器、阿里云云服务器时最大的不同之处是:阿里云RDS使用了SQL Server数据库镜像。
立即眼前一亮!问题的真正原因就在这——ADO.NET对SQL Server数据库镜像处理上的bug。
故障是这么发生的:
1. 我们在博客程序的连接字符串中设置的是Connect Timeout=30(默认是15);
2. SqlClient将 30(Connect Timeout) × 0.08 = 2.4s 作为超时时间发起一次数据库连接操作;
3. 对于SQL Server数据库镜像的场景,SqlClient只对Principal数据库发起1次且仅此1次数据库连接操作(不合理,至少失败时重试一次);
4. 如果超时,SqlClient就会去连接“连接字符串”中通过Failover Partner指定的镜像数据库;(4月17日故障时就是发生了超时情况)
5. 而我们在连接字符串中没有指定Failover Partner,SqlClient也没有镜像数据库可连,于是SqlClient就自以为是地Timeout。
这是ADO.NET的一个bug,微软在2011年就确认了这个bug,说是在下一版本中(也就是现在的.NET Framework 4.5)会修复这个问题。
Microsoft has confirmed that this is a problem in the current release of ADO.NET. This issue will be fixed in ADO.NET version, ships with Visual Studio 2011.
而我们的博客程序用的是.NET Framework 4.0,没能躲开这个bug的魔爪。
目前还不知道.NET Framework 4.5是不是真的解决了这个问题。
真没想到,最终竟然是被微软坑的!
临时解决方法:在连接字符串中设置Connect Timeout=150,并从网络与数据库层面尽量减少连接时间。
补充:有人在阿里云论坛上提到“之前用RDS时就会偶尔出现秒级以上的延时”,这可能也是一个肇事者。
更新:“问题的真正原因”背后的真正问题是为什么数据库连接会超时(注:只是连接,查询还没开始)?
相关博文:
我与IBM敏捷培训中心的一次交流后的问答,关注的敏捷的可以看看交流.
XXX:
你的这些问题都是很好的问题,有些问题,我们自己也在思考, 我就这些问题发表一下我自己的看法,见下面的蓝字部分:
邮件正文:
您好:那天的培训我提了几个,还有几个请帮忙解答一下,可能有些问题比较幼稚:)
1、敏捷合适什么样的项目类型? 因为IBM的项目大部分是产品研发类型的项目,可以很好的做一个比较长期的规划,明确发布计划和迭代周期,但对于那种需求不是非常明确或者经常变来变去的项目,感觉是不是不太合适??
敏捷思想和实践能适应的项目类型非常广泛,但不等于适合所有的项目,我去年参加了中国敏捷开发者大会、中国软件过程改进年会,从交流的内容来看,进行敏捷实施的项目类型很多,涵盖产品和项目,而且项目类型分散在各个行业领域,项目周期有长的也有短的,但是很难用简单的语言来概括哪些项目适合敏捷,哪些不适合。关键是在敏捷实施过程中灵活、准确的采用合适的敏捷流程和实践。敏捷不能包治百病,有时候我们的药方需要综合一些,结合敏捷已经其他的开发模型。
2、对于敏捷开发,这个干系人是非常重要的,对于客户来说,很多时候能参与到项目的人基本上是客户的项目经理,但这个人应该不是关键用户,对于一个比较复杂的项目,关键用户是很多的,但这些人是不是都要参与进来?? 实际情况下,很难做到让他们都参与进来的,仅仅这个PM肯定是不够的,这种情况下如何处理?
干系人的范围比较大,在项目中我们要抓住关键干系人。如果关键干系人有很多,我们很难让他们同时参与每次的计划、演示会议,我可以安排在不同的milestone给不同类型的干系人演示,过多的演示和反馈不但消耗大量的时间,而且容易造成干系人反馈意见难以统一。
3、敏捷开发与现在常用的分阶段开发的区别,你那天也提了一下,我想有没有更好的优劣对比?我个人认为分阶段开发可能更合适些,这个阶段周期可以根据需求情况可长可短,不受敏捷的固定迭代周期限制。
敏捷和其他的开发模型,我认为没有好坏之分,关键是针对项目的具体情况,选择适合的开发模型,敏捷的很多思想就来源于其他的开发模型例如Scrum、OpenUP,RUP,XP等。
4、敏捷的一个优点的是叫快速反馈,但很多项目,有时候在一个迭代内可能做的都是后端的基础研发,在前端UI上根本没有什么东西给客户看,这种情况下会不会存在一定的风险?
这样的阶段不能持续时间太久,即使是后端的开发也需要有验收的标准,比如自动化测试,或者是测试驱动开发。没有验收标准,如何保证质量,如何保证开发的成果能满足客户的需要,这种情况下的开发风险显而易见很大。
5、对于敏捷类型的项目,如何给客户报工作量??常规项目,一般都是在项目开始时把全部需求整理出来,然后整体评估工作量并给出一个合理的报价,但按照敏捷的思路,它不需要这样,只需要在每次迭代之前明确这次迭代的需求即可,它号称的是快速响应用户的变化,也就说通常是边做边确定后续的迭代需求,但这种方式貌似在开始的时候不好评估整体工作量?
我一直也在思考这个问题,敏捷的开发模式对估算整个项目的整体工作量是没有好的办法的,只能借助其他的手段来实现,比如,企业的组织过程资产库,或者其他的项目流程等,IBM就是采用IPD和敏捷开发相结合的方法来实现的。
6、无论是否敏捷,其实最关键的都是:人的自我能动性,如果开发人员的自我素质很好,对自己的开发东西非常认真负责,而且团队内部的沟通也非常好,那么是否敏捷是否还有必要??
你会发现,敏捷是没有一个固定的定义的,只有敏捷宣言和12条准则,敏捷重在方法,来确保这些目标的实现,如果你有很好的方法来实现团结成员有很好的能动性,那这本身也可以说是一种敏捷实践,虽然这不是典型的常见的敏捷实践。敏捷最佳实践就是收集并分享这些好的方法。
7、敏捷转型涉及到HR、财务等其他部门,对于IT这个对企业来说并不是很重视的部门,如何去推动整个组织的变化??
这个问题好像在会上回答过了,我想只能循序渐进了,纯的自上而下或者自下而上的去推动都是非常困难的,我们需要领导的支持和信任,同时开发团队也愿意去实践来解决他们的头疼的事情,在这种情况下进行敏捷转型是比较合适的。对于IT部门在整个公司的组织结构中地位偏低的情况,我想先把开发的事情做好,让敏捷能真正地解决我们的问题,同时带给我们受益,改善我们的业务目标,在这个基础上再逐渐对其他部门产生影响,这个时间会更长一些。
8、敏捷的核心是什么?? 或者说带来的最大的变化是什么?? 是迭代吗(分阶段类似)?是需求管理方式的改变(这个的优劣目前不明显)?是单元及自动化测试(这个无论是否敏捷,都是必须的)?还是TDD(这个感觉推动起来非常困难)??
我认为敏捷的核心就是我提到的那四点:准、快、优、稳,以及确保这些目标得以实现的敏捷实践。