首页 > 解决方案 > 我可以将我的本地 Azure 函数连接到我的 CosmosDB 数据库,但是当我在 Azure 上发布代码时,它无法再连接

问题描述

我开发了一个 blob 触发的函数应用程序,然后使用 Gremlin API 和 Gremlin.Net 驱动程序将数据保存到 CosmosDB 数据库。

我在 Azure 帐户上创建了一个 CosmosDB 数据库,然后在本地运行我的函数时从 local.settings.json 读取连接参数。这工作得很好,我的函数设法将数据存储在 Azure 上托管的数据库中。这是我连接到我的数据库的代码:

        var hostName = Environment.GetEnvironmentVariable($"CosmosDBHostname");

        var portNumber = Int32.Parse(Environment.GetEnvironmentVariable($"CosmosDBPort"));

        var enableSsl = Boolean.Parse(Environment.GetEnvironmentVariable($"CosmosDBEnableSSL"));

        string containerLink = Environment.GetEnvironmentVariable($"CosmosDBContainerLink");

        string password = Environment.GetEnvironmentVariable($"CosmosDBPassword");

        var gremlinServer = new GremlinServer(hostName, portNumber, enableSsl,
            username: containerLink,
            password: password);

        var gremlinClient = new GremlinClient(gremlinServer, new GraphSON2Reader(), new GraphSON2Writer(),
            GremlinClient.GraphSON2MimeType);

然后,我在与我的 Azure 帐户上的数据库相同的 ResourceGroup 上创建了一个函数应用程序,并将我的代码发布到这个函数应用程序,并将我的 local.settings.json 文件的参数复制到我的函数应用程序的 Azure 设置中。但是当我这样做时,我的函数不再能够连接到数据库。

当我的函数运行并尝试连接到数据库时,出现以下异常:

处理文件时出错:Microsoft.WindowsAzure.Storage.StorageException:尝试以访问权限禁止的方式访问套接字---> System.Net.Http.HttpRequestException:尝试访问套接字一种被其访问权限禁止的方式---> System.Net.Sockets.SocketException:试图以一种被其在 System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32) 的访问权限禁止的方式访问套接字端口,CancellationToken cancelToken) --- 内部异常堆栈跟踪结束 --- System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancelToken) at System.Threading.Tasks.ValueTask 1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result()在 System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.get_Result() 在 System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求,CancellationToken cancelToken) 在 System.Net.Http.DiagnosticsHandler 的 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage 请求,布尔 doRequestAuth,CancellationToken cancelToken) System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task 1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) 处的 .SendAsync(HttpRequestMessage request, CancellationToken 1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommandcancelToken) --- Microsoft.WindowsAzure 内部异常堆栈跟踪结束。 Storage.Core.Executor.Executor.ExecuteAsyncInternal[T](RESTCommand 1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.ListBlobsSegmentedAsync(String prefix, Boolean useFlatBlobListing, BlobListingDetails blobListingDetails, Nullable1 maxResults,BlobContinuationToken currentToken,BlobRequestOptions 选项,OperationContext operationContext,CancellationToken cancelToken)

关于为什么我的函数可以使用 local.settings.json 从我的本地开发环境连接到我的数据库,但不能在发布时使用 Azure 设置,是否有任何解释?

标签: c#azure-functionsazure-cosmosdbazure-cosmosdb-gremlinapi

解决方案


根据您提供的堆栈跟踪,错误来自 Azure 存储 ( Microsoft.WindowsAzure.Storage.StorageException),而不是来自 Gremlin 客户端:

Error while processing files: Microsoft.WindowsAzure.Storage.StorageException: An attempt was made to access a socket in a way forbidden by its access permissions 

函数使用 Azure 存储帐户,该帐户也是设置的一部分。在本地,它通常使用存储模拟器。

仔细检查该配置并检查正在使用的存储帐户,以及该存储帐户(如果存在)是否有任何防火墙/VPN 限制。

编辑:堆栈跟踪还显示该问题似乎与文件的访问有关:

Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.ListBlobsSegmentedAsync

这也可能与您打开的连接数有关,如果这种情况偶尔发生或在运行 X 时间后发生(如果您重新启动 Function App,它会暂时工作)。

我看到您的代码正在创建一个 GremlinServer 实例,如果您在每次执行 Function 时都这样做,这可能会导致连接问题。

看:


推荐阅读