Web API 在使用几天后总是无法连接到 MYSQL 数据库

Posted

技术标签:

【中文标题】Web API 在使用几天后总是无法连接到 MYSQL 数据库【英文标题】:Web API always can't connect to MYSQL db after using some days later 【发布时间】:2021-12-03 07:56:20 【问题描述】:

我有一个Web API,它工作了大约 20 天后无法连接到该mysql 服务器,因为它恢复正常我必须重新启动服务器,这真的很奇怪,我试图使用其他工具包(例如navicat)连接到MYSQL 服务器,在它无法连接到该数据库时,它无法正常工作,它只是无法连接到显示状态代码的MySQL 数据库,例如S1000 或@ 987654325@(我试着用谷歌搜索那个代码,它不起作用,我不知道如何处理这个问题) 我的 Web API 在 VS 2015 上使用 EF 5.0、.NET 4.6 构建在 C# 中。我将它部署在 Windows 2008 R2 服务器上,此 Web 服务器上的 IIS 上有 3 个 Web api,还有一个 Windows 2008 R2 服务器,它有 MySQL 服务器,版本是 5.5,因为我是只是开发人员,我只是在 web 服务器级别记录异常,我试图在 MySQL 端找到日志文件,DBA 没有在该数据库上记录任何文件,这真的很不幸。

