Разработка BPMN-процессов через Camunda
Camunda — платформа для оркестрации бизнес-процессов на основе стандарта BPMN 2.0. Подходит для длительных workflow с участием людей (Human Tasks), внешних сервисов и сложной условной логикой. В отличие от очередей сообщений, Camunda даёт визуализацию состояния каждого экземпляра процесса.
Когда нужен Camunda
- Процессы длятся часы/дни/недели (кредитная заявка, онбординг сотрудника)
- В процессе участвуют люди — требуется UI для задач
- Нужен аудит: кто принял какое решение и когда
- Условная маршрутизация по бизнес-правилам
- Компенсации при сбоях (аналог Saga Pattern)
BPMN-диаграмма: обработка кредитной заявки
[Start Event: Заявка получена]
│
[Service Task: Проверить кредитную историю]
│
[Gateway (XOR): Скоринг > 600?]
│ │
Да Нет
│ │
[User Task: [End Event:
Одобрение Отказ]
менеджером]
│
[Gateway (XOR): Решение менеджера?]
│ │
Одобрено Отклонено
│ │
[Service Task: [End Event: Отказ]
Выдать кредит]
│
[End Event: Успех]
Camunda 8 (SaaS) vs Camunda 7 (self-hosted)
| Camunda 8 | Camunda 7 | |
|---|---|---|
| Движок | Zeebe (cloud-native) | Java Process Engine |
| Деплой | SaaS или self-hosted | Self-hosted (Spring Boot) |
| Worker | External Task Workers | Java/External |
| Масштабирование | Горизонтальное | Вертикальное |
| Лицензия | Freemium | Apache 2.0 (community) |
Spring Boot + Camunda 7
<!-- pom.xml -->
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<version>7.20.0</version>
</dependency>
// Деплой BPMN из classpath
@Configuration
public class ProcessEngineConfig {
@Bean
public ProcessEnginePlugin deployProcesses() {
return new ProcessEnginePlugin() {
@Override
public void postInit(ProcessEngineConfigurationImpl config) {
config.setDeploymentResources(new String[] {
"classpath*:processes/*.bpmn"
});
}
};
}
}
Service Task Implementation:
@Component("creditCheckDelegate")
public class CreditCheckDelegate implements JavaDelegate {
@Autowired
private CreditBureauService creditBureauService;
@Override
public void execute(DelegateExecution execution) throws Exception {
String applicantId = (String) execution.getVariable("applicantId");
CreditReport report = creditBureauService.getReport(applicantId);
// Записываем результат в переменные процесса
execution.setVariable("creditScore", report.getScore());
execution.setVariable("creditHistory", report.toJson());
execution.setVariable("scoreApproved", report.getScore() >= 600);
}
}
User Task — задача для менеджера:
@RestController
@RequestMapping("/tasks")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/manager")
public List<TaskDto> getManagerTasks() {
return taskService.createTaskQuery()
.taskCandidateGroup("credit-managers")
.active()
.list()
.stream()
.map(task -> new TaskDto(
task.getId(),
task.getName(),
runtimeService.getVariables(task.getProcessInstanceId())
))
.toList();
}
@PostMapping("/{taskId}/complete")
public void completeTask(@PathVariable String taskId,
@RequestBody TaskDecisionDto decision) {
taskService.complete(taskId, Map.of(
"managerDecision", decision.getDecision(),
"managerComment", decision.getComment(),
"decidedBy", getCurrentUser().getEmail()
));
}
}
Camunda 8 с Zeebe Java Client
@Component
public class CreditCheckWorker {
@JobWorker(type = "credit-check")
public void handleCreditCheck(final JobClient client, final ActivatedJob job) {
var variables = job.getVariablesAsMap();
String applicantId = (String) variables.get("applicantId");
try {
CreditReport report = creditBureauService.getReport(applicantId);
client.newCompleteCommand(job.getKey())
.variables(Map.of(
"creditScore", report.getScore(),
"scoreApproved", report.getScore() >= 600
))
.send()
.join();
} catch (Exception e) {
client.newFailCommand(job.getKey())
.retries(job.getRetries() - 1)
.errorMessage(e.getMessage())
.send()
.join();
}
}
}
DMN — таблицы бизнес-правил
Camunda поддерживает DMN для сложных условий без кода:
| creditScore | loanAmount | employmentYears || decision |
|-------------|------------|-----------------||----------- |
| >= 750 | <= 5000000 | >= 1 || approved |
| >= 700 | <= 2000000 | >= 2 || approved |
| >= 650 | <= 1000000 | >= 3 || manual |
| < 650 | - | - || rejected |
В Service Task вызывается DMN-таблица:
DmnDecisionResult result = decisionService.evaluateDecisionByKey("credit-decision")
.variables(execution.getVariables())
.evaluate();
execution.setVariable("decision", result.getSingleEntry());
Мониторинг через Cockpit
Camunda Cockpit — UI для мониторинга процессов: активные экземпляры, зависшие задачи, инциденты, аудит переменных.
Сроки реализации
- Один BPMN-процесс с 3–5 Service Tasks и 1–2 User Tasks — 2–3 недели
- DMN-таблицы для бизнес-правил — 3–5 дней
- Полная система с несколькими процессами и Cockpit — 1–3 месяца







