Почему постоянно срабатывает OOM при работе бота на сервере?
У меня написан бот на Aiogram 3. Подключена БД Postgresql. Ранее хостился на NAT Cloud сервере и пол месяца ничего не вылетало, теперь перешел на VDS с теми же 512мб оперативы и стал килится бот Out of memory killer’ом. В логах так. Если смотреть по процессам, то больше всего жрет постгрес, хотя раньше на клауде такого не было, в коде ничего не менял, сервер настраивал также, без изменений. Не понимаю, в чем может быть проблема. Грешу на свой пока маленький опыт, так как это единственное, что я хостил с момента начала обучения. Просто смущает тот факт, что на NAT Cloud бот работал исправно.
Вот код мейна, мб у меня есть утечки памяти?
import asyncio import asyncpg import logging from aiogram import Bot, Dispatcher from aiogram.enums import ParseMode from handlers import basic, callback from middlewares.db_middleware import DbSession from data.config import bot_token, pguser, pgpassword, database, host, port async def create_pool(): return await asyncpg.create_pool(user=pguser, password=pgpassword, database=database, host=host, port=port, command_timeout=60) async def main(): logging.basicConfig(level=logging.INFO, format='%(asctime)s - [%(levelname)s] - ' '(%(filename)s).%(funcName)s(%(lineno)d) - %(message)s') bot = Bot(token=bot_token, parse_mode=ParseMode.HTML) pool_connect = await create_pool() dp = Dispatcher() dp.include_routers(basic.router, callback.router) dp.message.middleware.register(DbSession(pool_connect)) try: await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot) finally: await bot.session.close() if __name__ == '__main__': try: asyncio.run(main()) except KeyboardInterrupt: print('Exit') |
import asyncio import asyncpg import logging from aiogram import Bot, Dispatcher from aiogram.enums import ParseMode from handlers import basic, callback from middlewares.db_middleware import DbSession from data.config import bot_token, pguser, pgpassword, database, host, port async def create_pool(): return await asyncpg.create_pool(user=pguser, password=pgpassword, database=database, host=host, port=port, command_timeout=60) async def main(): logging.basicConfig(level=logging.INFO, format='%(asctime)s - [%(levelname)s] - ' '(%(filename)s).%(funcName)s(%(lineno)d) - %(message)s') bot = Bot(token=bot_token, parse_mode=ParseMode.HTML) pool_connect = await create_pool() dp = Dispatcher() dp.include_routers(basic.router, callback.router) dp.message.middleware.register(DbSession(pool_connect)) try: await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot) finally: await bot.session.close() if __name__ == '__main__': try: asyncio.run(main()) except KeyboardInterrupt: print('Exit')
Пробовал await pool_connect.close() прописывать в finally. Ничего не изменилось((
Если нужны другие куски кода, пишите отправлю. Буду очень благодарен за помощь!
Дополнительно:
Бот килится то сразу, то в течении суток. Забыл об этом сказать в вопросе.
Потому что когда на сервере работает несколько сервисов, им нужно явно указывать, сколько памяти они максимально могут потреблять - и в сумме должно получаться меньше, чем есть на сервере (минус сколько-нибудь под процессы ОС). Для Постгреса и вовсе - первая операция после установки, это редактирование настроек памяти.
Альтернатива ковыряния конфигов - разнесение всего хозяйства по контейнерам с лимитами памяти.
- shared_buffers = 128MB # min 128kB
У меня в конфиге так, или это не та инфа? - Maksim Ivanov, там не один параметр. В целом есть калькуляторы, например.
- для микросервера на 512мб ram, ещё и совмещённого с приложением (непонятно сколько памяти потребляющим) дефолтных 128мб shared_buffers явно слишком много. Рекомендация выдавать под shared_buffers 25% ram - это про выделенные сервера именно под базу и при хотя бы 8гб ram.
- ky0, Использовал сервис для генерации конфига, надеюсь поможет. Спасибо!
- Melkij, так 128мб это и есть 25% от 512. Или нужно еще меньше в моем случае?
- Maksim Ivanov, прочитайте остальную часть комментария. 25% ram это точно не про ваш случай
- Maksim Ivanov, если бот будет жрать память то ограничение памяти не поможет. просто будет чаще его килять.
разбираться с ботом
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Проблема OOM (Out of Memory) может возникать по нескольким причинам при работе бота на сервере. Вот некоторые из наиболее распространенных причин и способы их решения:
1. Утечка памяти: Бот может иметь утечки памяти, когда объекты создаются, но не удаляются из памяти после использования. Это может привести к тому, что память исчерпывается и возникает ошибка OOM. Чтобы исправить это, убедитесь, что вы правильно удаляете объекты после использования и используете механизмы управления памятью, такие как сборка мусора.
2. Недостаточное выделение памяти: Ваш бот может требовать больше памяти, чем ему было выделено на сервере. Увеличьте объем выделенной памяти для вашего бота, чтобы избежать ошибки OOM. Вы также можете оптимизировать свой код, чтобы потреблять меньше памяти.
3. Неправильная конфигурация сервера: Проверьте конфигурацию вашего сервера, возможно, она не соответствует требованиям вашего бота. Убедитесь, что ваш сервер имеет достаточное количество оперативной памяти и процессорных ресурсов для работы бота.
4. Длительная работа бота: Если ваш бот выполняет длительные операции или обрабатывает большие объемы данных, это также может привести к ошибке OOM. Разбейте операции на более мелкие части, используйте кэширование результатов и оптимизируйте запросы к базе данных.
5. Неэффективное использование ресурсов: Проверьте свой код на наличие узких мест и оптимизируйте его. Избегайте лишних запросов к базе данных, уменьшайте количество циклов и повторных вычислений.
Используйте вышеперечисленные рекомендации, чтобы устранить проблему с ошибкой OOM при работе вашего бота на сервере. Если проблема сохраняется, обратитесь к специалистам по серверной оптимизации или хостингу для дополнительной помощи.