Source: https://www.tuanh.net/blog/devops/scheduling-jobs-in-microservices-and-illustrative-examples
Trong kiến trúc microservices phức tạp ngày nay, quản lý hiệu quả các tác vụ được lên lịch là vô cùng quan trọng để duy trì hiệu suất và tính nhất quán của hệ thống. Bài viết này sẽ đi sâu vào các cách tiếp cận khác nhau để tích hợp chức năng cron job vào các dịch vụ dựa trên Spring Boot trong hệ sinh thái microservices.
1. Sử dụng @Scheduled
Spring Boot cho phép lập lịch các công việc định kỳ thông qua chú thích @Scheduled. Chú thích này có thể được áp dụng cho các phương thức trong các lớp bean, được chú thích với @Component, @Service hoặc @Configuration.
@Service
public class AService { @Scheduled(cron = "0 0 * * * *") public void performScheduledTask() { // Logic cho cron job }
}
Để lên lịch các tác vụ, trước tiên bạn cần kích hoạt tính năng lên lịch trong ứng dụng Spring Boot. Điều này được thực hiện bằng cách chú thích một lớp cấu hình với @EnableScheduling.
0 0 * * * là một biểu thức cron được sử dụng để lên lịch các tác vụ theo định kỳ. Dưới đây là phân tích chi tiết từng phần của biểu thức này:
- Giây: 0 Chỉ định rằng tác vụ sẽ bắt đầu ở giây thứ 0 của mỗi phút.
- Phút: 0 Chỉ định rằng tác vụ sẽ bắt đầu ở phút thứ 0 của mỗi giờ.
- Giờ: * Chỉ định rằng tác vụ sẽ chạy mỗi giờ. Dấu sao (*) có nghĩa là "mọi giá trị khả dụng", vì vậy tác vụ sẽ chạy vào mọi giờ trong ngày.
- Ngày trong tháng: * Chỉ định rằng tác vụ sẽ chạy mọi ngày trong tháng. Dấu sao (*) có nghĩa là "mọi giá trị khả dụng", vì vậy tác vụ sẽ chạy vào mọi ngày trong tháng.
- Tháng: * Chỉ định rằng tác vụ sẽ chạy mỗi tháng. Dấu sao (*) có nghĩa là "mọi giá trị khả dụng", vì vậy tác vụ sẽ chạy mọi tháng trong năm.
- Ngày trong tuần: * Chỉ định rằng tác vụ sẽ chạy mọi ngày trong tuần. Dấu sao (*) có nghĩa là "mọi giá trị khả dụng", vì vậy tác vụ sẽ chạy mọi ngày trong tuần. Tóm lại: Biểu thức cron 0 0 * * * sẽ thực thi tác vụ mỗi ngày vào lúc 00:00:00 (nửa đêm). Điều này có nghĩa là tác vụ sẽ chạy chính xác vào nửa đêm mỗi ngày.
Nếu bạn gặp bất kỳ khó khăn nào khi tạo biểu thức công việc cron, bạn có thể tham khảo crontab.guru
Khi bạn định nghĩa một module trên nhiều pod và sử dụng chú thích @Scheduled, chú thích này sẽ được kích hoạt nhiều lần vì mỗi pod về cơ bản là một ứng dụng riêng biệt. Chúng không có trạng thái đối với nhau. Do đó, nếu bạn muốn sử dụng chú thích @Scheduled, hãy đảm bảo chỉ có một phiên bản của module đang chạy tại bất kỳ thời điểm nào.
2. Sử dụng Task Scheduling Service
Các dịch vụ như Amazon CloudWatch Events và Google Cloud Scheduler cho phép bạn lập lịch kích hoạt các điểm cuối HTTP hoặc hàm của mình ở các khoảng thời gian cụ thể.
Dưới đây, tôi sẽ trình diễn một ví dụ đơn giản, sử dụng Schedules trong Amazon EventBridge của AWS.
Chọn sự kiện bạn muốn kích hoạt. Trong trường hợp này, tôi đã chọn một hàm lambda. Bạn có thể chọn các kích hoạt khác.
Sau khi thiết lập thành công, một hàm công khai sẽ được kích hoạt để chạy một công việc vào lúc 10:10 AM ngày 14 tháng 8 năm 2024.
3. Sử dụng Kubernetes CronJobs
Kubernetes CronJobs cung cấp một cơ chế lập lịch để chạy các job tại các thời điểm hoặc khoảng thời gian được chỉ định trong cụm Kubernetes của bạn, điều này rất lý tưởng cho kiến trúc microservices.
apiVersion: batch/v1
kind: CronJob
metadata: name: test-job labels: test.ch/module: test-service
spec: schedule: "0 1 * * *" jobTemplate: spec: template: metadata: labels: sidecar.istio.io/inject: "false" spec: containers: - name: test-job image: gcr.io/test-repo/java8-commons imagePullPolicy: IfNotPresent env: - name: URI value: "http://test-service:8080/api/test-cronjob/run" args: - /bin/sh - -c - | RESULT=$(curl -X POST -s -o /dev/null -I -w "%{http_code}" $URI -H "Accept: application/json" if [ $RESULT -ne 200 ]; then >&2 echo "Receive $RESULT from test-service with api $URI" else echo $RESULT fi restartPolicy: OnFailure
YAML này định nghĩa một CronJob trong Kubernetes. CronJob này sẽ chạy một công việc hàng ngày lúc 1 giờ sáng. Công việc này sẽ gửi một yêu cầu HTTP POST đến một URL cụ thể và kiểm tra mã phản hồi.
- apiVersion: batch/v1: Xác định phiên bản API cho CronJobs trong Kubernetes.
- kind: CronJob: Chỉ ra rằng đây là một đối tượng CronJob.
- metadata: Chứa thông tin meta về CronJob.
- name: Tên duy nhất của CronJob (test-job).
- labels: Nhãn dùng để chọn và nhận dạng CronJob.
- spec: Định nghĩa thông số kỹ thuật của CronJob.
- schedule: Lịch trình chạy công việc. Trong trường hợp này, nó được đặt để chạy lúc 1 giờ sáng mỗi ngày.
- jobTemplate: Chỉ định mẫu cho công việc sẽ được tạo bởi CronJob.
- spec: Thông số kỹ thuật của công việc.
- template: Mẫu pod cho công việc.
- metadata: Thông tin meta cho pod.
- labels: Nhãn cho pod, bao gồm nhãn để ngăn chặn tiêm nhập Istio sidecar.
- spec: Thông số kỹ thuật của pod.
- containers: Danh sách các container.
- name: Tên của container (test-job).
- image: Ảnh Docker được sử dụng cho container.
- imagePullPolicy: Chính sách kéo ảnh.
- envFrom: Chỉ định một bí mật để điền các biến môi trường.
- env: Định nghĩa các biến môi trường bổ sung.
- args: Các đối số truyền cho container.
Một script shell thực hiện:
- Gửi yêu cầu HTTP POST đến URI được chỉ định.
- Kiểm tra mã phản hồi HTTP và in ra một thông báo lỗi nếu không phải là 200.
- restartPolicy: Chính sách khởi động lại container.
Nếu bạn sử dụng GKE, bạn có thể tìm kiếm "test-cronjob" và nhận được kết quả như trên.
4. Kết luận
Tóm lại, việc chọn phương pháp lập lịch phù hợp phụ thuộc vào nhu cầu cụ thể của bạn và cấu trúc của hệ thống microservice mà bạn đang quản lý. Cảm ơn bạn đã đọc và chúng tôi mong được gặp lại bạn.