Привет, Хабр! Меня зовут Александр Бардаш, и я CTO интеграционной платформы MWS Octapi. В одной из предыдущих статей я рассказывал, как мы выбирали движок для low-code и почему остановились на Temporal, отказавшись от Apache Camel. С тех пор регулярно получаю один и тот же вопрос — от продактов, аналитиков, а иногда и от коллег-архитекторов: «Подождите, ну сейчас же есть Karavan, Kaoto, нормальные визуальные редакторы. Аналитик там накидает кубики, настроит логику, разве это не cделает Camel доступнее?» Короткий ответ — нет, не cделает. А вот почему, предлагаю разобрать в материале.

Дисклеймер: это мой личный опыт и опыт команды. Тема спорная, у вас может быть своя картина.

Что такое Apache Camel

Apache Camel — это набор готовых «коробочек» для интеграции систем между собой. Нужно прочитать сообщение из Kafka, разложить по полю, преобразовать формат и отправить в SAP. Camel умеет это делать через свои «коннекторы» и «паттерны». Разработчик описывает интеграционный сценарий маршрутами (routes) примерно так:

from("kafka:orders?brokers=kafka:9092")
    .unmarshal().json(JsonLibrary.Jackson, Order.class)
    .choice()
        .when(simple("${body.amount} > 100000"))
            .to("direct:vip-flow")
        .otherwise()
            .to("jms:queue:standard-orders")
    .end();

Из Kafka-топика orders приходят заказы, мы парсим их как JSON и, если сумма больше ста тысяч, отправляем в одну очередь, а если меньше — в другую. Всё прозрачно и понятно. В основном из-за такой понятности Camel и держится в индустрии больше пятнадцати лет. 

Camel — отличный инструмент, но за его простотой стоят несколько неочевидных проблем. И главная из них в том, что писать такой код всё равно может только инженер.

Главная особенность Camel

Camel выглядит как инструмент для аналитика («350+ компонентов, decade of EIP», «визуальный редактор Karavan»). Но аналитик не сможет работать с Camel самостоятельно. И многие джуниор-разработчики без помощи опытного коллеги застрянут на первой нестандартной задаче.

Разрыв между слайдом и продом
Разрыв между слайдом и продом

Барьер 1. Camel — это не визуальный конструктор

Современная платформа low-code отличается от Camel тем, что в ней можно работать через UI и не нужно писать код.

Camel же — это фреймворк для разработчика, а UI поверх него (Karavan, Kaoto) появился позже и просто генерирует тот же код, который человек написал бы руками. Как только в маршруте появляется нестандартная логика, нужно подключать разработчика.

Рассмотрим реальный пример. Простой Choice (это «если — иначе») c вложенным балансировщиком на Java выглядит так:

from("direct:start")
    .choice()
        .when(body().contains("Camel"))
            .loadBalance().roundRobin().to("mock:foo").to("mock:bar").endChoice()
        .otherwise()
            .to("mock:result");

Видите .endChoice() в конце ветки? Это особенность fluent-API (билдера, которым описывается маршрут): метод возвращает вас на уровень choice, иначе следующий вызов в цепочке привяжется не к тому объекту и код просто не скомпилируется. Маловероятно, что аналитик или продакт, рисующий маршрут в Karavan, догадается, почему его кубик с loadBalance внутри Choice ведёт себя не так, как в схеме.

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

Барьер 2. Чтобы написать что-то осмысленное, нужно знать несколько технологий

Возьмём простую задачу: «Прочитай заказ из Kafka, обогати его данными клиента из REST-сервиса, положи в базу». На Camel это пять-шесть строк кода, но, чтобы написать его корректно, нужно:

  • знать Java (Kotlin DSL Camel сначала пометил как deprecated в 4.7, а в 4.9 удалил совсем — теперь официально поддерживаются только Java, XML и YAML);

  • понимать асинхронность — Camel внутри асинхронный, и многие баги связаны именно с этим;

  • знать выбранный язык выражений — у Camel их сразу несколько: Simple, JSONPath, XPath, OGNL, Groovy, Datasonnet, JQ, — и в реальном проекте я видел сразу три;

  • ориентироваться в Enterprise Integration Patterns — это книга на 700 страниц, и в Camel реализовано больше шестидесяти таких паттернов, каждый со своими граничными случаями;

  • ориентироваться в «коннекторе» — у Camel более 350 готовых компонентов, и Kafka, JMS, HTTP, S3, Salesforce, SAP — у каждого свои настройки, свои подводные камни.

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

