一个诡异的bug的查找

一个诡异的bug的查找

以前写的一个异步防垃圾系统,有访问mysql 数据源.
而且运行都快大半年了,非常稳定。
然后前阵子机房掉电,损坏了服务器。
移到一台新的server上来了,却一直不稳定。
如果改成连接池,异常消除。
禁用连接池问题依旧。

报的异常信息是:
MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts. ---> System.Net.Sockets.SocketException: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 192.168.XXX.XXX:3306
   在 System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   在 MySql.Data.Common.StreamCreator.CreateSocketStream(IPAddress ip, Boolean unix)
   在 MySql.Data.Common.StreamCreator.GetStream(UInt32 timeout)
   在 MySql.Data.MySqlClient.NativeDriver.Open()
   --- 内部异常堆栈跟踪的结尾 ---
   在 MySql.Data.MySqlClient.NativeDriver.Open()
   在 MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
   在 MySql.Data.MySqlClient.MySqlConnection.Open()
   在 Microsoft.Practices.EnterpriseLibrary.Data.Database.GetNewOpenConnection()
   在 Microsoft.Practices.EnterpriseLibrary.Data.Database.GetOpenConnection(Boolean disposeInnerConnection)
   在 Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteScalar(DbCommand command)
   在 Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteScalar(CommandType commandType, String commandText)


报"通常每个套接字地址(协议/网络地址/端口)只允许使用一次"异常以前也见过,
比如重复listing 一个端口会报此信息,但后面不会跟remote host的IP 和port.
而这异常消息是:
中文版:
通常每个套接字地址(协议/网络地址/端口)只允许使用一次
英文版:
"Only one usage of each socket address (protocol/network address/port) is normally
permitted <IP ADDRESS/PORT HERE>."

1.第一个就是想办法复现这个问题
同样一套代码在本地就是不出问题
2.第二对比了环境。
mysql connector版本不一样
通过分析connector的源码发现,这块基本没有多少改动,而且后面我也统一了版本。
3.猜测是异步代码访问到同步代码,引起的资源冲突
写了一个多线程并发程序测试,也很正常。

这么一个小小问题,分析和查询了半天,就是没有复现和查询出来。后面发现用连接池没有问题,就这样一直放着,但感觉一直是个炸弹在那里,哪天DBA要求我改成短连接,问题又出来了。

今天突然想起前阵子写的tcp server,在做并发测试时,不同平台的连接数情况不同,测试结果不同。
在xp win server2003当socket连接数大于4000时,初使化socket时就会出现异常。
然后在win7 winserver 2008下,连接数大于20000,初使化socket依然稳定。
联想一下,会不会是由于这个稳定引起的?
后面写了一个代码在不同的机器上进行测试:
class Program
{

static void Main(string[] args)
{
 DbTest();
}

private static void DbTest()
{

 // The connection string should have Pooling=false;

 string connectionString = "<INSERT CONNECTION STRING HERE>";

 MySqlClientFactory mysql = MySqlClientFactory.Instance;

 DbConnection connection = mysql.CreateConnection();
 connection.ConnectionString = connectionString;

 DbCommand command = mysql.CreateCommand();
 command.Connection = connection;
 command.CommandText = "<INSERT FAVORITE QUERY HERE>";

 int i = 0;

 while (true)
 {
  i++;

  try
  {
   Console.WriteLine(i);

   connection.Open();

   command.ExecuteNonQuery();
  }
  catch (Exception ex)
  {
   System.Diagnostics.Trace.Write(ex);
   Console.WriteLine(ex);

   throw;
  }
  finally
  {
   connection.Close();
  }
 }
}
}

在winserver2003里
i==2341时,问题就复现现来了
MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified
 MySQL hosts. ---> System.Net.Sockets.SocketException: 通常每个套接字地址(协议/
网络地址/端口)只允许使用一次。 192.168.XXX.XXX:3306
   在 System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   在 MySql.Data.Common.StreamCreator.CreateSocketStream(IPAddress ip, Boolean u
nix)
   在 MySql.Data.Common.StreamCreator.GetStream(UInt32 timeout)
   在 MySql.Data.MySqlClient.NativeDriver.Open()
这时查
本地连接服务器端占用的socket句柄资源为:3853个约等于4000

现在基本是可以确定问题了
windows服务器连接数测试发现能达到50000个。但服务器自己内部发起连接通信数量只能达到4000。
原因是服务器发送端口范围从1024-5000之间。软件编程需要考虑此问题。


以前此系统是运行在win server 2008上,而现在运行在win server 2003上,由于并发量比较大,采用短连接,占用的
socket句柄资源来不及释放。
socket 如果系统自己释放默认是4分钟。
降低等待时间和增加最大端口数量可以提高系统的数据吞吐率.

可选的解决方案:
1.采用连接池
2.采用win server 2008 系统
3.把系统的socket清理时间设置得更短(30S,不要太短)
4.优化系统配置,修改系统端口范围
  优化的详情可以参考:http://bbs.itwgw.com/redirect.php?tid=94&goto=lastpost X系列服务器上Windows Server 2003性能优化

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值