Что такое очередь сообщений
RabbitMQ. Часть 3. Разбираемся с Queues и Bindings
Queue (очередь) — структура данных на диске или в оперативной памяти, которая хранит ссылки на сообщения и отдает их копии consumers (потребителям). Queue представляет собой Erlang-процесс с состоянием (где могут кэшироваться и сами сообщения). 1 тысяча очередей может занимать порядка 80Mb.
Binding (привязка) — правило, которое сообщает обменнику в какую из очередей должны попадать сообщения.
Оглавление
Временные очереди
Постоянные очереди
Highly Available очереди
Очереди HA требуют кластерной среды RabbitMQ. В кластерном режиме вся информация об обменниках, очередях, привязках и потребителях будет скопирована на все узлы.
Когда сообщение публикуется в какую-то HA очередь, оно хранится на каждом узле, относящемуся к HA очереди. После того как сообщение потребляется на каком-то из узлов, все копии этого сообщения будут удалены на других узлах.
Очереди HA могут распространяться на все узлы в некотором кластере или только на индивидуальные.
Создание очереди
Пример создания очереди при помощи RabbitMQ.Client:
arguments
Повторный вызов Queue.Declare с аналогичными параметрами вернет полезную информацию об этой очереди. Например, общее число сообщений, находящихся в ожидании в данной очереди, и общее число подписанных на неё потребителей.
Вызов Queue.Declare под учетными данными пользователя, которому не назначены необходимые права закроет канал при помощи команды Channel.Close и клиент получит исключение OperationInterruptedException, которое будет содержать код ошибки 403 и ее описание.
После того, как очередь простаивает в течении >= 10 секунд, она впадает в спящий режим, вызывая GC в очереди, что приводит к значительному сокращению памяти, необходимой для этой очереди.
Создание Queue через графический интерфейс
Создание Binding
Пример создания привязки при помощи RabbitMQ.Client:
Создание Binding через графический интерфейс
В данном разделе опишем очередь и привязку кодом на C#, так если бы нам требовалось разработать библиотеку. Возможно это будет полезно для восприятия.
Очереди сообщений в бэкенд-архитектуре: как построить надежную систему
Очереди сообщений — устоявшаяся технология, которую разработчики применяют уже много лет. Разберемся, как она работает.
Почему понадобились очереди сообщений
Серверные сообщения обычно устроены просто и однотипно: сервер получает запрос, обрабатывает его и сразу же возвращает клиенту. Схема хорошо работает до тех пор, пока обработка запроса занимает немного времени, например доли секунды.
Но бывает, что вернуть ответ клиентскому приложению сразу невозможно. Например, когда сервер обрабатывает видео — это может занять минуты и даже часы. На время обработки большого объема данных вычислительные ресурсы сервера загружены и его способность обрабатывать входящие запросы падает.
Что такое обмен серверными сообщениями и как он устроен
Допустим, серверное приложение получило тяжелый запрос. Оно передает его другим приложениям дальше по цепочке, а само продолжает общение с клиентом.
Для передачи сообщения другим приложениям используют специальный инструмент — очереди сообщений. Эта технология решает любые инфраструктурные вопросы:
Когда в вашем бэкенд-приложении задействованы очереди, обработка видео выглядит так:
Схема асинхронного обмена сообщениями между приложениями. Источник
FIFO и LIFO (ФИФО и ЛИФО) — что это такое
Сервисы обмена сообщениями между серверами делятся на два типа:
Сервисы для организации очередей сообщений
Популярные сервисы для организации очередей сообщений — RabbitMQ, Apache Kafka и Redis. Давайте посмотрим, чем они различаются.
RabbitMQ
Сервер организации очередей сообщений, написанный на языке программирования Erlang. Это распределенный и горизонтально масштабируемый брокер сообщений. Он позволяет разным программам взаимодействовать с помощью протокола AMQP, а через дополнительные модули — и с помощью некоторых других протоколов: MQTT, HTTP и так далее.
RabbitMQ — это инструмент, который силен в маршрутизации сообщений. Система поддерживает несколько видов распределения сообщений в сети, их комбинация позволяет создавать очень хитрые правила доставки сообщений.
Apache Kafka
Apache Kafka — продукт, который реализует систему распределенного журнала событий. Kafka славится своей скоростью работы и масштабируемостью. Из-за способности передавать терабайты данных эту систему очередей сообщений любят разработчики, работающие с Big Data. Например, ее используют в Airbnb, Adidas, Cisco и PayPal.
Redis
Redis создавалась как система хранения данных в оперативной памяти. Изначальное предназначение — ускорение доступа к востребованной информации и построение систем кеширования.
Но разработчики добавили в код возможность построения простых очередей и стеков. В итоге Redis применяют в качестве сервера очередей сообщений в проектах, где нужно быстро и дешево проверить инженерные гипотезы по работе с очередями.
Архитектура сервиса распределённых очередей сообщений в Яндекс.Облаке
Привет, меня зовут Василий Богонатов. Я один из тех, кто приложил руку и голову и вложил свою душу в сервис распределённых персистентных очередей сообщений Yandex Message Queue. Сервис вышел в общий доступ в конце мая, но внутри Яндекса он уже давно и активно используется в разных продуктах.
Сегодня я хочу рассказать читателям Хабра об очередях сообщений вообще и о Yandex Message Queue в частности. Сначала я хочу объяснить, что такое «распределённая персистентная очередь сообщений» и зачем она нужна. Показать её практическую ценность, механику работы с сообщениями, поговорить про API и удобство использования. Во второй половине материала мы посмотрим на техническую сторону: как в наших очередях используется Yandex Database (это надежный фундамент нашего сервиса), как выглядят наивный и улучшенный подход к построению архитектуры, какие проблемы вызывает распределённость и как их можно решить.
Что такое распределённая персистентная очередь сообщений?
Википедия определяет очередь сообщений как «программно-инженерный компонент, используемый для межпроцессного или межпотокового взаимодействия внутри одного процесса». На самом деле, это понятие несколько шире: процессы, взаимодействующие при помощи очереди, могут находиться на разных серверах и даже в разных дата-центрах.
Мы немного уточним термины.
Очередь сообщений – это хранилище, которое обеспечивает размещение и чтение данных в определённом порядке.
С очередью обычно взаимодействуют два типа сущностей:
Основной сценарий для очереди: надёжно и быстро передавать сообщения от писателя к читателю. В отличие от базы данных очередь не предназначена для длительного хранения сообщений. Во многих популярных реализациях существует соответствующий параметр – «Срок хранения сообщений». Он определяет, сколько времени хранится сообщение до момента безвозвратного удаления.
Мы разобрались с понятием очереди, переходим к «распределённости» и «персистентности».
Для чего нужна очередь сообщений
Очередь позволяет отделять логически независимые части сервисов друг от друга, то есть обеспечивает decoupling, который так востребован в популярных сейчас микросервисах. Это повышает масштабируемость и надёжность: всегда можно увеличить поток записи в очередь и добавить больше читателей – обработчиков сообщений, при этом отказ читателей никак не сказывается на работе писателей.
Очереди сглаживают пики нагрузок: они исполняют роль буфера для читателей. Если для мгновенной обработки всех поступающих сообщений текущих мощностей читателей недостаточно, помещённые в очередь сообщения будут обработаны позже, когда нагрузка уменьшится. Буферизация полезна для сервисов с нестабильной нагрузкой, где не нужна моментальная обработка входящих событий.
Давайте посмотрим, как это работает, на примере поискового робота (всё-таки Яндекс начинался с поиска!), который скачивает, обрабатывает и помещает веб-страницы в базу данных. Возьмём вот такую архитектуру.
Очередь сообщений решает здесь следующие проблемы:
Как Yandex Message Queue работает с сообщениями
Здесь можно выделить три основных этапа:
В момент прочтения сообщение скрывается из очереди на период времени, который называется таймаутом видимости (Visibility Timeout), и становится недоступным для других читателей. Если таймаут видимости истекает, сообщение возвращается в очередь и снова становится доступным для обработки. Порядок прочтения сообщений определяется очередью, а не читателем.
Сам читатель и сетевое соединение с ним потенциально ненадёжны. Таймаут видимости необходим, чтобы иметь возможность вернуть в очередь сообщение при аварийном завершении работы читателя или обрыве соединения. В противном случае возникает вероятность, что отдельное сообщение никогда не будет корректно обработано.
После успешного прочтения сообщение передаётся клиенту вместе с идентификатором ReceiptHandle. Идентификатор указывает на конкретные данные, которые должны быть удалены из очереди сообщений.
Типы очередей в Yandex Message Queue
Первый и наиболее часто используемый тип – стандартная очередь (Standard Queue). Она отличается высокой пропускной способностью (тысячи сообщений в секунду), отличной производительностью и малым временем исполнения основных операций. Стандартные очереди состоят из логических шардов и поддерживают практически линейное масштабирование пропускной способности.
Стандартные очереди не поддерживают дедупликацию сообщений при записи в очередь и не гарантируют порядок прочтения. Из-за использования шардинга запрос на чтение может не вернуть ни одного сообщения, даже если они есть в очереди. Чаще всего это случается в режиме short polling, когда чтение идёт из одного случайно выбранного шарда.
Yandex Message Queue API
API – крайне важная составляющая любого продукта. Хороший программный интерфейс должен быть простым и понятным, требовать минимального ознакомления с документацией для эффективного применения. Должен не позволять делать странные или ненужные действия и защищать от глупых ошибок, вовремя сообщая о нарушении «контракта».
Если у системы есть такой API, она быстро получает лояльных пользователей и обрастает удобными «обёртками» для разных платформ и языков программирования.
Amazon Simple Queue Service API (AWS SQS API) – пример такого интерфейса, проверенного временем и огромным количеством клиентов. Поэтому мы решили не изобретать уникальный интерфейс для Yandex Message Queue, а реализовали поддержку AWS SQS API, причём очень тщательно.
В большинстве случаев пользователю SQS достаточно сменить endpoint (адрес сервиса), регион (в данный момент у нас используется только «ru-central1») и получить новые реквизиты доступа (credentials) в пределах Яндекс.Облака. Всё остальное, например, скрипт с использованием командной строки AWS, код с использованием AWS SDK или готовый сервис на Celery или boto, скорее всего, трогать не придётся. Логика и функциональность сервиса очередей останутся прежними.
Подробное описание методов Yandex Message Queue API есть в документации сервиса.
Немного об удобстве
Yandex Message Queue – управляемый (managed) сервис, то есть за работоспособность серверов и программного обеспечения отвечает Яндекс.Облако. Команда сервиса следит за здоровьем очередей, оперативно заменяет вышедшие из строя диски, устраняет разрывы сети и выкатывает обновления. Обновление происходит без остановки сервиса: пока мы устанавливаем новую версию YMQ на одну группу серверов, балансировщик нагрузки старательно перенаправляет трафик на другие. Так что пользователи ничего не замечают.
Чтобы вам было удобнее контролировать работу очередей, мы добавили в YMQ большое количество наглядных графиков, здесь показана только небольшая их часть. Графики находятся в консоли Яндекс.Облака, в разделе «Статистика».
Мы расскажем про четыре самых полезных на наш взгляд графика:
Мы обсудили более-менее общие моменты, теперь перейдём к деталям.
Как в Yandex Message Queue используется Yandex Database
Сервис Yandex Message Queue построен поверх геораспределённой отказоустойчивой базы данных Yandex Database (YDB), которая обеспечивает строгую консистентность и поддержку ACID-транзакций. Мы не будем сейчас разбирать её устройство и характеристики, ограничимся общей схемой.
Очередь в YMQ состоит из логических шардов, представленных неким фиксированным набором таблиц YDB. Каждая таблица хранит свою часть информации. Например, есть таблица общего состояния под названием State, которая хранит offset’ы и реальное количество сообщений. Есть таблица с данными и метаданными сообщений. Есть таблица со связанными атрибутами.
Все основные операции с очередью — работа с сообщениями, изменение атрибутов, создание и удаление — это работа с иерархией таблиц и директорий YDB, либо транзакционные запросы к одной или нескольким таблицам очереди. Данные внутри таблиц очереди – источник абсолютной истины. Поэтому помимо корректной и стабильной работы БД нужно обеспечивать надёжное хранение и высокую доступность данных.
У нас информация хранится в нескольких репликах: по одной копии в каждом из трёх дата-центров Яндекса. В случае недоступности одного из дата-центров количество реплик в оставшихся удваивается. Таким образом восстанавливается требуемый уровень надежности. Даже если выйдет из строя целый дата-центр и одна стойка сервиса в другом, данные будут полностью доступны.
Первый вариант архитектуры Yandex Message Queue
Первый вариант архитектуры YMQ, который мы сами назвали наивным, выглядел вот так.
Схема показывает путь HTTPS-запроса от клиента YMQ до хранилища YDB. Посмотрим на основные компоненты:
Архитектура Yandex Message Queue с мастерами очередей
Нагрузочные стрельбы показали, что первый вариант архитектуры выдерживает около 450 сообщений в секунду на очередь с одним шардом. Это было очень мало.
Основной проблемой стал contention запросов. Большое количество логически конфликтующих транзакций быстро приводило кэши скрытых сообщений в несогласованное состояние. Для решения проблемы мы ввели особую сущность – мастер очередей (queue master).
Мастер очереди – актор, который в обычных условиях существует в кластере в единственном экземпляре и пропускает через себя все запросы, связанные с конкретной очередью. Если запрос к очереди приходит на сервер, где нужный мастер отсутствует, специальный прокси-актор перенаправляет запрос, а затем транслирует обратно полученный от мастера ответ.
При использовании мастера очередей правильный кэш незаблокированных сообщений снижает contention при работе с таблицами. Упрощается реализация ограничения потока запросов, например, через Leaky bucket. Доступны быстрые и точные метрики очереди: количество сообщений, общий трафик и тому подобное. Можно группировать однотипные запросы.
В теории у такой архитектуры есть определенные недостатки, связанные с централизацией:
Батчинг запросов в мастерах очередей
Распределенные транзакции с таблицами базы данных ведут к определенным дополнительным расходам, поэтому идея уменьшить количество запросов казалась нам логичной. Сто транзакций на запись сообщений по одному лучше превратить в одну транзакцию на запись ста сообщений сразу. С мастерами очередей внедрить такую пакетную обработку (батчинг, batching) намного проще.
Батчинг несколько увеличивает задержки (latency) при выполнении операций. Взамен значительно увеличивается пропускная способность. С батчингом одношардовая очередь может обработать до 30 000 запросов в секунду.
Вообще загрузка у очередей бывает очень разной: и тысячи сообщений в секунду, и несколько сообщений в день. Нам нужно было оптимизировать работу с очередями с помощью гибкого алгоритма. Лобовые варианты с накоплением сообщений в буфере до порогового количества или сбросом по таймеру нас не устраивали. Поэтому мы разработали для YMQ алгоритм адаптивного батчинга, который хорошо работает в обоих случаях. Его работа показана в формате временной диаграммы.
Здесь при поступлении нового сообщения возможен один из трёх сценариев:
Что происходит с мастерами при возникновении проблем
В Yandex Message Queue, как и в любой распределённой системе, могут возникать чрезвычайные ситуации. Отказывают серверы, тормозят диски, рвётся сеть внутри и между дата-центрами.
В подобных случаях YDB в течение нескольких секунд автоматически переносит затронутые сбоем таблетки на более подходящие серверы внутри кластера. Мастера очередей YMQ переносятся вместе со своими таблетками.
Не во всех случаях возможно достоверно определить статус сервера по сети, поэтому бывают ситуации, когда новый мастер уже запущен, а старый ещё не прекратил работу.
Для YMQ это не проблема. Запросы в базу не делают предположений о верности кэша видимых сообщений и проверяют каждое из них заново в процессе скрытия. Поэтому существование «лишних» мастеров приводит только к небольшому временному снижению производительности.
Как мы добились отказоустойчивости при создании очереди
В YDB невозможно создать несколько таблиц и модифицировать данные в рамках одной транзакции. Для нас это означало, что очередь, которая физически является набором таблиц, нельзя создать «транзакционно». При гонке в параллельных запросах или при отказах машин можно получить неконсистентное состояние, из которого невозможно выбраться без постороннего вмешательства. Мы подумали и разработали вот такую схему для решения проблемы.
Основная идея такова: для каждого запроса на создание очереди необходимые структуры данных очереди создаются параллельно и независимо. Таким образом создаются версии, которые в конце «коммитятся» в виде строки в специальную таблицу. Выбирается версия-победитель, а все «проигравшие» запросы понимают, какая версия «победила», и возвращают корректную ссылку.
Такой алгоритм в парадигме «всё или ничего» устойчив к отказам по причине независимости создаваемых структур и наличия финальной транзакции с коммитом версии. Если коммит завершился успешно, можно считать, что запрашиваемая очередь создана правильно.
Как в Yandex Message Queue организованы тестирование и мониторинг
Yandex Message Queue – сложный программно-аппаратный комплекс. У него много возможных точек отказа. Мы должны быть уверены в качестве сервиса, который предоставляем. Поэтому мы регулярно его тестируем.
В первую очередь мы отслеживаем:
В заключение
Задача инфраструктурных команд в Яндексе – создавать и поддерживать надёжные, масштабируемые и производительные решения, на основе которых можно быстро и успешно запускать новые продукты, улучшающие жизнь конечных пользователей. Внутри компании наш сервис очередей давно доказал свою полезность и стал частью архитектуры Яндекс.Видео, Яндекс.Маркета, Яндекс.Образования, Яндекс.Такси и других служб.
Теперь он доступен в экосистеме Яндекс.Облака и его можно использовать для построения сервисов внутри и вне самого Облака. Сейчас новые пользователи при регистрации получают денежный грант на ознакомление, так что попробовать Yandex Message Queue можно бесплатно.
Не терять клиентов и быстро обрабатывать запросы: зачем очереди сообщений ритейлу, хостингам, онлайн-школам и банкам
Представьте, что вы приходите в магазин, набираете тележку продуктов, подходите к кассе — а кассир занят. И вы просто бросаете тележку и уходите. Так работают некоторые IT-системы: сервер сломался, перегружен, не отвечает — и запросы от клиентов и других серверов к нему не доходят. Или доходят, но не туда, куда нужно, и не в то время. В итоге можно потерять клиентов, данные и деньги. Решить эту проблему помогут сервисы очередей сообщений — с ними запросы будут вставать в очередь, как покупатели в магазине.
Расскажем, как работают очереди сообщений и для решения каких проблем используют такие инструменты.
Для описания нюансов работы очередей в статье мы поговорили с Mons Anderson, архитектором Mail.ru Cloud Solutions, по следам его выступления на митапе HighLoad.
Запросы покупателей или клиентов любых онлайн-сервисов обрабатываются на серверах, где этот сервис размещен. Эти запросы должны как можно быстрее дойти до сервера и обратно, чтобы клиент получил тот ответ, который ожидает: «Оплата прошла», «Заказ оформлен» или что-то еще.
Очереди сообщений хранят у себя запросы, чтобы они не потерялись, и передают их серверам постепенно. Например, клиент оформляет заказ в интернет-магазине, и заказ уходит не сразу на сервер, а в очередь. Если сервер откажет, очередь сохранит заказ и отправит его позже, ничего не потеряется.
Теперь посмотрим на примерах, кому и в каких случаях пригодятся очереди сообщений и как они помогут оптимизировать расходы на IT-инфраструктуру.
Ситуация. Нагрузка на серверы колеблется: в одни часы или дни она выше, в другие ниже.
Что происходит без очередей. В моменты повышенной нагрузки серверы не справляются. И вместо того чтобы поставить излишек запросов в ожидание, они выдают клиентам отказы: пишут что-то вроде «Невозможно обработать заказ» или совсем отключают нужные функции.
Чтобы этого избежать, можно заранее докупить мощности про запас. Но часто это избыточно: в будущем ресурсы могут не понадобиться, а запросы вполне можно обработать на текущих мощностях, но позже.
Как помогут очереди. Все запросы от клиентов не идут напрямую на сервер, а кладутся в очередь. И очередь отправляет клиенту ответ, например: «Заказ принят». Сервер же берет из очереди запросы по мере того, как освобождается. В итоге обработка займет чуть больше времени, но клиент сразу видит, что его действие выполнено, ни один запрос не пропадает, а сайт и все формы работают без падений и ошибок.
Если ваши серверы находятся в облаке, к ним можно докупить дополнительные мощности временно, на период повышенной нагрузки. Это поможет избежать сбоев, но повысит расходы. С очередями можно ничего не докупать и не подключать, а обойтись обычными мощностями.
Учтите : очереди не помогут, если на запрос нужно выдавать мгновенный ответ. Например, если пользователь ждет, что калькулятор посчитает ему стоимость заказа. Или что заказ сразу уйдет в оплату.
Ситуация. В компании может быть много разных серверов: слабее и мощнее, более старые и более новые, уже загруженные работой и практически свободные. Например:
Что происходит без очередей. Запросы просто идут к любому свободному серверу, не учитывая его загруженность и способность выполнить задачу. В случае неравномерного распределения запросов какой-то сервер может простаивать, а какой-то — работать на последнем издыхании и решать задачи гораздо медленнее допустимого.
А может случиться так, что какой-то сервер рухнет или уйдет в перезагрузку. Если при этом на него пойдет запрос, он просто потеряется.
Как помогут очереди. Запросы можно не отправлять напрямую серверам, а класть в очередь. А сервер, когда освободится от прошлой задачи, сам «придет» к очереди и заберет оттуда новый запрос. В итоге тот сервер, что слабее, будет просто обращаться к очереди реже и работать в комфортном темпе. А более мощный — быстрее справляться с задачами и брать новые запросы чаще.
Отключившийся или сломавшийся сервер задачу вообще не получит — он просто не сможет обратиться к очереди, пока снова не начнет работать. В итоге ни один запрос не пропадет.
Ситуация. В работе IT-системы может быть много дополнительных задач: отправка электронной почты, обработка изображений, формирование отчетов, конвертация файлов в другие форматы. Все эти задачи не требуют мгновенного выполнения, а пользователь готов подождать, если уведомить его, что запрос принят и все в порядке.
Что происходит без очередей. Несрочные задачи уходят на выполнение на сервере сразу. И в итоге могут помешать сделать что-то важное и срочное, например отработать заявку клиента.
Как помогут очереди. Все фоновые запросы не идут на сервер сразу, а кладутся в очередь. Когда сервер освобождается от нагрузки, он сам забирает из очереди то, что может сделать.
В итоге это очень выгодно: в моменты, когда нет срочных запросов, сервер не простаивает, а выполняет несрочные. Он равномерно нагружен и полностью отрабатывает потраченные на него деньги. И тормозов в моменты высокой нагрузки тоже нет, так как на несрочные запросы ресурсы просто не тратятся.
Ситуация. Серверы компании могут быть сильно распределены по географии. Например, если головной офис в Москве, а филиалы в Новосибирске и Владивостоке. И между этими серверами нужно обмениваться сообщениями — например, отправлять данные от клиентов из региональной базы в общую.
Что происходит без очередей. Из-за удаленности всегда есть риск, что сообщение не дойдет: канал связи оборвется, передача будет идти слишком долго, что-то пойдет не так. В итоге можно потерять важные данные. Или сохранить их на региональном сервере, но не обновить на главном.
Иногда этот вопрос решают без очередей. Например, добавляют дополнительную проверку передачи. Но это создает серьезную нагрузку на серверы, так как сообщения становятся тяжелее, а их обработка занимает больше времени.
Как помогут очереди. На все серверы, участвующие в обмене сообщениями, устанавливаются системы очередей. Когда один сервер хочет что-то отправить, то не шлет запрос другому серверу, а кладет его в свою личную очередь. И после этого считает, что запрос отправлен. И уже очередь «стучится» к другому серверу и отправляет сообщение до тех пор, пока отправка не увенчается успехом.
В итоге мощности сервера не заняты постоянными отправками и проверками — он работает в нормальном режиме, считая, что уже отправил сообщение. А персональная очередь будет держать у себя сообщение до успешной отправки и точно ничего не потеряет.
Ситуация. Бывает, что пользователям или клиентам нужно рассылать уведомления. Например:
Что происходит без очередей. Уведомление по умолчанию уходит сразу после формирования. Но это не всегда удобно: иногда формирование может произойти ночью или в нерабочее время. В итоге есть риск, что пользователь пропустит уведомление либо оно вызовет у него раздражение.
Как помогут очереди. После формирования на сервере сообщение никуда не уходит, а кладется в очередь. И ждет там, пока пользователь выйдет в онлайн, у него наступит утро или начнется рабочее время.
Например, так делает социальная сеть «Одноклассники». В 00:00 нового дня они собирают базу всех, у кого сегодня день рождения. Потом отбирают список лучших друзей и ставят уведомление о дне рождения в очередь. Но отправляют его только в тот момент, когда у человека зафиксирована максимальная активность в профиле — чтобы он точно ничего не пропустил и при этом не отвлекался на уведомление в другое время.