Барьер 3. Зоопарк рантаймов и DSL

Найти опытного инженера — это только начало. Дальше нужно ответить на вопрос: на каком именно Camel вы будете жить? Потому что Camel — это семейство. Варианты обвязки, в которой будет жить ваш Camel-сервис:

  • Camel Main — отдельное standalone-приложение;

  • Camel Spring Boot — поверх Spring Boot;

  • Camel Quarkus — поверх Quarkus, подойдёт для cloud-native, поддерживает нативную сборку в бинарник;

  • Camel on Karaf (OSGi) — подойдёт для OSGi-контейнеров, исторически популярный в энтерпрайзе;

  • Camel JBang — лёгкий способ запустить Camel-скрипт без сборки.

Ощущение «ого, сколько всего надо выбрать» испытывает каждый, кто впервые планирует проект на Camel. А ещё в каждом рантайме есть свой набор расширений, особенности конфигурации, обвязка для метрик, тестирования, секретов. 

Команда выбирает один из рантаймов и фактически женится на нём, ведь дальнейший переезд выльется в серьёзный и дорогостоящий проект.

К рантаймам добавляются варианты DSL, на которых можно описывать маршруты:

  • Java DSL — самый мощный, но с минусами, о которых я рассказал выше;

  • XML DSL — исторический, многословный, в новых проектах не используется;

  • YAML DSL — человекочитаемый, на нём как раз работают визуальные редакторы;

  • Spring XML — для Spring-проектов;

  • REST DSL — отдельная разновидность для REST-эндпоинтов;

  • аннотации — @Consume и @Produce.

Есть множество разных точек входа с разными возможностями. Например, на YAML DSL не написать сложный кастомный Processor. Придётся всё равно идти в Java.

«Один Camel» — сложный выбор из разных вариантов
«Один Camel» — сложный выбор из разных вариантов

Решение на старте требует большой работы архитектора. Если ошибиться, через год команда потратит квартал на переезд между рантаймами.

Деплой и эксплуатация — отдельная история

Camel-приложение — это полноценный Java-сервис со всеми вытекающими. Не лямбда-функция или контейнер с готовым воркером, а JVM-приложение, которое надо собирать, паковать, версионировать и разворачивать.

Сборка

Простое Camel-приложение на Spring Boot собирается в jar на 80–150 МБ. Если вы хотите cloud-native (Camel Quarkus с native-сборкой), вам понадобится отдельный билд-агент с минимум 4 GiB памяти, а на реальных проектах с Jackson, Kafka и JDBC обычно нужно от 6 до 8 GiB. Сама нативная сборка займёт несколько минут, что влияет на скорость пайплайна.

Зависимости

Каждый коннектор — это новые Maven-зависимости. В корпоративном контуре обычно нет прямого доступа в Maven Central, нужно настраивать прокси-репозиторий, креды, доверие к TLS. Это всё уже не одна команда из README, а полноценная DevOps-обвязка.

Версионная связка

В Camel вы постоянно балансируете между тремя версиями: ядро Camel, обвязка (Spring Boot или Quarkus) и конкретные коннекторы. На одной LTS-ветке (например, 4.14) одни компоненты доступны, на более свежей (4.18, а тем более 4.20) уже другие. Хотите свежий компонент — обновляйтесь, но сначала проверьте, что обновление не сломает остальные двадцать. И держите в голове ритм релизов: у Camel две LTS в год со сроком поддержки около года, так что не выйдет всё время сидеть на одной версии.

Сам стек тяжёлый

Простое Camel-приложение в режиме Spring Boot потребляет 250–500 МБ RAM в проде. Каждый отдельный Camel-сервис весит примерно как небольшой Java-микросервис. И если вы планируете 30 интеграционных сервисов, считайте сами: это уже 7–15 ГБ оперативки только под интеграции, без учёта самой бизнес-логики. На Camel Quarkus в native-режиме можно ужаться до 70–120 МБ на сервис, но цена — сложная сборка и ограничения на рефлексию (часть Java-библиотек просто не будет работать).