这是我的控制器代码

  public DMLjfretModels uploadjfdetails(DMLjfparamsModels dmlparms)
    
        DMLjfretModels dmlret = new Models.DMLjfretModels();
        dmlret.returncode = 0;
        dmlret.expmsg = "";



        if (dmlparms.clicardjftype != "1" && dmlparms.clicardjftype != "2" && dmlparms.clicardjftype != "4")
        
            dmlret.returncode = -30;
            return dmlret;
        

        if ((dmlparms.clicard??"").Trim().Length != 10)
        
            dmlret.returncode = -60;
            dmlret.expmsg = "cardno is invald";
            return dmlret;
        

        try
        
            using (var context = new testEntities())
            
                context.Database.CommandTimeout = 180;
                if (ModelState.IsValid)
                
                    Globalvariable glv = new Globalvariable();
                    int result = glv.validate(dmlparms.username, dmlparms.password, dmlparms.curno);
                    if (result!=0)
                    
                        dmlret.returncode = result;
                        return dmlret;
                    

                    string clicardstring = dmlparms.clicard.Trim();
                    var memberresult = context.wp_client_card.Where(x => x.cli_card == clicardstring);
                    int therecordscount = memberresult.Count();

                    try
                    
                        string filePath = @"d:\\log\\lognumber" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt"; 

                        using (StreamWriter writer = new StreamWriter(filePath, true))
                        
                            writer.WriteLine("cli_card:" + clicardstring ?? "" + ",listno:" + dmlparms.clicardjflistno ?? "" + ",countvalue:" + therecordscount.ToString());
                            writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
                        

                    
                    catch (Exception ex)
                    
                        string filePath = @"d:\\log\\Error" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";

                        using (StreamWriter writer = new StreamWriter(filePath, true))
                        
                            writer.WriteLine("Message :" + ex.Message + "<br/>" + Environment.NewLine + "StackTrace :" + ex.StackTrace +
                               "" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
                            writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
                        
                    

                    if (therecordscount == 0)
                    
                        dmlret.returncode = -25;
                        return dmlret;
                    



                    if (dmlparms.clicardjftype== "1" || dmlparms.clicardjftype == "2")
                    
                        foreach (DMLdetailModels dm in dmlparms.clidetails)
                        
                            if (string.IsNullOrEmpty(dm.prodno) || string.IsNullOrEmpty(dm.batchno)
                                || string.IsNullOrEmpty(dm.prodadd) || dm.prodnum <= 0.0 || dm.sellprice <= 0.0
                                || dm.stdprice <= 0.0  || dm.clicardjfnum<=0.0)
                            
                                dmlret.returncode = -33;
                                return dmlret;
                            
                        
            
                    
                    else
                    
                        decimal thesum = context.wp_cli_card_jf.Where(x => x.cli_card==dmlparms.clicard.Trim()) 
                         .Sum( 
                                        d =>
                                        ((d.cli_card_jf_type == "1") && (d.cli_card_jf_num != null))
                                         ? d.cli_card_jf_num
                                          : ((d.cli_card_jf_type == "2") && (d.cli_card_jf_num != null))
                                          ? ((Decimal?)((Decimal)0) - d.cli_card_jf_num)
                                          : ((d.cli_card_jf_type == "4") && (d.cli_card_jf_num != null))
                                          ? ((Decimal?)((Decimal)0) - d.cli_card_jf_num)
                                          : (Decimal?)((Decimal)0)
                                           )??0.0M;

                        

                        decimal thesumjf = 0.0M;
                        foreach(DMLdetailModels details in dmlparms.clidetails)
                        
                            thesumjf = thesumjf + Convert.ToDecimal( details.clicardjfnum);
                        

                        if (thesum< thesumjf)
                        
                            dmlret.returncode = -50;
                            return dmlret;
                        

                    

                    foreach (DMLdetailModels detail in dmlparms.clidetails)
                    
                        //write the data into my database
                        context.wp_cli_card_jf.Add(wjf);
                    

                    context.SaveChanges();
                    return dmlret;

                
                else
                   
                    dmlret.returncode = -20;
                    return dmlret;
                
            
        
        catch (Exception ex)
        
           
           logfile(ex);
        

    

顺便说一句,我也在 webapi 中记录了请求和响应

      public class LogRequestAndResponseHandler : DelegatingHandler

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    
        String UUID = Guid.NewGuid().ToString();
        // log request body
        string requestBody = await request.Content.ReadAsStringAsync();
        string requestmethod = request.RequestUri.ToString();
        string mymethod = requestmethod.ToLower();



        // let other handlers process the request
        var result = await base.SendAsync(request, cancellationToken);

        if (result.Content != null)
        
            // once response body is ready, log it
            var responseBody = await result.Content.ReadAsStringAsync();
            logrequestnresponse(UUID, requestBody, responseBody.ToString(), mymethod);
        

        return result;
    


    private void logrequestnresponse(string uuid, string requestbody, string responsebody,string requestmethod)
    
        try
        
             using (var context = new testEntities())
              
                  context.Database.CommandTimeout = 180;
                  wp_web_api_log wplog = context.wp_web_api_log.Create();
                  wplog.row_index = uuid;
                  wplog.request_detail = requestbody;
                  wplog.request_url = requestmethod;
                  wplog.response_detail = responsebody;
                  context.wp_web_api_log.Add(wplog);
                  context.SaveChanges();
               

            string filePath = @"d:\\log\\Logfile.txt";

      
        
        catch (Exception ex)
        
            
             logfile(ex);

         
    

我的日志文件记录了在那段时间它无法连接到 MYSQL 数据库

 Message :The underlying provider failed on Open<br/>
 StackTrace :   at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
 at System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection(Boolean shouldMonitorTransactions)
 at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
 at System.Data.Entity.Internal.InternalContext.SaveChanges()
 at dggyapi.LogRequestAndResponseHandler.Logrequestnresponse(String uuid, String requestbody, String responsebody, String requestmethod),",method:querymember
 Overall Exception:System.Data.Entity.Core.EntityException: The underlying provider failed on           Open---> MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts. ---> System.Net.Sockets.SocketException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
 at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
 at System.Net.Sockets.Socket.InternalBind(EndPoint localEP)
 at System.Net.Sockets.Socket.BeginConnectEx(EndPoint remoteEP, Boolean flowContext, AsyncCallback callback, Object state)
 at System.Net.Sockets.Socket.BeginConnect(EndPoint remoteEP, AsyncCallback callback, Object state)
 at MySql.Data.Common.MyNetworkStream.CreateSocketStream(MySqlConnectionStringBuilder settings, IPAddress ip, Boolean unix)
 at MySql.Data.Common.MyNetworkStream.CreateStream(MySqlConnectionStringBuilder settings, Boolean unix)
 at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
 at MySql.Data.MySqlClient.NativeDriver.Open()
 ---  End of inner exception stack trace ---
 at MySql.Data.MySqlClient.NativeDriver.Open()
 at MySql.Data.MySqlClient.Driver.Open()
 at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
 at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
 at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
 at MySql.Data.MySqlClient.MySqlPool.GetConnection()
 at MySql.Data.MySqlClient.MySqlConnection.Open()
 at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
 at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection, DbInterceptionContext interceptionContext)
 at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
 ---  End of inner exception stack trace ---
 at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
 at System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection(Boolean shouldMonitorTransactions)
 at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
 at System.Data.Entity.Internal.InternalContext.SaveChanges()
 at dggyapi.LogRequestAndResponseHandler.Logrequestnresponse(String uuid, String requestbody, String responsebody, String requestmethod)
 Innerexception:System.Net.Sockets.SocketException (0x80004005): An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
 at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
 at System.Net.Sockets.Socket.InternalBind(EndPoint localEP)
 at System.Net.Sockets.Socket.BeginConnectEx(EndPoint remoteEP, Boolean flowContext, AsyncCallback callback, Object state)
 at System.Net.Sockets.Socket.BeginConnect(EndPoint remoteEP, AsyncCallback callback, Object state)
 at MySql.Data.Common.MyNetworkStream.CreateSocketStream(MySqlConnectionStringBuilder settings, IPAddress ip, Boolean unix)
 at MySql.Data.Common.MyNetworkStream.CreateStream(MySqlConnectionStringBuilder settings, Boolean unix)
 at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
 at MySql.Data.MySqlClient.NativeDriver.Open()

