Статьи

Идеи настройки производительности для Apache Camel

Время от времени у меня возникают вопросы по поводу оптимизации приложений Camel с аргументом, что Camel работает медленно. Верблюд — это просто клей, соединяющий разрозненные системы, механизм маршрутизации находится в памяти и не требует постоянного состояния. Таким образом, в 99% случаев проблемы с производительностью связаны с узкими местами в других системах или с разработкой приложения без учета производительности. Если дело обстоит именно так, мало чего можно достичь, настроив Camel дальше, и вам придется вернуться к чертежной доске.

BoI5lo8IgAAOFHd
Но иногда, возможно, стоит выжать еще несколько миллисекунд из ваших верблюжьих маршрутов. Настройка каждого приложения очень специфична и зависит от технологии и варианта использования. Вот несколько идей по настройке систем на базе Camel, которые могут подойти вам (или нет).

Настройка конечной точки

Конечные точки в Camel являются точками интеграции с другими системами, и способ их настройки будет иметь огромное влияние на производительность системы. Понимание того, как работают различные конечные точки и их настройка, должно быть одним из первых мест, с которого нужно начинать. Вот несколько примеров:

  • Обмен сообщениями — если ваше приложение Camel использует обмен сообщениями, общая производительность будет сильно зависеть от производительности системы обмена сообщениями. Здесь слишком много факторов для рассмотрения, но основные из них:
    • Посредник сообщений — скорость сети и диска в сочетании с топологией посредника будут определять производительность посредника. Чтобы дать вам представление, с ActiveMQ постоянное хранилище на основе реляционной базы данных будет выполнять около 50% хранилища на основе файлов, а использование сети брокеров для горизонтального масштабирования будет стоить еще 30% производительности. Удивительно, как одно изменение конфигурации в ActiveMQ может оказать огромное влияние на систему обмена сообщениями и затем на приложение Camel. Необходимо прочитать руководство по настройке ActiveMQ от Red Hat с большим количеством деталей, чтобы рассмотреть и оценить. Также реальный пример от Chrisitan Posta, показывающий, как ускорить брокера в 25 раз в некоторых случаях.
    • Клиент сообщений — если производительность является приоритетом, есть также некоторые хаки, которые вы можете сделать на стороне клиента ActiveMQ, такие как: увеличение TCP socketBufferSize и ioBufferSize, настройка параметров протокола OpenWire, использование сжатия сообщений, пакетные подтверждения с optimizeAcknowledge, асинхронной отправкой с useAsyncSend, настройкой предопределенного предела и т. д. Здесь снова есть несколько хороших слайдов от Кристины и старое, но все еще очень актуальное видео от Роба Дэвиса о настройке ActiveMQ. Все эти ресурсы должны дать вам достаточно идей для экспериментов и повышения производительности с точки зрения обмена сообщениями.
  • База данных пишет — используйте пакетирование, когда это возможно. Вы можете использовать агрегатор для сбора нескольких записей перед выполнением пакетной операции для взаимодействия с базой данных (например, с компонентом SQL).
    1
    2
    3
    4
    5
    6
    7
    return new RouteBuilder() {
      public void configure() throws Exception {
        from("direct:start")
          .aggregate(header("PROD_TYPE"), new SQLStrategy()).completionSize(100).completionTimeout(1000)
          .to("sql:insert into products (price, description) values (#, #)?batch=true");
      }
    };
  • Работа с шаблонами — если вам необходимо использовать компонент шаблона как часть маршрутизации, попробуйте использовать существующие движки шаблонов (FreeMarker, Velocity, SpringTeplate, Mustache, Chunk) с небольшим тестом в качестве следующего и определите, какой из них работает лучше. Кристиан Мюллер предлагает отличную презентацию под названием « Оптимизация производительности для Camel » с исходным кодом, подтверждающим результаты. Из этих измерений мы видим, что FreeMarker работает лучше, чем Velocity и SprintTemplates в целом.
  • Использование веб-сервисов — всякий раз, когда вам нужно использовать веб-конечную точку, сам веб-контейнер (должен настраиваться отдельно). С точки зрения конечной точки Camel, вы можете дополнительно немного оптимизировать, пропуская демаршаллинг, если вам не нужны объекты Java и используя асинхронную обработку.
  • concurrentConsumers — существует ряд компонентов (Seda, VM, JMS, RabbitMQ, Disruptor, AWS-SQS и т. д.), которые поддерживают параллельное потребление. Прежде чем использовать конечную точку, проверьте документацию по компоненту для возможностей пула потоков или пакетной обработки. Чтобы дать вам представление, посмотрите, как можно улучшить обработку Amzon SQS с помощью этих опций.

