案例研究:Web应用间歇性SqlException
最近有客户找到我,说他们生产环境的事件日志中有下面的报错。要我帮忙找找原因。
Event Type: Warning
Event Source: ASP.NET 2.0.50727.0
Event Category: Web Event
Event ID: 1309
Description:
..
Event code: 3005 Event message: An unhandled exception has occurred.
Exception information: Exception type: SqlException Exception message: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
…
这是一个典型的asp.net unhandled exception记录。如果asp.net web应用运行的过程中出现异常,并且这个异常没有被web应用的代码捕捉到,asp.net运行时就会捕捉这个未处理的异常,并在应用程序事件日志中记录类似的记录。记录的ID总是1309。
这次的异常消息非常明确:web应用无法连接到数据库。从经验来看,出现这个错误时,往往连最基本的TCP三次握手都没有成功完成。也就是说TCP连接都还没有建立起来就失败了。
客户说这个问题并不总是发生,而是间歇性的会有几个出现在事件日志里面。
好医生从来不掐指算。没有数据支持的结论都是臆想。用Network Monitor工具收个网络包吧。我们从网络包中可以看到web前端和后端数据库之间的网络交互,有了它,我们就可以分析当时它们之间到底为什么不能建立连接。
一般情况下Network Monitor只能连续运行几分钟,否则记录的网络日志会非常大,拖累系统性能,并且难于分析。为了限制生成的日志文件的大小,我需要用命令行的nmcap.exe 工具,并且用/File参数来限制文件的大小。具体请参考nmcap.exe 。
另外一个使用的工具是DebugDiag。形象的说,它作用是在SqlException发生时,给IIS进程拍个快照(memory dump)。这样当问题发生时,所用内存中的信息都会被保存下来。这样事后我再看当时正在执行的代码,局部变量的值,函数的参数,连接字符串等等都不是问题。有关DebugDiag 的使用详解,请参考How to Use the Debug Diagnostic Tool v1.1 (DebugDiag) to Debug User Mode Processes
就这样客户连续运行了nmcap.exe和DebugDiag几天,问题终于又发生了。
用network monitor看TCP 3次握手,可以通过设置filter为tcp.Flags.Syn来过滤网络包。同时我假设SQL连接用的是默认的1433端口,所以同时使用filter: tcp.Port==1433。结果如下:
Time Delta |
Source |
Destination |
Description |
0.0000000 |
Web |
SQL |
TCP:Flags=......S., |
2.8593750 |
Web |
SQL |
TCP:[SynReTransmit]Flags=......S., |
6.0162010 |
Web |
SQL |
TCP:[SynReTransmit]Flags=......S., |
果然握手就出了问题。所要连接的SQL服务器一直没有响应,最后导致连接超时。
通过使用psscor2,可以从dump中解出当时的连接字符串如下:
data source=test1;persist security info=True;initial catalog=…
数据库的名字是test1,一看就是台测试服务器。一定是部署到生产环境后,忘了改连接字符串。但是为什么这个问题只是在处理有些请求时才发生?大多数请求还是好的?为什么出问题后,什么也不用做,后续的请求可能就自动恢复了?
Psscor2有个sam(save all modules)命令可以从dump中,把当时加载的所有.net assembly DLL都保存到别的目录。然后我就可以用像ILSpy 这样的工具来反编译DLL中的代码。
反编译结果如下:
public static string getConnectionString(string name)
{
string str = "T";
if (!isTesting())
{
str = "P";
}
return ConfigurationManager.ConnectionStrings[str + name].ConnectionString;
}
连接字符串是由getConnectionString ()函数返回的。这个函数根据isTesting ()的结果来返回生产或者测试环境中对应的连接字符串。继续往下看:
public static bool isTesting()
{
string a = HttpContext.Current.Request.Url.Host.ToLower();
return !(a == “www.contoso-production.com”);
}
看起来,逻辑还比较简单:如果请求的主机名不是生产环境的主机名,那就返回true。看起来挺合理,那为什么对于当时这个请求就出错了呢?
可惜当时那个请求的URL如下:
http://www.contoso-production.com.:80/default.aspx
请注意:80前面的那个点。根据RFC http://www.ietf.org/rfc/rfc1034.txt ,这个点是合理的,但是当时的判断逻辑不能很好的处理这种情况。
The most common interpretation uses the root "." as either the single origin or as one of the members of the search list, so a multi-label relative name is often one where the trailing dot has been omitted to save typing.
修改代码后,问题就不再出现了。如果你的应用里面也用到了类似的代码,那么也请注意了。
Juntao
案例研究:Web应用间歇性SqlException的更多相关文章
- 案例研究:Web应用出现间歇性的SqlException
案例研究:Web应用出现间歇性的SqlException 2013-07-29 14:36 by 微软互联网开发支持, 231 阅读, 3 评论, 收藏, 编辑 最近有客户找到我,说他们生产环境的事件 ...
- Netty实战十四之案例研究(一)
1.Droplr——构建移动服务 Bruno de Carvalho,首席架构师 在Droplr,我们在我的基础设施的核心部分.从我们的API服务器到辅助服务的各个部分都使用了Netty. 这是一个关 ...
- Coursera 机器学习课程 机器学习基础:案例研究 证书
完成了课程1 机器学习基础:案例研究 贴个证书,继续努力完成后续的课程:
- RDIFramework.NET ━ 9.16 案例模块━ Web部分
RDIFramework.NET ━ .NET快速信息化系统开发框架 9.15 案例模块 -Web部分 9.16.1.产品管理模块 产品管理模块提供了基本的增.删.改.查.导出.分页等的实现,用户可 ...
- Top100Summit全球案例研究峰会第一天总结——云计算和大数据
很荣幸受邀参加Top100Summit全球软件案例研究峰会,这次的大会主题是<技术推动商业变革>,组委会从全国投稿的460多件案例中甄选出100件具有代表价值的案例,进行为期4天的分享,第 ...
- JavaEE Tutorials (30) - Duke综合案例研究示例
30.1Duke综合应用的设计和架构456 30.1.1events工程458 30.1.2entities工程459 30.1.3dukes—payment工程461 30.1.4dukes—res ...
- JavaEE Tutorials (29) - Duke辅导案例研究示例
29.1Duke辅导应用的设计和架构44529.2主界面447 29.2.1主界面中使用的Java持久化API实体447 29.2.2主界面中使用的企业bean448 29.2.3主界面中使用的Web ...
- JavaEE Tutorials (28) - Duke书店案例研究示例
28.1Duke书店的设计和架构43828.2Duke书店接口439 28.2.1Book Java持久化API实体439 28.2.2Duke书店中使用的企业bean440 28.2.3Duke书店 ...
- 《Java大学教程》—第11章 案例研究--第1部分
自测题:1. 图11-1的UML设计中各个类之间的关系.Hostel与TenantList是关联关系:TenantList和PaymentList与ObjectList是泛化关系.TenantL ...
随机推荐
- Apizza可以进行本地调试,也可以进行跨域调试,但是需要chrome插件
装Apizza Chrome插件 1 1. 进入Apizza官方网站.注册账号,进入控制台,可以看到提示安装chrome插件 2. 进入google app商店,搜索apiano 找到对于插件安装 ...
- XAF学习笔记之-多表头设计
空闲之余,看了下全英文的DEV 的XAF帮助文档,一半的英文我认识他,一半的英文他认识我,反正拆开成26个字母我全认识 不那么啰嗦了,先看效果 如何做:分以下几步 第一步:打开这个文件,这个文件就是X ...
- create()创建的控件不能映射消息函数的解决
有时,使用create()在运行时创建的控件不能将消息映射到父窗口内,此时需要使用消息转发的机制,主要原理:注册一个全局的消息,针对接收消息的控件编写继承类,在该继承类中响应消息,并将已注册的全局消息 ...
- mac端的优秀抓包工具——Charles使用
http://my.oschina.net/u/2340880/blog/508688 mac端的优秀抓包工具——Charles使用 一.简介 二.安装与使用 三.使用Charles在mac上进行抓包 ...
- 云存储的那些事(2)——数据分布算法CRUSH
在分布式系统中,数据最终还是要存储到物理设备上的,ceph的底层设备抽象角色是OSD,那么数据是如何被决定放在哪块OSD上的,答案就是CRUSH算法. 关键字:CRUSH.一致性hash.ceph数据 ...
- 【温故Delphi】GAEA用到Win32 API目录
Delphi是Windows平台下著名的快速应用程序开发工具,它在VCL中封装并使用了大量的Win32 API. GAEA基于VCL开发的工具类产品,在程序中使用了大量的Win32 API,将经常用到 ...
- netload 加载程序集抛异常----无法加载程序集解决办法
netload 加载程序集抛异常----无法加载程序集 错误信息如下: 无法加载程序集.错误详细信息: System.BadImageFormatException: 未能加载文件或程序集“file: ...
- IOS调用WCF服务,WCF服务器进行上传图片
1.IOS端采用post方式请求服务器端的url地址 如:http://192.168.0.12:50000/serverce1.svc/upload IOS端的代码采用base64位编码的方式传值给 ...
- oracle权限语句大全
Oracle 系统默认的几个用户: sys --------网络管理用户,具有最高数据库管理权限 system------本地管理用户,权限次于sys scott-------普通用户,默认是锁住的( ...
- 字符串s中从第i个位置起取长度为len的子串,函数返回子串链表
/*已知字符串采用带结点的链式存储结构(详见linksrting.h文件),请编写函数linkstring substring(linkstring s,int i,int len),在字符串s中从第 ...