«Camel — это же просто библиотека» — да, но каждый такой сервис по весу как полноценный микросервис
«Camel — это же просто библиотека» — да, но каждый такой сервис по весу как полноценный микросервис

Всё это выглядит нормально для команды, которая привыкла эксплуатировать Java-сервисы, но даже не близко к той картине, в которой аналитик сам нарисует интеграцию.

Наблюдаемость: ещё одна загвоздка для тех, кто не из разработки

Без сквозного трейсинга современный продакшн становится слепой зоной. Когда у вас 30 интеграций и где-то в системе тормозит, вам нужно понимать, в каком конкретно сервисе и на каком шаге, иначе разбор инцидента займёт непозволительно много времени. Хоть Apache Camel и предлагает решения, но и с ними не всё так просто.

В Camel для трейсинга есть несколько компонентов, появлявшихся в разное время и постепенно сменяющих друг друга. На сегодня в экосистеме параллельно живут:

  • camel-tracing — старая абстракция, которая постепенно вытесняется новой;

  • camel-telemetry — новая абстракция;

  • camel-opentracing — устаревшая реализация (OpenTracing-проект архивирован CNCF в 2022-м);

  • camel-opentelemetry и camel-opentelemetry2 — текущие реализации;

  • camel-observation и camel-micrometer-observability — отдельная ветка через Micrometer;

  • camel-observability-services — «зонтик», объединяющий метрики, health-чеки и трейсинг через /observe/* эндпоинты.

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

Выбрать правильную коробку для трейсинга — квест
Выбрать правильную коробку для трейсинга — квест

Чтобы было нагляднее, вот пример «минимального продакшн-конфига» наблюдаемости для одного Camel-сервиса:

# application.properties
camel.opentelemetry.enabled = true
camel.opentelemetry.instrumentationName = order-router
camel.mdc.customHeaders = CAMEL_TRACE_ID,CAMEL_SPAN_ID

camel.observability-services.enabled = true
quarkus.management.enabled = true
quarkus.management.port = 9876

# чтобы в логах появились trace_id и span_id
quarkus.log.console.format = %d{HH:mm:ss.SSS} %-5p [%X{trace_id},%X{span_id}] %c{1} - %m%n

И параметры запуска:

java -javaagent:opentelemetry-javaagent.jar \
     -Dotel.exporter.otlp.endpoint=http://otel-collector:4318 \
     -Dotel.service.name=order-router \
     -jar app.jar

Чтобы в Jaeger появились нормальные сквозные трассировки, нужно много чего знать:

  • какие свойства включить; 

  • как связать идентификатор трассировки в логах с трассировкой в графической системе мониторинга; 

  • как настроить «передачу эстафеты» между сервисами через Kafka — это отдельная боль, потому что в Camel заголовки трассировки между сервисами надо пробрасывать вручную через сообщения, само оно не работает;

  • как правильно стартовать процесс с агентом OpenTelemetry.

Кстати, про MDC, который я упомянул в конфиге: MDC — это технология, которая кладёт ключевые переменные (например, идентификатор запроса) в каждую строку логов. Без неё в логах вы не увидите, какая именно строка относится к какому запросу. Аналогично «контекстная пропагация через Kafka» — просто передача между сервисами идентификатора трассировки в заголовках сообщения, чтобы потом можно было собрать единую картину в Jaeger.

Насчёт Karavan и других визуальных редакторов

Karavan — IDE open source от Apache, специально под Camel. Kaoto — похожий продукт от Red Hat. Оба умеют:

  • визуально рисовать маршруты — drag-and-drop EIP-блоки и компоненты;

  • генерировать YAML-роуты;

  • запускать интеграции локально;

  • собирать и публиковать образы.

И это правда красиво. Я открывал Karavan, и да, действительно, рисовать маршрут в нём приятнее, чем писать YAML руками. Но проблема в том, что Karavan — редактор, а не платформа для аналитика.

Что Karavan не делает:

  • Не убирает требование к Java-знаниям

Любая нестандартная логика, будь то кастомный Processor, нетривиальный Aggregator или обработка ошибок, пишется на Java и подключается к маршруту. UI вам в этом не поможет: для вставки кастомного Java-кода надо знать Java, понимать жизненный цикл Exchange, уметь работать с зависимостями.

  • Не убирает зоопарк рантаймов

Karavan-проект может генерировать код под Camel Quarkus, Spring Boot или Camel Main. Выбор всё равно остаётся за командой со всеми вытекающими — это инженерное решение, а не «выбор шаблона из списка».

  • Не закрывает наблюдаемость

Никуда не делись все боли с трейсингом, MDC, пропагацией через Kafka. Karavan может сгенерировать properties, но за вас он не настроит коллектор и не пробросит пропагацию через Kafka.

  • Не даёт настоящего визуального дебага

В Camunda и подобных BPMN-движках вы видите, на каком шаге процесса застрял конкретный экземпляр, прямо в продовом UI. В Karavan этого нет — отладка всё равно идёт через логи, IDE и camel debug в JBang, то есть инструменты разработчика.

  • Не убирает баги UI

Субъективно, но в обсуждениях репозитория (в релизах ветки 4.14) пользователи жаловались, что некоторые настройки компонентов не сохраняются — приходится чинить YAML вручную. Так что не стоит рассчитывать только на UI.

И самое главное: визуальный редактор в Camel создаёт у заказчика ложное ощущение доступности. Но в реальности любая нестандартная задача всё равно уйдёт в очередь к разработчику.

В каких сценариях Camel подойдёт

В каких случаях Camel подходит идеально:

  • Много простых интеграций, выполняемых командой Java-разработчиков

Если у вас уже есть Java-команда, нужно расфасовывать сообщения по очередям, конвертировать форматы, делать routing по контенту, то Camel поможет сэкономить время. EIP реализованы хорошо, так что для этого класса задач это действительно мощный инструмент.

  • Уникальные коннекторы

350+ готовых компонентов — это огромный плюс. Нужен Salesforce или Bulk API, что-то экзотическое — высокий шанс, что в Camel это уже есть. Писать с нуля было бы сильно дороже.

  • Camel «внутри сервиса», а не «платформа на Camel»

Подключить camel-spring-boot или camel-quarkus как библиотеку в существующий Java-микросервис — отличный способ упростить его интеграционный код. 

И зеркальные сценарии, где я бы Camel не выбирал:

  • единая интеграционная платформа со множеством тенантов и собственным ИИ, рассчитанная на самостоятельную работу аналитиков и продактов — здесь нужен низкий порог входа;

  • команды, где нет сильной Java-экспертизы, но есть аналитики и хочется сократить Time to Market;

  • проекты, где critical path — наблюдаемость, SLA и быстрое расследование инцидентов, а отдельной observability-команды нет.

Заключение

Вся сложность прячется под красивым UI 
Вся сложность прячется под красивым UI 

Camel — это инструмент для Java-разработчика. Он не подходит аналитику, продакт-оунеру или «гражданскому интегратору». Не дайте ввести себя в заблуждение красивой презентацией про low-code с демонстрацией Camel + Karavan. В реальности вам понадобятся два сеньор-инженера, которые знают, что такое endChoice(), и DevOps-команда, которая разворачивает JVM-сервисы и настраивает OpenTelemetry.

В нашей команде мы пошли другим путём — взяли движок без UI, отделили представление маршрутов от их исполнения, чтобы продактам и аналитикам можно было давать понятные нотации, а инженерам — управляемое исполнение. Я писал об этом в предыдущих статьях. Не скажу, что это самый лучший путь — это просто другой набор компромиссов, подходящий в нашем случае.

На этом у меня всё, готов отвечать на вопросы и спорить в комментариях. Спасибо, что прочитали!

Комментарии (1)


  1. azZy28
    16.07.2026 18:08

    В РФ больше половины esb построены на camel. Люди покупают по сути open source решение с красивым UI и потом нанимают отдел разработки на java что бы делать интеграции.