Chào bạn,
Ở bài học trước, chúng ta đã cùng nhau tìm hiểu về External Task Pattern - một mẫu kiến trúc nền tảng giúp tách rời (decouple) process engine khỏi logic nghiệp vụ. Bạn đã hiểu rõ mô hình "kéo" (pull), nơi các worker độc lập chủ động lấy công việc từ engine, và những lợi ích to lớn của nó trong kiến trúc microservices.
Trong bài học hôm nay, chúng ta sẽ chuyển từ "tại sao" sang "như thế nào". Đây là bài học thực hành đầu tiên về External Task. Mục tiêu của chúng ta là cấu hình một Service Task để sử dụng 'External' implementation. Bạn sẽ học cách sử dụng Camunda Modeler để chuyển đổi một Service Task, định nghĩa "Topic" cho nó, và hiểu được những thay đổi tương ứng trong file BPMN XML.
Hãy bắt đầu nào!
1. Cấu hình trong Camunda Modeler
Bước đầu tiên để áp dụng External Task Pattern là khai báo nó trong sơ đồ quy trình của bạn. Thao tác này được thực hiện trực quan trong Camunda Modeler.
Chúng ta sẽ tạo một quy trình đơn giản, sau đó cấu hình một Service Task trong đó để nó trở thành một External Task.
Tài liệu hướng dẫn nhanh của Camunda mô tả chính xác các bước này.
Executing automated steps (2/6)
Hãy đọc tài liệu sau để thực hiện các bước cơ bản: tạo một Service Task, và quan trọng nhất là chuyển đổi nó thành một External Task.
Đọc phần "Start with a Simple Process" để biết cách tạo và đặt tên cho các thành phần. Sau đó, đọc kỹ phần "Configure the Service Task". Hãy tập trung vào hai thao tác chính: thay đổi Implementation thành External và đặt tên cho Topic.
Sau khi đọc tài liệu, hãy tóm tắt lại các bước chính:
- Tạo một Service Task: Trong Camunda Modeler, bạn có thể thêm một Task mới và dùng công cụ "cờ-lê" (wrench) để đổi loại của nó thành Service Task.
- Mở Properties Panel: Click vào Service Task đó để bảng thuộc tính (Properties Panel) hiện ra ở bên phải.
- Thay đổi Implementation: Trong tab General, tìm mục Implementation và chọn
Externaltừ danh sách thả xuống. - Định nghĩa Topic: Ngay khi bạn chọn
External, một trường mới tên là Topic sẽ xuất hiện. Đây là nơi bạn định nghĩa một chuỗi định danh duy nhất cho loại công việc này (ví dụ:charge-card,send-welcome-email).
Hình ảnh dưới đây minh họa chính xác vị trí của các thuộc tính này trong Camunda Modeler.

2. "Topic" là gì và tại sao nó quan trọng?
Trong bước cấu hình trên, Topic là khái niệm quan trọng nhất bạn cần nắm vững.
Hãy tưởng tượng Topic như một kênh (channel) trong một hệ thống hàng đợi tin nhắn (message queue) như RabbitMQ hay Kafka.
- Process Engine là người gửi (Publisher): Khi quy trình chạy đến External Task này, engine sẽ "gửi" một công việc vào kênh có tên là
Topicmà bạn đã định nghĩa. - External Worker là người nhận (Subscriber): Một hoặc nhiều worker sẽ "lắng nghe" trên kênh này. Khi có công việc mới, một worker sẽ nhận (fetch) và khóa (lock) nó để xử lý.
Do đó, Topic chính là khóa nối giữa định nghĩa quy trình (BPMN) và mã thực thi logic nghiệp vụ (worker).
Một số lưu ý khi đặt tên Topic:
- Mô tả rõ ràng: Tên Topic nên mô tả hành động mà worker sẽ thực hiện. Ví dụ:
validate-address,generate-invoice-pdf,notify-customer. - Thống nhất quy tắc: Hãy thống nhất một quy tắc đặt tên trong dự án của bạn, ví dụ như dùng
kebab-case(chữ thường, nối bằng dấu gạch ngang) hoặccamelCase. Điều này giúp cho việc quản lý và tìm kiếm dễ dàng hơn.
Hình ảnh sau là một ví dụ khác về một quy trình sử dụng External Task với Topic là compute-total.

