Closed k0st1x closed 1 year ago
Похоже на то, с чем столкнулись мы в #40. Вне контейнера проблема с большим потреблением сохраняется? Какой у вас режим сборщика мусора? Запускали ли профилировщик, какие результаты?
Вне контейнера проблема с большим потреблением сохраняется?
специально не проверял, но интересует сценарий именно в контейнере.
Какой у вас режим сборщика мусора?
Server
Запускали ли профилировщик, какие результаты?
Запускали, по результатам нет интересного, за что можно зацепиться. Хотя память понемногу, но всё время растёт в unmanaged части.
К сожалению, сейчас попали в ситуацию, что криптопро sdk для .net на проде не помогает решать задачу, а является слишком нестабильным.
А что за проблемы с КриптоПро .NET? Мы стараемся пока его поддерживать, но после серьёзных обновлений .NET Framework патчи слетают к сожалению -- нужно дожидаться новой версии от нес -- эти деятели постоянно меняют компилятор. Но на проде же можно не обновлять Framework сразу.
А что за проблемы с КриптоПро .NET?
Используем net6, как и написано в документации.
- Попробуйте заменить режим сборки мусора на WorkStation и понаблюдать
пробовали чистить память GC.Collect в ручном режиме, после запроса на подпись. Не помогло - память накапливается. Т.е. не считаем, что смена стратегии GC сможет помочь.
Произведите профилирование неуправляемого кода с помощью dotnet-dump по инструкции
по инструкции же только про анализ managed части памяти. в unmanaged можно только посмотреть, какое её количество. либо покажите, пожалуйста, что именно вы имеете ввиду. Но я попозже попробую собрать именно dotnet-dump и посмотрю на него повнимательнее.
- Попробуйте заменить режим сборки мусора на WorkStation и понаблюдать
пробовали чистить память GC.Collect в ручном режиме, после запроса на подпись. Не помогло - память накапливается. Т.е. не считаем, что смена стратегии GC сможет помочь.
Произведите профилирование неуправляемого кода с помощью dotnet-dump по инструкции
по инструкции же только про анализ managed части памяти. в unmanaged можно только посмотреть, какое её количество. либо покажите, пожалуйста, что именно вы имеете ввиду. Но я попозже попробую собрать именно dotnet-dump и посмотрю на него повнимательнее.
Действительно, dotnet-dump позволяет получить информацию об управляемой памяти, лучше использовать lldb и sos для анализа. Дамп можно сделать с помощью того же dotnet-dump
Upd: дамп лучше делать не с помощью dotnet-dump (т.к. он не нативный отладчик), а с помощью gcore. Вообще, дамп у вас уже должен быть, т.к. в большинстве дистрибутивов включено автоматическое создание дампа при падении.
Вообще, Workstation GC - это не просто вызвать GC.Collect
Про сравнение 2х дампов памяти (dotnet-dump) это разница 2х дампов - первый: прогретый, вторй: +200 запросов на detached-подписи документов. Видно, что сертификаты прогретые - CertificatePal - висят, не меняются. А вот некий SafeCertContextHandle растёт с количеством запросов - вырос с 638 до 1271.
Так же отмечу, что managed памяти примерно одинаково - 300Mb, а сами дампы - 2Gb и 2.5Gb, т.е. вижу, что unmanaged памяти там съедено много.
Вообще, Workstation GC - это не просто вызвать GC.Collect
Я лишь хотел показать, что пробовал разные сценарии. И чистку LOH тоже применял. Но результат один - контейнеру нехватает памяти и происходит падение. Т.е. вижу, что игры с GC не помогут, тк где-то нативную память надо было почистить, а она растёт.
PS. с gcore разобраться пока не успел. но не уверен, что без криптопро pdb мне это поможет как-то разобраться в native памяти.
ответ по SafeCertContextHandle в #40. Не факт, что вам вообще удастся что-то найти в неуправляемой памяти. Исследование неуправляемой памяти в Linux - довольно непростая задача.
Посмотрел немного CoreFX, SafeHandle
(от которого наследуется SafeCertContextHandle
) имеет деструктор, а значит даже если в самом CoreFX не был вызван Dispose, то GC все равно соберет мусор, но только позже. Поэтому проблема с утечкой в неуправляемой памяти не должна быть связана с этим.
@k0st1x, как проблему в итоге решили?
@Bykiev, отказ от LibCore.Linux nupkg. И ждем релиза версии под net8 в надежде, что там не будет проблемы.
@Bykiev, отказ от LibCore.Linux nupkg. И ждем релиза версии под net8 в надежде, что там не будет проблемы.
А вариант с заданием максимальной памяти в юните с автоперезапуском сервиса не устроил?
@Bykiev, А вариант с заданием максимальной памяти в юните с автоперезапуском сервиса не устроил?
Если это про перезагрузку контейнера при достижении лимита по памяти, то с этим имею плохой опыт - при нагрузке есть вероятность отшибить запрос, который только пришел, но сервису пора перезапускаться. Конечно же, от сервиса работы с криптографией ожидаем максимально стабильной работы без перебоев и mem leak'ов.
нет, сервис ведь запускается systemd?
@Bykiev
нет, сервис ведь запускается systemd?
по инструкции от MS https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/building-net-docker-images?view=aspnetcore-6.0#build-and-deploy-manually
из командной строки обычное
dotnet MyApp.dll
тогда не получится так
@Bykiev, А вариант с заданием максимальной памяти в юните с автоперезапуском сервиса не устроил?
Если это про перезагрузку контейнера при достижении лимита по памяти, то с этим имею плохой опыт - при нагрузке есть вероятность отшибить запрос, который только пришел, но сервису пора перезапускаться. Конечно же, от сервиса работы с криптографией ожидаем максимально стабильной работы без перебоев и mem leak'ов.
Мы тоже делали сервис на net6 для подписания документов. Правда на винде. А вы не пробовали такой финт ушами - вынести подписание в консольное приложение, которое уже и вызывать из сервиса. По идее, при завершении консольки, все ресурсы за ней должны почиститься системой, даже если утечки были. Слишком медленно для вас ?
@Bykiev, А вариант с заданием максимальной памяти в юните с автоперезапуском сервиса не устроил?
Если это про перезагрузку контейнера при достижении лимита по памяти, то с этим имею плохой опыт - при нагрузке есть вероятность отшибить запрос, который только пришел, но сервису пора перезапускаться. Конечно же, от сервиса работы с криптографией ожидаем максимально стабильной работы без перебоев и mem leak'ов.
Мы тоже делали сервис на net6 для подписания документов. Правда на винде. А вы не пробовали такой финт ушами - вынести подписание в консольное приложение, которое уже и вызывать из сервиса. По идее, при завершении консольки, все ресурсы за ней должны почиститься системой, даже если утечки были. Слишком медленно для вас ?
в итоге примерно так и делаем. только не своё приложение, а используем стандартный certmgr. из-за чего имеем неудобнфый код с динамическим обновлением сертификатов в контейнере. и это не отменяет того, что у платного продукта есть критическая проблема в реализации библиотеки.
@k0st1x, а у вас случайно не установлен антивирус?
@k0st1x, а у вас случайно не установлен антивирус?
Софт крутится внутри docker. Внутри докер-образа антивируса нет.
Есть микросервис с КриптоПро под Debinan. Со временем контейнер перезагружается из-за лимита памяти. По MemoryDump видно, что он занимает ~4Gb, причем .net managed памяти там съедено ~300Mb, которые не текут. В коде приложения загружаем сертификат с паролем, он висит всё время в памяти, им только подписываем документ и проверяем отсоединенные подписи присланных документов.
Код, который использует КриптоПро
использую пакет LibCore.Linux.2023.4.25.1.nupkg версия КриптоПро 5.0.12600
Сервис приходится перезагружать раз в несколько дней - это критично для нас. Нужна консультация/идеи, как разобраться с проблемой.