Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Azure函数运行到System.Net.Sockets.SocketException中_C#_Asp.net Core_Azure Functions_Tcpclient_Socketexception - Fatal编程技术网

C# Azure函数运行到System.Net.Sockets.SocketException中

C# Azure函数运行到System.Net.Sockets.SocketException中,c#,asp.net-core,azure-functions,tcpclient,socketexception,C#,Asp.net Core,Azure Functions,Tcpclient,Socketexception,我有一个AzureFunctions应用程序,有两个HTTP触发函数。两者都来自同一个类,但使用不同的URL获取数据。 每天Azure Data Factory管道都会触发第一个HTTP函数 另一条管道在1分钟内调用第二个函数 每个函数向第三方网站发出大约1300个HTTP请求,并将每个响应作为单独的json文件存储在Blob存储中 问题几乎每次(但并非总是)第二个函数抛出System.Net.Sockets.SocketException时都会出现,因为很少有出站请求会运行到常见的21秒TCP

我有一个AzureFunctions应用程序,有两个HTTP触发函数。两者都来自同一个类,但使用不同的URL获取数据。 每天Azure Data Factory管道都会触发第一个HTTP函数 另一条管道在1分钟内调用第二个函数

每个函数向第三方网站发出大约1300个HTTP请求,并将每个响应作为单独的json文件存储在Blob存储中

问题几乎每次(但并非总是)第二个函数抛出System.Net.Sockets.SocketException时都会出现,因为很少有出站请求会运行到常见的21秒TCP超时。 我注意到了一件奇怪的事情——可能是Azure出于某种原因限制了我的出站请求:第一批需要大约300毫秒,下一批需要4.3秒,然后是9.5秒,下一批需要21秒

异常堆栈跟踪:

System.Net.Http.HttpRequestException:连接尝试失败 因为关联方在一段时间后未作出适当回应 时间,或建立的连接失败,因为连接的主机已 未能响应-->System.Net.Sockets.SocketException:A 连接尝试失败,因为连接方未正确连接 一段时间后响应,或建立的连接失败 因为连接的主机无法在响应 System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32端口, CancellationToken CancellationToken)--内部异常结束 堆栈跟踪--at System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32端口, 取消令牌(取消令牌)位于 System.Threading.Tasks.ValueTask
1.get_Result()位于
System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage
请求,取消令牌(取消令牌)位于
System.Threading.Tasks.ValueTask
1.获取结果()位于 System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask
1
creationTask)在System.Threading.Tasks.ValueTask
1.get_Result()
在 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage 请求,布尔值doRequestAuth,CancellationToken CancellationToken)
在System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求,取消令牌(取消令牌)位于 System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage 请求,取消令牌(取消令牌)位于 System.Net.Http.HttpClient.FinishSendAsyncBuffered(任务'1 sendTask, HttpRequestMessage请求,CancellationTokenSource cts,布尔值 处置)在 FunctionApp.BaseFunc.c_uudisplayClass7_2.d.MoveNext() 在里面 E:\vsts-agent-win-1\u work\339\s\Services\Host\Controllers\BaseFunc.cs:line 102 ---来自引发异常的上一个位置的堆栈结束跟踪——在functionpp.BaseFunc.ProcessRun(ILogger 日志,字符串(runId) E:\vsts-agent-win-1\u work\339\s\Services\Host\Controllers\BaseFunc.cs:line 122

FunctionApp托管在AppService plan S1上,因此出站连接没有600个的限制(我相信是这样)

异常期间TCP连接的度量(最大值为498):

来自AzureFunction应用程序“解决问题”助手的TCP连接

异常期间应用程序服务计划的CPU和内存:

应用程序是.Net核心2.2

我没有在我的本地PC上复制它。但是在Azure上,它几乎每天都在每个环境(开发、测试、产品)上发生。 失败后,Azure Data Factory在5分钟内重试,每次都成功

下面是两个函数使用的基类代码:

 public abstract class BaseFunc
{
    protected abstract string BlobFolderName { get; }
    protected TelemetryClient telemetryClient;
    private static HttpClient _httpClient;

    static BaseFunc()
    {
        HttpClientHandler handler = new HttpClientHandler();
        handler.MaxConnectionsPerServer = 300;
        _httpClient = new HttpClient(handler);
    }
    protected async Task ProcessRun(ILogger log, string runId)
    {
        int processedItems = 0;
        try
        {
            Stopwatch sw = Stopwatch.StartNew();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            await Authentication("url", log, runId); //sets default Authorization header

            string getIdeaResult = await _httpClient.GetStringAsync("url");
            JObject jsonObject = JObject.Parse(getIdeaResult);
            int ideaCount = (int)jsonObject.SelectToken("total_count");

            List<Task> tasks = new List<Task>();
            string DataPulledDate = DateTime.Now.ToString("dd-MMM-yyyy");
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse("connection string");
            CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("container");

            string getIdsUri = "url" + $"&limit={batchSize}&offset=";
            int iterations = (int)Math.Ceiling((decimal)ideaCount/batchSize);

            for (int i = 0; i < iterations; i++)
            {
                string result = await _httpClient.GetStringAsync("url" + i * 50);
                JObject jsonIdsObject = JObject.Parse(result);
                int[] ideaIds = jsonIdsObject["content"].Children().Values<int>("id").ToArray();
                foreach (int id in ideaIds)
                {
                    tasks.Add(Task.Run(async () =>
                    {
                        string content = null;
                        using (var response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "url"+ id))) //Exception is thrown on this line
                        {
                            content = await response.Content.ReadAsStringAsync();
                            response.EnsureSuccessStatusCode();
                        }
                        CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference($"{DataPulledDate}/{BlobFolderName}/ideaId-{id}.json");
                        await cloudBlobContainer.CreateIfNotExistsAsync();
                        await cloudBlockBlob.UploadTextAsync(content);
                        Interlocked.Increment(ref processedItems);
                    }));
                }
            }
            await Task.WhenAll(tasks);
            sw.Stop();
        }
        catch (Exception ex)
        {
            log.LogError(ex, "{RunId}: Run failed. {Items} items processed successfully, Exception: {Exception}.", runId, processedItems, ex.ToString());
            throw;
        }
        finally
        {
            if (telemetryClient != null)
            {
                telemetryClient.Flush();
                Thread.Sleep(3000);
            }
        }
    }
}

感谢您的帮助。

我们也遇到了同样的问题,但在我们的案例中,我们有一个代码修补程序,它有一个无限的while循环,创建了数百个对Microsoft GraphApi的请求,而没有响应一个请求,它创建了另一个请求。我们纠正了它,问题解决了!也许这对某人有帮助

您是否为每个连接创建了一个新的
BaseFunc
@谢谢你的回复。没有-在初始问题中添加函数代码您多久创建一次新的GetIdeas?如果是每次“呼叫”一次,那么你就与我发布的链接不符。@Neil我没有实例化GetIdeas。它是Azure函数的入口点。这类似于使用“始终打开”设置运行的WebJob。因此,我们应该始终运行。“Run”由Http调用从外部调用抱歉,我错过了
BaseFunc
构造函数上的
static
namespace FunctionApp
{
    public class GetIdeas : BaseFunc
    {
        public GetIdeas(TelemetryClient telemetryClient)
        {
            this.telemetryClient = telemetryClient;
        }

        protected override string BlobFolderName { get => "folder"; }
        protected override string GetItemUrl { get => "url"; }

        [FunctionName("GetIdeasFn")]
        public async Task Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
        {
            await ProcessRun(log, $"GetIdeasFn - {DateTime.UtcNow.Ticks}");
        }
    }
}