3. Bên dưới giao diện: File BPMN XML
Là một developer, bạn sẽ thấy hứng thú khi biết rằng mọi thao tác bạn thực hiện trên giao diện đồ họa của Camunda Modeler đều được thể hiện trong file BPMN XML bên dưới.
Khi bạn đặt Implementation là External và điền Topic, Modeler sẽ thêm các thuộc tính đặc tả của Camunda vào thẻ <serviceTask> trong file XML.
Hãy xem tài liệu sau để thấy đoạn mã XML tương ứng.
Tài liệu này sẽ cho bạn thấy cấu trúc XML của một External Task. Việc hiểu rõ cấu trúc này rất hữu ích cho việc debug và tự động hóa sau này.
Đọc phần có tiêu đề "BPMN" và chú ý vào đoạn mã XML mẫu. Tập trung vào hai thuộc tính: camunda:type và camunda:topic.
Như bạn thấy trong tài liệu, một Service Task được cấu hình là external sẽ có dạng như sau trong file XML:
<serviceTask id="validateAddressTask"
name="Validate Address"
camunda:type="external"
camunda:topic="AddressValidation" />
camunda:type="external": Thuộc tính này báo cho process engine biết rằng đây là một external task.camunda:topic="AddressValidation": Thuộc tính này định nghĩa Topic mà chúng ta đã thảo luận ở trên.
Việc hiểu mối liên kết giữa giao diện và mã XML giúp bạn có một cái nhìn sâu sắc hơn về cách Camunda hoạt động và trao cho bạn khả năng kiểm soát tốt hơn.
4. Điều gì xảy ra khi quy trình thực thi?
Bây giờ, hãy hình dung khi một process instance chạy đến Service Task mà chúng ta vừa cấu hình:
- Process engine đọc định nghĩa của task và thấy
camunda:type="external". - Thay vì cố gắng thực thi một lớp Java nào đó, engine sẽ tạo một bản ghi external task instance trong cơ sở dữ liệu của nó. Bản ghi này chứa thông tin về process instance, task id, và quan trọng nhất là topic (
AddressValidationtrong ví dụ trên). - Quy trình sẽ dừng lại (tạo ra một wait state) tại điểm này. Nó sẽ không đi tiếp cho đến khi nhận được tín hiệu rằng công việc đã được hoàn thành.
- Engine chỉ đơn giản là chờ đợi. Nó đã hoàn thành phần việc của mình. Trách nhiệm bây giờ thuộc về một External Worker nào đó sẽ đến và "nhận việc".
Cơ chế này chính là cốt lõi của sự tách rời (decoupling) mà chúng ta đã nói đến. Engine không cần biết worker nào sẽ xử lý, worker được viết bằng ngôn ngữ gì, hay nó đang chạy ở đâu. Nó chỉ cần biết công việc thuộc về topic nào.
Tổng kết
Trong bài học ngắn nhưng quan trọng này, bạn đã thực hiện bước thực hành đầu tiên với External Task Pattern.
Những điểm chính cần ghi nhớ:
- Để cấu hình một External Task, bạn cần vào Properties Panel của một Service Task, đặt Implementation là
External. - Topic là một định danh quan trọng, hoạt động như một "kênh" để kết nối engine và worker.
- Các thay đổi trên giao diện Modeler sẽ tạo ra các thuộc tính
camunda:typevàcamunda:topictrong file BPMN XML. - Khi thực thi, engine sẽ tạo một task instance và dừng lại, chờ một worker bên ngoài hoàn thành công việc.
Xem trước bài học tiếp theo
Chúng ta đã cấu hình xong một bên của phương trình: process engine đã sẵn sàng để giao việc. Trong bài học tiếp theo, "Implement một External Task Worker bằng Java client để xử lý tác vụ", chúng ta sẽ xây dựng bên còn lại. Bạn sẽ học cách viết một worker bằng Java, sử dụng thư viện của Camunda để kết nối đến engine, lấy các công việc theo topic, và báo cáo lại khi đã hoàn thành. Đó sẽ là lúc bạn thấy toàn bộ chu trình hoạt động một cách hoàn chỉnh.