我刚刚重新启动了我的网络服务器,并尝试跟踪持久性并找到了

  mysql> show status where variable_name like 'thread%';
  +-------------------+-------+
  | Variable_name     | Value |
  +-------------------+-------+
  | Threads_cached    | 4     |
  | Threads_connected | 41    |
  | Threads_created   | 53302 |
  | Threads_running   | 2     |
  +-------------------+-------+
  4 rows in set

  mysql> show processlist;
    +----------+---------+--------------------+--------+---------+------+-------+------------------+
  | Id       | User    | Host               | db     | Command | Time | State | Info             |
        +----------+---------+--------------------+--------+---------+------+-------+------------------+
  |  3540670 | myuser  | localhost:56924    | NULL   | Sleep   |  111 |       | NULL             |
  |  3540671 | myuser  | localhost:56925    | NULL   | Sleep   |  111 |       | NULL             |
  |  3540692 | myuser  | localhost:56928    | NULL   | Sleep   |    2 |       | NULL             |
  | 11278418 | myuser  | 192.168.0.200:1038 | mydb   | Sleep   |   44 |       | NULL             |
  | 11278428 | myuser  | 192.168.0.200:1043 | mydb   | Sleep   |   38 |       | NULL             |
  | 11278439 | myuser  | 192.168.0.200:1044 | mydb   | Sleep   |   33 |       | NULL             |
  | 11278441 | myuser  | 192.168.0.200:1045 | mydb   | Sleep   |   15 |       | NULL             |
  | 11278597 | myuser  | 192.168.0.200:1077 | mydb   | Sleep   |   18 |       | NULL             |
  | 11278602 | myuser  | 192.168.0.200:1078 | mydb   | Sleep   |    6 |       | NULL             |
  | 11278627 | myuser  | 192.168.0.200:1080 | mydb   | Sleep   |  102 |       | NULL             |
  | 11278654 | myuser  | 192.168.0.200:1082 | mydb   | Sleep   |  102 |       | NULL             |
  | 11278668 | myuser  | 192.168.0.200:1087 | mydb   | Sleep   |   97 |       | NULL             |
  | 11278710 | myuser  | 192.168.0.200:1088 | mydb   | Sleep   |   89 |       | NULL             |
  | 11278768 | myuser  | 192.168.0.200:1089 | mydb   | Sleep   |   89 |       | NULL             |
  | 11278780 | myuser  | 192.168.0.200:1090 | mydb   | Sleep   |   88 |       | NULL             |
  | 11278781 | myuser  | 192.168.0.200:1091 | mydb   | Sleep   |   85 |       | NULL             |
  | 11278805 | myuser  | 192.168.0.200:1092 | mydb   | Sleep   |   76 |       | NULL             |
  | 11278860 | myuser  | 192.168.0.200:1093 | mydb   | Sleep   |   73 |       | NULL             |
  | 11278877 | myuser  | 192.168.0.200:1094 | mydb   | Sleep   |   66 |       | NULL             |
  | 11278898 | myuser  | 192.168.0.200:1099 | mydb   | Sleep   |   54 |       | NULL             |
  | 11278913 | myuser  | 192.168.0.200:1100 | mydb   | Sleep   |   46 |       | NULL             |
  | 11278935 | myuser  | 192.168.0.200:1101 | mydb   | Sleep   |   42 |       | NULL             |
  | 11303229 | myuser  | 192.168.0.200:1833 | mydb   | Sleep   |    3 |       | NULL             |
  | 11307621 | myuser  | 192.168.0.200:2006 | mydb   | Sleep   |  161 |       | NULL             |
  | 11307953 | myuser  | 192.168.0.200:2028 | mydb   | Sleep   |   93 |       | NULL             |
  | 11307998 | myuser  | 192.168.0.200:2029 | mydb   | Sleep   |   76 |       | NULL             |
  | 11308004 | myuser  | 192.168.0.200:2030 | mydb   | Sleep   |   74 |       | NULL             |
  | 11308244 | myuser  | 192.168.0.200:2038 | mydb   | Sleep   |  147 |       | NULL             |
  | 11308349 | myuser  | 192.168.0.200:2044 | mydb   | Sleep   |  132 |       | NULL             |
  | 11308350 | myuser  | 192.168.0.200:2045 | mydb   | Sleep   |  127 |       | NULL             |
  | 11308387 | myuser  | 192.168.0.200:2051 | mydb   | Sleep   |  126 |       | NULL             |
  | 11308416 | myuser  | 192.168.0.200:2052 | mydb   | Sleep   |  119 |       | NULL             |
  | 11308454 | myuser  | 192.168.0.200:2053 | mydb   | Sleep   |   71 |       | NULL             |
  | 11308460 | myuser  | 192.168.0.200:2054 | mydb   | Sleep   |   98 |       | NULL             |
  | 11308487 | myuser  | 192.168.0.200:2055 | mydb   | Sleep   |   44 |       | NULL             |
  | 11308498 | myuser  | 192.168.0.200:2056 | mydb   | Sleep   |   23 |       | NULL             |
  | 11308542 | myuser  | 192.168.0.200:2057 | mydb   | Sleep   |   13 |       | NULL             |
  | 11308560 | myuser  | 192.168.0.200:2058 | mydb   | Sleep   |   10 |       | NULL             |
  | 11308682 | myuser  | server5:5190       | NULL   | Sleep   |  117 |       | NULL             |
  | 11308722 | myuser  | server5:51903      | mydb   | Query   |    0 | NULL  |       show processlist |
        +----------+---------+--------------------+--------+---------+------+-------+------------------+
  40 rows in set
  

