我为我的.NET程序创建了一个Dockerfile。该程序在我的桌面和没有Docker的Windows Server 2016(Azure VM)上运行良好。当我尝试将其作为容器运行时(基于microsoft/windowsservercore),然后在连接到我的Azure SQL实例时经常会出现数据库错误。
我有两个Azure SQL实例在运行(P1和无负载)。当可以建立连接时,它们非常快,但问题是通常无法建立连接。看起来网络非常不稳定。这些都是我的典型错误:
System.Data.SqlClient.SqlException:与网络相关或 建立连接时发生特定于实例的错误 SQL Server。服务器未找到或无法访问。校验 实例名称正确且SQL Server配置为 允许远程连接。 (提供者:命名管道提供商,错误:40 - 无法打开与SQL Server的连接)
内部异常报告找不到网络路径。起初我以为它可能是我的本地计算机,但它在Azure上的Windows Server 2016(带容器)VM实例上也存在问题。
为了查明问题,我创建了一个每隔5秒连接到我的数据库的测试程序(并运行SELECT COUNT(*) from sysobjects
)。该程序总能成功找到数据库。
我的其他程序似乎经常在启动时失败,但在初始化期间会有很多数据库调用。我怀疑线程,连接池,......有什么不同。
任何人都有线索?
答案 0 :(得分:2)
目前我们还遇到了Windows容器的更多网络问题。但是,使用Azure / Containers中的软件定义网络,一般建议使用一些重试逻辑。
如果您正在使用实体框架,则可以插入不同的弹性和重试策略“SqlAzureExecutionStrategy”。这通常不仅适用于Azure,而且可以帮助减少异常。
本文介绍了如何: https://msdn.microsoft.com/en-us/library/dn456835(v=vs.113).aspx
答案 1 :(得分:1)
错误消息来自命名管道提供程序似乎很奇怪,因为Azure SQL只能通过TCP / IP连接。不知何故,它似乎回退到命名管道,可以通过在主机名前加tcp:
来阻止它。所以,我的连接字符串看起来像:
Server=tcp:example.database.windows.net;Database=<dbname>;User Id=...
这可以防止服务器回退以尝试使用命名管道,而我还没有看到这个问题。
不幸的是,我还没有找到在某些情况下使用命名管道提供程序的原因。它应该由microsoft/windowsservercore映像中的某些配置引起,因为我从未在Docker镜像之外看到过错误消息。否则,我会怀疑Azure SQL的限制机制(尽管负载非常低)。