Cron job là chương trình để chạy các tác vụ lặp đi lặp lại theo chu kỳ nhất định.
Hôm nay chúng ta sẽ tìm hiểu cách cài đặt extension cron trong postgresql trên môi trường docker và chạy thử.
1. Cấu trúc thư mục
├── postgres
| ├── init-db
| └── pg_cron.sh
| ├── Dockerfile
├── docker-compose.yaml
2. Dockerfile
FROM postgres:latest ## Cài đặt git, các lệnh build (như make) và postgres
RUN apt-get update && apt-get -y install git build-essential postgresql-server-dev-14 ## clone repo pg_cron
RUN git clone https://github.com/citusdata/pg_cron.git
## cd vào repo và install
RUN cd pg_cron && make && make install ## Sau khi install xong thì xóa repo lẫn các thư viện vừa cài đặt trên
RUN cd / && \ rm -rf /pg_cron && \ apt-get remove -y git build-essential postgresql-server-dev-14 && \ apt-get autoremove --purge -y && \ apt-get clean && \ apt-get purge ## Copy folder chứa file pg_cron.sh chứa các chuỗi lệnh để chạy trước khi khởi chạy server postgres
COPY ./init-db /docker-entrypoint-initdb.d
3. pg_cron.sh
customconf=/var/lib/postgresql/data/postgresql.conf //Load pg_cron lúc khởi chạy postgre
echo "shared_preload_libraries = 'pg_cron'" >> $customconf //Xác định database mà pg_cron chạy trên đấy, đọc ở biến môi trường
echo "cron.database_name = '$POSTGRES_DB'" >> $customconf
4. docker-compose.yaml
version: "3.8" volumes: db_vol: services: postgres: image: database build: context: ./postgres dockerfile: Dockerfile volumes: - db_vol:/var/lib/postgresql/data ports: - 5433:5432 environment: POSTGRES_PASSWORD: 123 POSTGRES_DB: postgres POSTGRES_USER: postgres
5. Khởi động
Mở terminal chạy lệnh sau
docker-compose up -d
Sau khi build xong, ta bắt đầu kết nối vào container postgres.
Sau đó chạy các lệnh sql sau
Create extension pg_cron; Create table users ( id serial, name text
);
6. Bài tập:
Giờ ta sẽ thử làm một bài tập: Mỗi 1 phút trôi qua, insert vào bảng users một name ngẫu nhiên trong mảng gồm 5 giá trị name.
/* Khởi tạo tác vụ định kỳ bằng cách chạy function schedule */
SELECT cron.schedule('insert-name', '* * * * *',$$ Insert into users (name) values ( (Array['Alice', 'Bob', 'John', 'Jane', 'Smith'])[floor ( 10 * random() / 2)] )
$$);
Sau khi chạy function, ta thử kiểm tra bảng cron.job
Select * from cron.job
Kết quả:
jobid | schedule | command | nodename | nodeport | database | username | active | jobname |
---|---|---|---|---|---|---|---|---|
1 | * * * * * | Insert into users (name) values ......... | localhost | 5432 | postgres | postgres | true | insert-name |
Giờ ta chờ mỗi phút và kiểm tra xem bảng users đã insert dữ liệu hay chưa. Đây là kết quả sau 3 phút
SELECT * FROM users;
Kết quả:
id | name |
---|---|
1 | John |
2 | Bob |
3 | Jane |
Để từ bỏ tác vụ trên, ta có thể sử dụng function unschedule(jobid) hay unschedule(jobname)
SELECT cron.unschedule(1)
//hoặc
SELECT cron.unschedule('insert-name')
Kiểm tra bảng cron.job:
jobid | schedule | command | nodename | nodeport | database | username | active | jobname |
---|
Kết
Như vậy trong bài này ta đã biết cách để chạy tác vụ định kỳ trên postgres khởi động bằng docker. Đây là tiện ích có thể áp dụng cho rất nhiều tình huống trong đời sống cần chạy tác vụ định kỳ, ví dụ như cuối tháng tính lương cho nhân viên,...