ядро dotnet - сервер зависает на производстве - PullRequest
0 голосов
/ 04 сентября 2018

В настоящее время у нас возникла проблема, когда мы запускаем настройку нашего основного сервера dotnet в Production. Мы публикуем его на Bamboo и запускаем с сервера AWS linux, и он находится за обратным прокси-сервером nginx.

По сути, каждые несколько дней процесс нашего главного сервера dotnet будет отключаться. Он молча принимает и зависает на веб-запросах и даже молча игнорирует наши (более вежливые) попытки остановить его. Мы убедились, что - это на самом деле процесс netcore, который зависает, отправляя запросы curl непосредственно на порт 5000 изнутри сервера. Мы реплицировали наше производственное развертывание в меру наших возможностей в нашей тестовой среде и не смогли воспроизвести этот режим отказа.

Мы контролировали сервер с помощью NewRelic и проверяли его время от времени, когда он переходил в режим отказа. Мы не смогли связать это поведение с каким-либо значительным уровнем трафика, использованием ОЗУ, использованием ЦП или использованием дескриптора открытого файла. Действительно, кажется, что все эти измерения остаются на очень разумных уровнях.

Моя команда и я немного застряли в том, что может вызвать наш зависший сервер, или даже что мы можем сделать для его диагностики. Что может вызывать зависание нашего серверного процесса? Какие дальнейшие шаги мы можем предпринять, чтобы диагностировать проблему?

Дополнительная информация

Наш шаблон nginx conf:

upstream wfe {
  server 127.0.0.1:5000;
  server 127.0.0.1:5001;
}

server {
  listen 80 default_server;
  location / {
    proxy_set_header Host $http_host;
    proxy_pass http://wfe;
    proxy_read_timeout 20s;

    # Attempting a fix suggested by:
    # https://medium.com/@mshanak/soved-dotnet-core-too-many-open-files-in-system-when-using-postgress-with-entity-framework-c6e30eeff6d1
    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection keep-alive;
    proxy_cache_bypass $http_upgrade;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
  }
}

Наши Program.cs:

using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;

namespace MyApplication.Presentation
{
    [ExcludeFromCodeCoverage]
    public class Program
    {
        public static void Main(string[] args)
        {
            IWebHost host = WebHost.CreateDefaultBuilder(args)
#if DEBUG
                                   .UseKestrel(options => options.Listen(IPAddress.Any, 5000))
#endif
                                   .UseStartup<Startup>()
                                   .UseSerilog()
                                   .Build();

            host.Run();
        }
    }
}

В процессе сборки компакт-диска мы публикуем наше приложение для развертывания:

dotnet publish --self-contained -c Release -r linux-x64

Затем мы развертываем папку bin/Release/netcoreapp2.0/linux-x64 на нашем сервере и запускаем publish/<our-executable-name> изнутри.

РЕДАКТИРОВАТЬ: dotnet --version выводит 2.1.4, как на нашей платформе CI, так и на производственном сервере.

Когда начинается сбой, журналы nginx показывают, что ответы сервера на запросы изменяются с 200 на 502, при этом во время сбоя отправляется один 504.

В то же время журналы с нашего сервера просто останавливаются. И там есть предупреждения, но все они явные предупреждения, которые мы поместили в код нашего приложения. Ни один из них не указывает на то, что были сгенерированы какие-либо исключения.

...