Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 56

Quản lý sự cố với Cockpit

Recommended resources

Chào bạn,

Ở bài học trước, chúng ta đã học cách di chuyển một process instance đang chạy sang một phiên bản quy trình mới hơn. Đây là một kỹ thuật cực kỳ mạnh mẽ để sửa lỗi hoặc cập nhật logic cho các quy trình đang hoạt động. Tuy nhiên, điều này đặt ra một câu hỏi: làm thế nào chúng ta phát hiện ra những lỗi đó ngay từ đầu?

Khi một quy trình gặp sự cố mà nó không thể tự phục hồi — ví dụ như một Service Task cố gắng gọi một API không tồn tại, hoặc một đoạn mã Java ném ra một ngoại lệ — Camunda sẽ không để quy trình đó "chết" trong im lặng. Thay vào đó, nó sẽ tạo ra một Incident (sự cố).

Trong bài học hôm nay, chúng ta sẽ tập trung vào vai trò của người vận hành và developer trong việc quản lý các sự cố này. Mục tiêu của bạn là sử dụng Cockpit để theo dõi, phân tích và xử lý các sự cố (incidents). Chúng ta sẽ tìm hiểu cách sự cố được tạo ra, cách sử dụng Cockpit để tìm ra nguyên nhân gốc rễ, và các phương pháp để khắc phục chúng.


1. Incident là gì và nó được tạo ra như thế nào?

Trong Camunda, một Incident đại diện cho một công việc thất bại (failed job) mà engine không thể tự động giải quyết. Thông thường, đây là các lỗi kỹ thuật.

Khi một tác vụ (ví dụ: một Service Task) thất bại, Camunda engine sẽ không ngay lập tức tạo ra một incident. Thay vào đó, nó sẽ cố gắng thực thi lại (retry) tác vụ đó một vài lần. Theo mặc định là 3 lần. Nếu tất cả các lần thử lại đều thất bại, engine sẽ từ bỏ và tạo ra một incident.

Incident này sẽ:

  • Tạm dừng (suspend) luồng thực thi tại điểm xảy ra lỗi.
  • Ghi lại thông báo lỗi và stack trace chi tiết.
  • Hiển thị một cảnh báo trực quan trong Camunda Cockpit, cho phép người vận hành can thiệp.
Camunda Cockpit Runtime View with Heatmap
Giao diện Cockpit cho phép bạn nhanh chóng nhận diện các quy trình đang có sự cố (thông qua tab "Incidents") và xem trạng thái tổng thể của chúng.

Operating Camunda 7

Để có cái nhìn tổng quan về vai trò của incidents trong vận hành, hãy đọc tài liệu sau. Tài liệu này giải thích rõ cơ chế retry và cách một incident được tạo ra.

Hãy đọc phần "Recognizing and managing incidents". Chú ý đến khái niệm "retry" và sự khác biệt giữa giải pháp giám sát "active" và "passive".

Điểm mấu chốt cho Developer: Transaction Boundaries và async before

Đây là một khái niệm cực kỳ quan trọng mà bạn cần nắm vững với tư cách là một developer. Hãy tưởng tượng bạn khởi tạo một quy trình thông qua một lời gọi REST API. Nếu một Service Task trong quy trình đó bị lỗi ngay lập tức, điều gì sẽ xảy ra?

  • Mặc định: Lỗi sẽ được trả về ngay lập tức cho lời gọi REST API dưới dạng lỗi HTTP 500 Internal Server Error. Process instance sẽ không được lưu vào cơ sở dữ liệu và không có incident nào được tạo ra. Bạn sẽ không thấy dấu vết gì trong Cockpit.
  • Khi sử dụng asynchronous before: Bằng cách đánh dấu vào ô "Asynchronous Before" cho một tác vụ trong Camunda Modeler, bạn tạo ra một điểm lưu (savepoint) trong quy trình. Khi quy trình đi đến tác vụ này, engine sẽ commit transaction hiện tại, lưu trạng thái của process instance vào DB, và trả về một HTTP 200 OK cho người gọi. Sau đó, một luồng (thread) riêng của Job Executor sẽ tiếp tục thực thi tác vụ đó. Nếu tác vụ này thất bại, vì nó chạy trong một transaction riêng, lỗi sẽ được engine bắt lại và một incident sẽ được tạo ra.

Video sau đây minh họa chính xác sự khác biệt này.

8 Tutorial Error Handling

Hãy xem cách việc sử dụng 'asynchronous before' thay đổi hoàn toàn cách Camunda xử lý lỗi, từ việc trả về lỗi cho client sang việc tạo ra một incident có thể quản lý được trong Cockpit.

Xem từ 09:59 đến 14:29. Chú ý đến hai lần gọi API: lần đầu tiên nhận về lỗi 'Internal Server Error', và lần thứ hai (sau khi thêm 'asynchronous before') nhận về '200 OK' và một incident xuất hiện trong Cockpit.