这正常吗?

【问题讨论】:

抱歉回复晚了,非常感谢@LeandroBardelli先生,真的很感谢它 【参考方案1】:

问题似乎很清楚,错误说:

System.Net.Sockets.SocketException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

造成这种情况的原因可能是多方面的(您可以 google 一下),但通常是因为缺少硬件、缺少服务器更新、过时的更新,或者您没有在连接上处理对象,或者没有关闭连接,内存不足,资源不足,但在定义上:你使用了很多端口。

你可以试试这个:

在 Windows Server 2008 R2 上 打开命令提示符

键入以下内容 netsh int ipv4 设置动态端口 tcp start=10000 num=50000 按回车

键入以下内容 netsh int ipv4 set dynamicport udp start=10000 num=50000 按回车

键入以下内容 netsh int ipv6 set dynamicport tcp start=10000 num=50000 按回车

键入以下内容 netsh int ipv6 set dynamicport udp start=10000 num=50000 按回车

更多信息请访问: http://web.archive.org/web/20160118151510/http://blogs.technet.com/b/askds/archive/2008/10/29/port-exhaustion-and-you-or-why-the-netstat-tool-is-your-friend.aspx

https://blog.whitesites.com/blog.aspx?key=635140180116307813

【讨论】:

老实说,我没有尝试执行这些命令,因为这是一个紧急场景,我不得不重新启动服务器,即使问题暂时消失了,问题还没有真正解决,但我会尝试减少我代码中的端口,我真的很感谢你的帮助,希望它能解决我的问题

以上是关于Web API 在使用几天后总是无法连接到 MYSQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 JQuery 连接到 Web 服务

无法从 NET Core 2.2 Web API 连接到 docker sql server

Azure AD 将多个应用程序连接到单个 Web API

Docker 中的 web api 无法连接到主机上的 SQL Server,出现登录前握手错误

无法连接到 MySQL 服务器

C# 和 Docker - 无法从容器化 .NET Core 3.1 Web API 连接到容器化 MySQL 服务器