Выбор типа данных

Тип и формат данных, которые проходят через маршруты Camel, также будут влиять на производительность. Чтобы продемонстрировать это, давайте рассмотрим несколько примеров.

  • Контент-маршрутизатор, сплиттер, фильтр — примеры EIP, которые выполняют некоторую работу на основе содержимого сообщения. И тип сообщения влияет на скорость обработки этих элементов. Ниже приведена диаграмма из презентации Кристиана Мюллера, демонстрирующая, как Маршрутизатор на основе контента работает с различными типами сообщений:
    Контентная маршрутизация на основе разных типов данных

    Контентная маршрутизация на основе разных типов данных

    Например, если у вас есть большой XML-документ в Exchange, и на его основе вы выполняете маршрутизацию на основе содержимого, фильтрацию и т. Д., Что будет влиять на скорость маршрута. Вместо этого вы можете извлечь некоторую ключевую информацию из документа и заполнить заголовки Exchange для более быстрого доступа и маршрутизации позже.

  • Маршалинг / демаршалинг — по аналогии с шаблонизаторами разные covenrtors формата данных работают по-разному. Чтобы увидеть некоторые метрики, проверьте еще раз презентацию Кристиана, но также имейте в виду, что производительность поддерживаемых форматов данных может различаться в зависимости от версии и платформы, поэтому измерьте ее в своем случае.
  • Потоковая передача — потоковая передача и верблюдное кэширование — одна из недооцененных функций, которая может быть полезна для работы с большими сообщениями.
  • EIP проверки заявок — если логика приложения это позволяет, рассмотрите возможность использования шаблона проверки заявок для повышения производительности и сокращения потребления ресурсов.

Многопоточность

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

  • Параллельная обработка EIP — следующие реализации Camel EIP поддерживают параллельную обработку — многоадресная передача, список получателей, сплиттер, задержка, прослушивание, дросселирование, обработчик ошибок. Если вы собираетесь включить параллельную обработку для них, было бы еще лучше, если бы вы также предоставили пользовательский пул потоков, специально настроенный для вашего варианта использования, а не полагаясь на профиль пула потоков Camel по умолчанию.
  • Построение потоков DSL — некоторые конечные точки Camel (такие как потребитель File) являются однопоточными по конструкции и не могут быть распараллелены на уровне конечных точек. В случае потребителя файла один поток выбирает файл за раз и обрабатывает его по маршруту, пока не достигнет конца маршрута, а затем поток потребителя выберет следующий файл. Это когда конструкция Camel Threads может быть полезна. Как показано ниже, поток потребителя файла может выбрать файл и передать его потоку из конструкции Threads для дальнейшей обработки. Затем потребитель файлов может выбрать другой файл, не дожидаясь полной обработки предыдущей версией Exchange.
    Параллельное использование файлов

    Параллельное использование файлов

  • Компонент Seda — Seda — еще один способ достижения параллелизма в Camel. Компонент Seda имеет список в памяти для накопления входящих сообщений от производителя и concurrentConsumers для обработки этого входящего запроса параллельно несколькими потоками.
  • Асинхронная повторная доставка / повторная попытка — если вы используете обработчик ошибок с политикой повторной доставки в качестве части процесса маршрутизации, вы можете настроить его как асинхронный и выполнять доставку в отдельном потоке. Это будет использовать отдельный пул потоков для повторной доставки, чтобы не блокировать основной поток обработки запросов во время ожидания. Если вам требуются длительные задержки доставки, возможно, лучше использовать повторную доставку посредника ActiveMQ (отличающуюся от повторной доставки потребителя BTW), когда повторные доставки будут сохраняться в посреднике сообщений и не сохраняться в памяти приложения Camel. Еще одним преимуществом этого механизма является то, что повторные поставки будут действовать после перезапуска приложения, а также будут хорошо работать при кластеризации приложения. Я описал различные шаблоны повторов в книге « Шаблоны верблюжьего дизайна» .

Другие Оптимизации

