为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Azure SQL 数据库防止/处理 ErrBadConn

如何使用 Azure SQL 数据库防止/处理 ErrBadConn

Go
富国沪深 2021-12-20 15:14:00
我正在使用这个驱动程序:https : //github.com/denisenkom/go-mssqldb并且在使用 Azure SQL 数据库标准 S3 级别的生产中,我们得到了太多 ErrBadconn -driver: Bad connection返回。我怎样才能防止或至少优雅地处理它。这里有一些代码来展示事情是如何设置的。一个典型的数据库函数调用包 dalvar db *sql.DBtype Database struct{}func (d Database) Open() {    newDB, err := sql.Open("mssql", os.Getenv("dbconnestion"))    if err != nil {        panic(err)    }    err = newDB.Ping()    if err != nil {        panic(err)    }    db = newDB}func (d Database) Close() {    db.Close()}// ... in another filefunc (e *Entities) Add(entity Entity) (int64, error) {    stmt, err := db.Prepare("INSERT INTO Entities VALUES(?, ?)")    if err != nil {        return -1, err    }    defer stmt.Close()    result, err := stmt.Exec(entity.Field1, entity.Field2)    if err != nil {        return -1, err    }    return result.LastInsertId()}简而言之,该dal包在多个 Azure Web 应用程序和命令行 Go 应用程序之间共享。我看不到一种模式,即那些频繁且随机发生的错误。我们正在使用 Bugsnag 来记录我们所有应用程序的错误。为了完成,有时会达到我们的标准 S3 限制 200 个并发连接。我在访问数据库的包上的所有地方都进行了三重检查,确保所有内容sql.Rows都已关闭,所有db.Prepare语句都已关闭。作为示例,典型的查询函数如下所示:该readEntity基本上只做Scan上的字段。我认为这与代码无关,单元测试在本地运行良好。有时在运行后仅部署到 Azure 一次,驱动程序:错误连接开始非常频繁地出现。我已运行此查询以尝试查看此问题中的建议:Azure SQL server max pool size was connected 错误select * from sys.dm_exeC_requests但我不确定在这里我应该注意什么。我做过/确定过的事情。正如建议的那样,database/sql应该处理连接池,因此为数据库连接设置一个全局变量应该没问题。确保sql.Rows和db.Prepare声明在任何地方都是关闭的。将 Azure SQL 级别提高到 S3。我正在使用的 sql 驱动程序存在问题,如果它们空闲超过 2 分钟,则 Azure SQL 使数据库连接处于错误状态。 https://github.com/denisenkom/go-mssqldb/issues/81database/sql处理连接池的方式是否与 Azure SQL 数据库的管理方式不兼容。有没有办法优雅地处理这个问题?我知道 C#/Entity Framework 有一个针对 Azure SQL 的连接弹性/重试逻辑,是不是出于类似的原因?我如何实现这一点而不必在我的错误处理中到处传递?我的意思是我不想清楚地做这样的事情:if err == sql.ErrBadConn {  // close and re-open the global db object  // retry}这当然不是我唯一的选择吗?任何帮助将非常受欢迎。谢谢
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

岩,

您多久遇到这些连接问题?我建议您构建重试逻辑,以便从错误的连接中优雅地失败。以下是使用 C# 的方法:https : //azure.microsoft.com/en-us/documentation/articles/sql-database-develop-csharp-retry-windows/

如果您仍然觉得需要帮助,请随时通过 meetb@microsoft.com 向我发送包含您的服务器名称和数据库名称的电子邮件,我们将让我们的团队调查此问题。

干杯,见面


查看完整回答
反对 回复 2021-12-20
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

我没有看到您关闭数据库的任何地方。最佳实践(在其他语言中 - 对 Go 不利)是在使用后关闭/解除分配/取消引用数据库对象,将连接释放回池中。如果你的连接资源用完了,你会被告知你需要释放一些东西。保持引用打开意味着没有其他人可以使用该连接,因此它会一直存在,直到它因为超时而被回收。这就是为什么您会间歇性地而不是始终如一地获得它 - 这取决于在特定时间段内发生一定数量的连接。


查看完整回答
反对 回复 2021-12-20
  • 2 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信