Сбой службы Systemd при запросе http - PullRequest
1 голос
/ 19 января 2020

У меня есть. NET Исполняемый файл Core 3.1, скомпилированный как зависящий от фреймворка / переносимый. Я запускаю его на сервере CentOS с установленным. NET Core Runtime. Приложение работает совершенно нормально, когда выполняется в терминале, но когда я выполняю из файла .service с помощью systemd, оно всегда «зависает» при выполнении http-запроса.

Вот код. NET:

//Systemd - Bug hunting
Console.WriteLine("starting download..");
var c = new HttpClient();
var _download = await c.GetStringAsync("https://www.google.com");
Console.WriteLine($"Downloaded {_download.Length} characters.");
//---------------------

Вывод на консоль при запуске в CLI:

starting download..
Downloaded 47466 characters.

Как и ожидалось ..

Однако, если я запускаю это из службы, вывод консоли (из journalctl) выглядит следующим образом:

Jan 18 23:34:13 myvps.local mydaemon[1385]: starting download..
Jan 18 23:34:23 myvps.local systemd[1]: mydaemon.service holdoff time over, 
scheduling restart.
Jan 18 23:34:23 myvps.local systemd[1]: Stopped My Daemon Service.
Jan 18 23:34:23 myvps.local systemd[1]: Started My Daemon Service.

И затем он начинается снова.

Возможно, стоит упомянуть, что это C# код выполняется в отдельном потоке.

Вот файл конфигурации службы (/etc/systemd/system/mydaemon.service):

[Unit]
Description=My Daemon Service

[Service]
WorkingDirectory=/home/myuser/applicationDir
ExecStart=/usr/bin/dotnet /home/myuser/applicationDir/mydaemon.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=mydaemon
User=myuser
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

Из того, что я наблюдал Служба как-то не может отправлять запросы http. Я пробовал это несколько раз, и каждый раз получал один и тот же результат. Приложение do tnet, похоже, не обрабатывает sh, оно скорее «зависает», и затем запускается таймер перезапуска из службы, вызывая перезапуск приложения.

Как мне настроить мой сервис для работы?

Ответы [ 2 ]

0 голосов
/ 19 января 2020

Не видя, что делает код приложения ... если "другой поток", который вы упоминаете, является Задачей (она должна быть, не используйте пустые потоки), вам следует Task.WaitAll для всех остальных потоков / longrunning tasks.

Основной поток не должен выходить, пока не исчезнут все его дочерние элементы.

0 голосов
/ 19 января 2020

Я наконец-то нашел решение.

Проблема заключалась в том, что http-запрос произошел в отдельном потоке, из-за чего systemd подумал, что основной процесс завершился. Я попытался решить эту проблему, добавив Type=forking в файл конфигурации службы, но безрезультатно.

В качестве обходного пути я просто добавил некоторое время l oop в конец основного потока, который записывает некоторую информацию. Таким образом, основной процесс никогда не заканчивается, и, таким образом, systemd не терпит неудачу.

Я знаю, что это на самом деле не лучшее решение, но это единственное, что сработало для меня.

...