Есть несколько других трюков, которые вы можете сделать, чтобы еще больше подстроить Camel.

  • Регистрация конфигураций — надеюсь, вам не нужно регистрировать каждое сообщение и его содержимое в производственной среде. Но если вам нужно, подумайте об использовании некоторого асинхронного регистратора. В системе с высокой пропускной способностью любой вариант может заключаться в регистрации статистики и агрегированных показателей через регистратор Camel Throughput. Регистратор пропускной способности позволяет регистрировать агрегированную статистику с фиксированными интервалами или по количеству обработанных сообщений, а не по базам сообщений. Другой вариант — использовать не очень популярный EIP Camel Sampler и время от времени регистрировать только образцы сообщений.
  • Отключить JMX — по умолчанию включена инструментарий Camel JMX, который создает много MBean-компонентов. Это позволяет осуществлять мониторинг и управление средой выполнения Camel, но также имеет некоторое снижение производительности и требует больше ресурсов. Я до сих пор помню время, когда мне пришлось полностью отключить JMX в Camel, чтобы запустить его с кучей 512 МБ на бесплатной учетной записи AWS. Как минимум, подумайте, нужен ли вам вообще какой-либо JMX, и если да, то использовать ли профили RoutesOnly, Default или Extended JMX.
  • История сообщений — Camel реализует EIP Истории сообщений и запускает его по умолчанию. Находясь в среде разработки, может быть полезно увидеть каждую конечную точку, к которой было отправлено сообщение, но в рабочей среде вы можете отключить эту функцию.
  • Исходное сообщение. Каждый маршрут Camel создает копию исходного входящего сообщения перед любыми изменениями в нем. Эта первичная копия сообщения сохраняется на тот случай, если ее необходимо доставить во время обработки ошибок или с помощью конструкции onCompletion. Если вы не используете эти функции, вы можете отключить создание и сохранение исходного состояния каждого входящего сообщения.
  • Другие настройки — Почти каждая функция в CamelContext может быть настроена. Например, вы можете использовать lazyLoadTypeConverters для более быстрого запуска приложения или настроить shutdownStrategy для более быстрого завершения работы при наличии сообщений в полете, или использовать пользовательский UuidGenerator, который работает быстрее и т. Д.

Дизайн приложения

Все предыдущие настройки являются микрооптимизациями по сравнению с дизайном приложений и архитектурой. Если ваше приложение не предназначено для масштабируемости и производительности, рано или поздно малые хаки настройки достигнут своего предела. Скорее всего, то, что вы делаете, было сделано ранее, и вместо того, чтобы заново изобретать колесо или придумывать какие-то умные замыслы, учитесь на опыте других и используйте хорошо известные шаблоны, принципы и практики. Используйте принципы SOA, архитектуры микросервисов, принципы отказоустойчивости, передовые методы обмена сообщениями и т. Д. Некоторые из этих шаблонов, такие как параллельные конвейеры, CQRS, выравнивание нагрузки, автоматический выключатель, описаны в книге «Шаблоны проектирования Camel» и помогают улучшить общий дизайн приложения.

JVM

Есть много статей о настройке JVM. Здесь я только хочу упомянуть приложение генерации конфигурации JVM от Red Hat. Вы можете использовать его, если у вас есть учетная запись Red Hat (в любом случае, она бесплатна для разработчиков).

Операционные системы

Вы можете сжать приложение только так сильно. Для правильной обработки при высокой нагрузке также необходима настройка хост-системы. Чтобы получить представление о различных параметрах уровня ОС, взгляните на следующий контрольный список из проекта Jetty.

В заключении

Эта статья здесь только для того, чтобы дать вам некоторые идеи и показать возможные области, которые необходимо учитывать, когда вам нужно улучшить производительность приложения Camel. Вместо того, чтобы искать магический рецепт или пройти контрольный список, делайте небольшие постепенные изменения, поддерживаемые измерениями, пока не достигнете желаемого состояния. И вместо того, чтобы сосредоточиться на микрооптимизациях и хакерских атаках, имейте целостное представление о системе, сделайте правильный дизайн и начните настройку с хост-системы на JVM, CamelContext, элементы маршрутизации, конечные точки и сами данные.

Использование хорошо известных шаблонов, принципов и практик с упором на простой и масштабируемый дизайн — это хорошее начало. Удачи.