2. Thực hành: Tạo và Phân tích một Incident

Bây giờ, chúng ta sẽ cố tình tạo ra một incident để có thể thực hành các bước xử lý.

Bước 1: Chuẩn bị một Service Task gây lỗi

  1. Chọn một quy trình: Sử dụng lại quy trình "Xin nghỉ phép" hoặc bất kỳ quy trình nào bạn đang có.
  2. Thêm Service Task lỗi: Mở file BPMN trong Camunda Modeler. Thêm một Service Task mới, ví dụ đặt tên là "Validate External System".
  3. Cấu hình Implementation:
    • Trong tab 'Properties Panel', chọn 'Implementation' là Java Class.
    • Trỏ nó đến một lớp Java Delegate, ví dụ com.example.camunda.ValidateExternalSystemDelegate.
  4. Tạo Java Delegate: Trong project Spring Boot của bạn, tạo lớp ValidateExternalSystemDelegate và implement interface JavaDelegate. Bên trong phương thức execute, hãy cố tình ném ra một ngoại lệ:
    package com.example.camunda;
    
    import org.camunda.bpm.engine.delegate.DelegateExecution;
    import org.camunda.bpm.engine.delegate.JavaDelegate;
    import org.springframework.stereotype.Component;
    
    @Component("validateExternalSystemDelegate")
    public class ValidateExternalSystemDelegate implements JavaDelegate {
    
        @Override
        public void execute(DelegateExecution execution) throws Exception {
            // Giả lập lỗi kết nối đến hệ thống bên ngoài
            throw new RuntimeException("Failed to connect to external system. Service unavailable.");
        }
    }
    
  5. Quan trọng: Quay lại Camunda Modeler, chọn Service Task "Validate External System", và trong 'Properties Panel', tìm đến mục 'Execution' và tích vào ô Asynchronous Before.
  6. Deploy: Lưu file BPMN và khởi động lại ứng dụng Spring Boot của bạn để deploy phiên bản mới.

Bước 2: Kích hoạt Incident

  1. Bắt đầu một process instance mới của quy trình bạn vừa chỉnh sửa.
  2. Tiến hành quy trình cho đến khi nó đi đến Service Task gây lỗi.

Bước 3: Theo dõi và Phân tích trong Cockpit

  1. Mở Camunda Cockpit.
  2. Trên trang dashboard, bạn sẽ thấy một chỉ số "Open Incidents" hiện là 1.
  3. Vào trang Process Definition của bạn, bạn sẽ thấy một instance đang chạy với một huy hiệu màu đỏ bên cạnh, báo hiệu có sự cố.
Camunda Cockpit: Process Monitoring and Analysis
Cockpit sử dụng các chỉ báo trực quan, như số lượng instance và incidents tại mỗi bước, giúp bạn nhanh chóng xác định các điểm nóng trong quy trình.
  1. Click vào instance đó. Bạn sẽ thấy token đang dừng lại ở Service Task bị lỗi, được tô màu đỏ.
  2. Ở phía dưới, chọn tab "Incidents".
    • Error Message: Bạn sẽ thấy thông báo lỗi ngắn gọn: Failed to connect to external system. Service unavailable..
    • Stacktrace: Click vào link "Full" để xem toàn bộ stack trace. Đây là thông tin quan trọng nhất để bạn (với tư cách là developer) debug và tìm ra nguyên nhân chính xác của lỗi trong code.


3. Xử lý và Khắc phục Incidents trong Cockpit

Sau khi đã phân tích và hiểu nguyên nhân, Cockpit cung cấp cho bạn một số công cụ để xử lý incident.

Operating Camunda 7

Tài liệu này mô tả các hành động bạn có thể thực hiện trực tiếp trong Cockpit để giải quyết một incident. Đây là những thao tác cốt lõi bạn cần nắm vững.

Đọc phần "Handling incidents". Chú ý đến các hành động được liệt kê, đặc biệt là "retry failing jobs", "modify variables", và "cancel process instances".

