我有一个 C# .NET 8 隔离的 Azure 函数应用程序,我正在尝试连接到 SQL 数据库,但在尝试定位问题时遇到了困难。
SqlException: 建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供商:TCP 提供商,错误:26 - 定位指定服务器/实例时出错)
我们有不同的团队,我在开发团队,有网络团队和 SQL 团队。我正在尝试找出问题可能出在哪里。
该函数尝试使用托管身份和直接用户名和密码直接连接 SQL,但没有成功。从 Function App 到 Azure MS SQL 服务器不公开,位于 vnet 和专用终结点后面。它们似乎从网络方面设置正确,因为我可以解析服务器地址和端口。
我已经用简单的代码来测试是否可以打开连接:
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
_logger.LogInformation("Successfully connected to SQL Server.");
}
return new OkObjectResult("Successfully connected to SQL Server.");
}
catch (SqlException ex)
{
var result = JsonConvert.SerializeObject(new
{
Message = $"SqlException: {ex.Message}",
ex.StackTrace,
ex.InnerException,
ex.Source
});
_logger.LogError(ex, ex.Message);
return new ObjectResult(result) { StatusCode = StatusCodes.Status503ServiceUnavailable };
}
catch (Exception ex)
{
var result = JsonConvert.SerializeObject(new
{
Message = $"Exception: {ex.Message}",
ex.StackTrace,
ex.InnerException,
ex.Source
});
_logger.LogError(ex, ex.Message);
return new ObjectResult(result) { StatusCode = StatusCodes.Status503ServiceUnavailable };
}
这个问题是数据库、网络还是代码的问题?
我尝试通过Azure函数应用程序上的Kudu进行tcpping,它可以解析.database.windows.net 1433
我创建了一个新的 Azure MS SQL 服务器和数据库,没有 vnet 和专用端点,也没有权限或类似的东西,但我可以很好地连接到它。
我也尝试过不同的连接字符串。
编辑:
有关该功能的更多背景信息,它使用 Linux 应用程序计划。
我更新了连接字符串以使用 IP 地址而不是服务器名称,最终出现如下错误:
A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)
在进行了更多阅读之后,它向我指出了 TLS/SSL 问题的方向。因此,我将该函数添加到本地 Linux docker 容器中,现在在尝试连接到一台 SQL 服务器时遇到了相同的错误。 但是,当我再次连接到我创建的基本连接时,它就起作用了。我缺少什么 SQL 配置以及为什么它与 Linux 映像有关?
这个问题是数据库、网络还是代码的问题?
您的 Newtwork 设置是问题所在:
与服务器成功建立连接,但在登录前握手期间发生错误。 (提供者:TCP 提供者,错误:35 - 捕获内部异常)
要解决上述错误,请将 Encrypt=false; 项添加到连接字符串中。如下:
Server=tcp:servername.database.windows.net,1433;Initial Catalog=databaseName;Persist Security Info=False;User ID=username;Password={your_password};MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=True;Connection Timeout=30;