Hãy thử các hành động này trên incident bạn vừa tạo:

  • Retry: Ở tab "Incidents", bạn sẽ thấy một nút "Retry" (thường là một biểu tượng mũi tên quay vòng) bên cạnh job bị lỗi.
    • Thử ngay: Click vào nút này. Bạn sẽ thấy số lần thử lại (retries) giảm đi, nhưng incident sẽ sớm xuất hiện trở lại vì code của chúng ta vẫn còn lỗi.
  • Modify Variables (Khi lỗi do dữ liệu): Đôi khi lỗi xảy ra do dữ liệu không hợp lệ (ví dụ: một biến null gây ra NullPointerException). Trong trường hợp đó, bạn có thể:
    1. Vào tab "Variables" của process instance.
    2. Chỉnh sửa giá trị của biến gây lỗi.
    3. Quay lại tab "Incidents" và click "Retry". Lần này, tác vụ có thể sẽ thành công.
  • Migrate và Retry (Khi lỗi do code): Đây là kịch bản phổ biến nhất và kết nối trực tiếp với bài học trước.
    1. Sửa lỗi: Bạn (developer) sửa lỗi trong lớp ValidateExternalSystemDelegate (ví dụ: xóa dòng throw new RuntimeException(...)).
    2. Deploy phiên bản mới: Khởi động lại ứng dụng Spring Boot. Bây giờ bạn có một phiên bản quy trình mới đã được sửa lỗi.
    3. Di chuyển (Migrate): Sử dụng các bước đã học ở bài trước, di chuyển process instance đang bị lỗi sang phiên bản quy trình mới nhất.
    4. Retry: Sau khi di chuyển thành công, quay lại instance và click "Retry" một lần nữa. Vì instance giờ đã chạy trên phiên bản mới với code đã sửa, tác vụ sẽ hoàn thành và quy trình sẽ tiếp tục.
  • Cancel Process Instance: Nếu sự cố không thể khắc phục và bạn muốn hủy bỏ quy trình, bạn có thể click vào nút "Cancel" ở góc trên bên phải của trang process instance.

Video sau đây minh họa kịch bản "Migrate và Retry", một luồng xử lý rất thực tế.

8 Tutorial Error Handling

Xem cách một người vận hành di chuyển một instance bị lỗi sang phiên bản mới và sau đó thực hiện retry để giải quyết sự cố, kết hợp kiến thức từ bài học trước và bài học này.

Xem từ 18:21 đến 19:52. Chú ý đến các bước: click vào nút "Migrate", chọn phiên bản đích, thực hiện di chuyển, và cuối cùng là retry tác vụ bị lỗi bằng cách kéo thả token.



4. Các Kỹ thuật Quản lý Nâng cao

Khi hệ thống của bạn lớn hơn, việc xử lý từng incident một có thể không hiệu quả. Camunda cung cấp các cơ chế để quản lý ở quy mô lớn hơn.

  • Suspend Job Definition: Nếu bạn biết một hệ thống bên ngoài (ví dụ: một API) đang gặp sự cố, bạn có thể tạm dừng tất cả các job liên quan đến nó để ngăn chặn việc tạo ra hàng loạt incidents. Trong Cockpit, bạn có thể vào trang 'Job Definitions' và tạm dừng một job definition cụ thể. Điều này sẽ ngăn Job Executor thực thi bất kỳ job nào của loại đó cho đến khi bạn kích hoạt lại.
  • Suspend Process Definition: Trong trường hợp khẩn cấp, bạn có thể tạm dừng toàn bộ một định nghĩa quy trình. Điều này sẽ ngăn việc tạo ra các instance mới và tạm dừng tất cả các instance đang chạy của định nghĩa đó.

Operating Camunda 7

Để hoàn thiện kiến thức về vận hành, hãy đọc về cách tạm dừng các định nghĩa job và quy trình. Đây là những biện pháp phòng ngừa hữu ích khi đối phó với các sự cố hệ thống trên diện rộng.

Đọc nhanh các phần "Suspending specific service calls" và "Suspending whole processes" để hiểu mục đích và cách thực hiện.



Tổng kết

Trong bài học này, bạn đã học được một trong những khía cạnh quan trọng nhất của việc vận hành một hệ thống BPM: quản lý sự cố. Việc xử lý lỗi một cách hiệu quả là yếu tố then chốt để đảm bảo tính ổn định và tin cậy của các quy trình nghiệp vụ.

Những điểm chính bạn cần nhớ:

  • Incident được tạo ra khi một job thất bại sau tất cả các lần retry.
  • Sử dụng asynchronous before là cách tốt nhất để đảm bảo các lỗi kỹ thuật được bắt lại thành incidents trong Camunda thay vì bị mất.
  • Cockpit là trung tâm chỉ huy của bạn để theo dõi (phát hiện incidents), phân tích (xem stack trace), và xử lý (retry, modify variables, cancel).
  • Luồng xử lý sự cố phổ biến nhất đối với lỗi code là: Phân tích lỗi -> Sửa code -> Deploy phiên bản mới -> Di chuyển instance lỗi -> Retry.

Xem trước bài học tiếp theo

Chúng ta đã dành nhiều thời gian cho các tác vụ tự động (Service Tasks) và lỗi của chúng. Tuy nhiên, phần lớn các quy trình nghiệp vụ đều có sự tham gia của con người. Trong bài học tiếp theo của module 10, "Cấu hình User Task với Assignee, Candidate Users và Candidate Groups", chúng ta sẽ đi sâu vào User Task. Bạn sẽ học cách giao việc cho một người cụ thể, một nhóm người, và cách xây dựng các quy trình có tính cộng tác cao.