Linux Cron thực tiễn – Tất tần tật những gì bạn cần biết

You have a cron – you have a job
Image from: https://www.reddit.com/r/ProgrammerHumor/comments/6ng8f7/cron_job/

Đợt vừa rồi hết cách ly xã hội dự án lại đi vào phase release, nên lu bu quá không viết được bài nào. Hôm nay mình sẽ note lại một số kỹ thuật chú ý khi dùng Cron job trong Linux như thiết định job theo giờ, cài đặt crontab trong Docker, thiêt định job theo đơn vị giây, …

Cron là gì

Cron job là những tác vụ, chương trình cần chạy hằng ngày, hằng giờ hoặc vài phút 1 lần, …

Trong Linux (Ubuntu) thì crontab là daemon để quản lý thiết định cron. Bài này của mình chủ yếu trình bày các thiết định trên Ubuntu nếu bạn cần thiết định trên CentOS, Redhat thì có thể trao đổi với mình hoặc chịu khó google một chút sẽ tìm thấy cách làm tương ứng ở hệ điều hành khác.

Các file thiết định cron

/etc/
├── cron.d
│   ├── anacron
├── cron.daily
├── cron.hourly
├── cron.monthly
├── crontab
├── cron.weekly

cron.d

Thông thường mọi người sẽ tạo quản lý file thiết định tại thư mục này.

cron.***

Các file thiết định được chia theo ngày, tháng, giờ. Bạn có thể tạo file thiết định trong các thư mục này cho dễ quản lý. Tuy nhiên theo kinh nghiệm của mình thì nên dùng cron.d thì các file thiết định tập trung một chỗ sẽ dễ quản lý hơn.

crontab

Đây là file thiết định chính của cron trên Linux, ngoài ra bạn có thể dùng command crontab để thiết đinh.

Tạo một cron của bạn

Hãy thử tạo một cron job bằng cách tạo 1 file trong thư mục /etc/cron.d. Mình khuyến khích nên copy từ file crontab và chỉnh sửa

$ cp /etc/crontab /etc/cron.d/test_cron

Xong. bạn đã có 1 file thiết định cron. Đơn giản quá phải không?

Tiếp theo mình sẽ cũng xem chi tiết cách thiết định thời gian, chương trình chạy, và khởi động file cron vừa tạo nhé.

Cách viết cron

Hãy check nội dung file /etc/cron.d/test_cron

# cat /etc/cron.d/test_cron
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

Hãy thử thay đổi nội dung file test_cron như sau.

# m h dom mon dow user  command
Minute Hour DayOfMonth Month DayOfWeek User Command

# every 1 minute
* *    * * *  root   touch /home/ubuntu/test.txt

# every minute in 1:00〜1:59 everyday
* 1    * * *  root   touch /home/ubuntu/test.txt

# 1:00 AM everyday
0 1    * * *  root   touch /home/ubuntu/test.txt

# at 00:00 from day 12 to 20 every month
0 0    12-20 * *  root   touch /home/ubuntu/test.txt

# at 00:00 from Monday to Friday every week
0 0    * * 1-5  root   touch /home/ubuntu/test.txt
#

Chú ý 1: cú pháp sử dụng Tab, Space trong thiết đinh. Vị trí của Tab,Space như sau nhé.

*[Space]*[Tab]*[Space]*[Space]*[Tab]root[Tab]Commands

Chú ý 2: Cuối file thiết định cron luôn thêm một dòng trống.

Cập nhật thay đổi Cron

Cập nhật thay đổi của cron bằng cách khởi động lại dịch vụ (daemon) cron.

$ sudo service cron restart

Thiết định file log cho cron

Dùng syslog

Thêm thiết định cho phép syslog thu thập cron log bằng cách bỏ comment out trong file thiết định syslog.

Nhớ khởi động lại service rsyslog sau khi lưu file thiết định. Log này sẽ giúp bạn debug cron nếu xảy ra lỗi trong file thiết định

$ vim /etc/rsyslog.d/50-default.conf

# Remove this comment out
# cron.*                          /var/log/cron.log

$ sudo service rsyslog restart

Thiết định log cho command trong Cron

Mình hay thiết định log cho các tác vụ cron để đảm bảo job chạy đúng cho phép xem lại log khi có lỗi hay vấn đề gì.

Ta có thể thay đổi file /etc/cron.d/test_cron như sau

* *    * * *  root   touch /home/ubuntu/test.txt >> /var/log/test-cron.log 2>> /var/log/test-cron-error.log

File /var/log/test-cron.log sẽ chứa các output thường của cron job. File /var/log/test-cron-error.log sẽ chứa các lỗi khi thực hiện cron job

Thiết định cron job theo đơn vị giây

Thông thường, cron job chỉ cho phép thiết định theo đơn vị phút. Trường hợp bạn cần thiết định 10 giây chạy một lần thì phải làm thế nào?

Chúng ta cần một trick khi thiết định.

Hãy thử thay đổi file test_cron để chạy 10 giây 1 lần nhé.

# for i in `seq [second_from] [num_of_seconds] [second_to]`;do (sleep ${i}; [your command] ) & done;
# every 10 seconds
* *    * * *  root   for i in `seq 0 10 59`;do (sleep ${i}; touch /home/ubuntu/test.txt ) & done;

Xong. Quá đơn giản phải không? Ta sẽ thiết định một vòng for chạy từ giây second_from đến giây thứ second_to theo khoảng cách num_of_seconds. Trong ví dụ trên, mình đã thiết định vòng for chạy theo seq từ giây 0 đến giây 59 theo khoảng cách 10 giây 1. Bạn có thể sửa lại cho phép chạy 5s 1 lần hay từ giây thứ 10 đến giây thứ 30, …

Bạn còn có thể dùng cấu trúc while … do để thiết định. Ví dụ:

while : ; do sleep 10 ; some_command || break ; done

Thiết định cron duy nhất 1 process 1 lần

Một số trường hợp bắt buộc chỉ được chạy job 1 process 1 lần tránh bị duplicate

Đối với Ubuntu bạn có thể dùng run-one hoặc flock để đảm bảo chỉ 1 process duy nhất. Ví dụ

* *    * * *  root   run-once touch /home/ubuntu/test.txt >> /var/log/test-cron.log 2>> /var/log/test-cron-error.log
* *    * * *  root   run-once flock -n /tmp/test-cron.lock  /home/ubuntu/test.txt >> /var/log/test-cron.log 2>> /var/log/test-cron-error.log

Bạn có thể tìm hiểu thêm thêm về run-one hoặc flock nếu cần.

Đọc biến môi trường từ file thiết định bên ngoài

Bạn cũng có thể thiết định cron job cho phép đọc các thiết định từ file bên ngoài. Mình thường dùng các file .env để quản lý môi trường

Ví dụ: Mình sẽ lưu khoảng cách thực hiện 10 giây ở ví dụ trên vào file /home/ubuntu/test-cron.env và load nó khi chạy cron job.

TIME=10

Sửa lại file thiết định test_cron

# Thiết định Shell type là bash
SHELL=/bin/bash
# Load biến môi trường TIME từ file .env trước khi chạy cronjob
* *    * * *  root   for i in `source /home/ubuntu/test-cron.env && seq 0 ${TIME} 59`;do (sleep ${i}; touch /home/ubuntu/test.txt ) & done;

Thiết định cron job cho trong Dockerfile

Bạn có thể tham khảo Stackoverflow topic sau

https://stackoverflow.com/questions/37458287/how-to-run-a-cron-job-inside-a-docker-container

Ví dụ trường hợp test-cron thì có thể thiết định như sau.
Dockerfile

FROM ubuntu:latest

RUN apt-get update && apt-get -y install cron

# Copy test-cron file to the cron.d directory
COPY test-cron /etc/cron.d/test-cron

# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/test-cron

# Apply cron job
RUN crontab /etc/cron.d/test-cron

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Run the command on container startup
CMD ["cron", "-f"]

File test-cron sẽ được sửa như sau để đảm bảo redirect log sang standard output của Docker.

* *    * * *  root   run-once touch /home/ubuntu/test.txt > /proc/1/fd/1 2>/proc/1/fd/2

Conclusion

Mình đã chia sẻ tất tần tật những kinh nghiệm thiết định cron job mình cóp nhặt được. Nếu bạn làm chủ được các kỹ thuật trên thì có thể mạnh dạn áp dụng vào sản phẩm hiện có, hoặc tự tin chém gió khi phỏng vấn.

Happy hacking.

Bài viết có tham khảo từ:

Python – ngôn ngữ lập trình nhất định phải học năm 2020

Work from home

Social Distancing – Cách ly toàn xã hội thì ở nhà làm gì?

Dịch bệnh hay cách ly là điều không ai muốn của dịch bệnh, song nếu có góc nhìn tích cực thì có nhiều thứ có thể khiến ta thấy vui vẻ, lạc quan hơn. Chỉ số Air Visual của Hà Nội thấp hơn, không khí trong lành hơn, ô nhiễm giảm nhờ cách ly. Cách ly là thời gian ta được (phải) sống chậm lại, có nhiều thời gian để đầu tư cho bản thân, ở gần gia đình hơn. Nhiều bạn bè mình khoe đọc được cả chục cuốn sách, chạy được mấy trăm cây số, … Bản thân mình cũng được ở nhà cả ngày, được ăn cơm vợ nấu rất ngon, chơi với con nhiều hơn, tìm được niềm vui trong việc rửa bát.

Bẻ lái – Nhân thời gian cách ly, mình sẽ chia sẻ một chút về ngôn ngữ lập trình 😀

Ngôn ngữ lập trình nào nên học

Chỉ cần tìm kiếm sơ sơ trên google thì bạn có thể tìm thấy hàng trăm hàng ngàn kết quả na ná như “Em nên học ngôn ngữ lập trình nào”, “Ngôn ngữ lập trình nào nên học”, “Ngôn ngữ lập trình nào dễ tìm việc”, …. Khi bắt đầu học lập trình thì câu hỏi thường gặp nhất và khó nhất là chọn ngôn ngữ nào dễ học nhất, học xong thì dễ tìm việc nhất, dễ kiếm tiền nhất.

Mình code vì tiền … à nhầm vì đam mê nên không quá đặt nặng vấn đề ngôn ngữ nào lắm. Mỗi ngôn ngữ như C, Java, PHP, Python, Go, Javascript,… có điểm mạnh điểm yếu riêng. Ngôn ngữ là công cụ nên không có công cụ nào xịn nhất chỉ có cái nào phù hợp nhất. Ngôn ngữ nào có thể giải quyết tốt bài toán đang gặp một cách nhanh nhất, hiệu quả nhất thì nên chọn.

Bẻ lái 2 – Hôm nay mình sẽ giới thiệu về Python – 1 ngôn ngữ mình nghĩ là sẽ hot trong năm 2020.

Chú ý: Đối tượng bài viết này là các anh em developer đã có kinh nghiệm lập trình và đang tìm một ngôn ngữ mới để học, làm việc.

Python được dùng rộng rãi trong giới developer nhà giàu?

Python – Ngôn ngữ lập trình ra đời từ năm 1991 bởi Guido van Rossum và rất phổ biến. Python đang ngày càng trở nên hot.

Theo phân tích của Stack Overflow thì dựa trên lượng truy cập từ các quốc gia thu nhập cao – thu nhập của developer cũng cao – developer nhà giàu , Python cũng có vị thế đang tăng đáng chú ý. (bài gốc: https://stackoverflow.blog/2017/09/06/incredible-growth-python/)

Python được sử dụng rộng rãi ở nước có thu nhập cao

Tại sao gần đây Python lại hot

Sự phát triển của Machine Learning (ML) /AI

Những năm gần đây đánh dấu sự phát triển mạnh mẽ của lĩnh vực ML và AI. Trong giới software developer chắc bạn cũng cảm nhận được làn sóng này, nhiều công ty cá nhân bắt đầu dịch chuyển sản phẩm từ outsourcing sang lĩnh vực này.

Python có thế mạnh sẵn có là các thư viện hỗ trợ phân tích dữ liệu nên được sử dụng rộng rãi trong nhiều công ty lớn. Trong lĩnh vực ML , Python được sử dụng rộng rãi trong việc build model, thuật toán trong AI/ML. Các thư viện nghiên cứu & áp dụng Machine Learning đều làm việc bằng Python. TensorFlow nổi tiếng của Google cũng chủ yếu làm việc với Python. Hầu hết các khóa học về ML / AI đều dùng Python.

Tại sao web developer cũng nên học Python

Càng ngày càng có nhiều công ty, tổ chức áp dụng ML/ AI vào trong sản phẩm của mình. Dẫn đến việc triển khai các model của ML/AI lên nền tảng Web / API là không thể thiếu.

Để tối ưu thời gian phát triển và triển khai model lên môi trường production thì các công ty, developer thường chọn Python vì nó dễ tiếp cận với ML/AI researcher – những người phát triển & nghiên cứu ML/AI. Hơn nữa, Khi muốn triển khai một model ML lên nền tảng ngôn ngữ khác như PHP, Java thì bắt buộc phải xử lý convert model hoặc phải phát triển phần adapter giữa 2 ngôn ngữ. Việc convert một thuật toán hoặc model ra ngôn ngữ khác thì mất rất nhiều chi phí vì các thư viện ML/AI thì chủ yếu làm việc với Python.

Bên cạnh các dự án phát triển ML/AI model thì dự án phát triển API dùng Python cho hệ thống sử dụng ML/AI cũng rất hot. Gần đây mình cũng làm khá nhiều dự án liên quan đến tư vấn, phát triển hệ thống web, API có tích hợp ML/AI model. Python luôn là sự lựa chọn hàng đầu của mình và khách hàng.

Các công ty lớn sử dụng Python

Nhiều công ty công nghệ, tài chính hot hít trên thế giới sử dụng Python. Có thể kể sương sương như Uber, PayPal, Google, Facebook, Instagram, Dropbox, Netflix, Reddit, Goldman Sachs đều dùng Python để phát triển và thử nghiệm.

Bạn sẽ có cơ hội được làm việc cho các công ty lớn, dự án lớn hơn.

Hơn nữa, các công ty lớn thường có nhiều đóng góp mã nguồn mở giúp cho cộng đồng Python lớn mạnh.

Túm lại

Nếu đánh giá về độ phổ biến, tương lai và mức lương thì Python là một ngôn ngữ lập trình nhất định phải master trong năm 2020

Đây hoàn toàn là ý kiến suy nghĩ (thiên kiến) cá nhân của mình nên nếu bạn có ý kiến đóng góp hay nhận xét gì xin để lại comment hoặc liên hệ mình theo email tuantranf[at]gmail.com

Flux architecture trong Reactjs

(Đợt này dịch Anh Cô Vy cũng căng, các trường mầm non đều nghỉ nên cả ngày toàn dành thời gian chơi với con nên mãi không viết được blog nào. )

Từ khi vào đời bằng nghề code thì hầu hết thời gian mình lăn lộn trong rừng backend, devops, app, … cũng không mấy khi làm dự án frontend.

Backend – Frontend
From: https://www.reddit.com/r/ProgrammerHumor/comments/84mzyg/frontend_vs_backend_20/

Lâu lâu thì cũng có nhảy vào fix bug nhưng hầu hết là xử lý logic hoặc task đơn giản. Gần đây, mình tham gia một dự án Web chatbot với Rasa Backend (để make color cho CV full-stack engineer) từ khâu thiết kế code base, … Nên muốn chia sẻ đôi chút về cấu trúc code.

Những kỹ thuật đã áp dụng

Dự án lần này mình làm dự án về kỹ thuật thì có một số thứ
– React js
– Typescript
– MobX
– Webpack
– Socket.io
– Unittest (Jest)

Architecture

Mục đích đặt ra
– Cấu trúc đơn giản dễ hiểu do hệ thống cũng khá đơn giản
– Hạn chế tối đa lỗi, bug
– Đảm bảo code format, code style cho dự án (tận dụng sức mạnh của typescript, unittest)

Sử dụng Flux architecture

Flux Architecture
From: https://medium.com/@me_76676/hand-tooled-flux-creating-a-tiny-flux-architecture-in-a-handful-of-lines-d3ae27865e2e

Data flow

Dataflow
  • Repository: phần phụ trách trao đổi dữ liệu từ server thông qua API hoặc Websocket. Các thao tác lấy và cập nhật dữ liệu thực hiện qua lớp này. Bên mình dùng Restful nên thường đặt tên theo resource ví dụ như: UserRepository gọi các API liên quan đến user, ApplicationRepository phụ trách các API liên quan đến application
  • Actions: action là phần quan trọng phụ trách các tác vụ sau
    • Thao tác Repository để lấy và cập nhật dữ liệu từ backend
    • Nhận các event từ view
    • Cập nhật store = trạng thái application
  • Stores: Quản lý trạng thái application (MobX)
  • Views: Là phần phụ trách UI, nhận các thao tác của người dùng, truyền các event vào actions. View sẽ giám sát sự thay đổi của store để cập nhật các component của mình

Một nguyên tắc quan trọng ở đây là trạng thái của application – store chỉ được thay đổi thông qua actions, views sẽ giám sát thực thay đổi của store để cập nhật lại. Views không thao tác trực tiếp đến store.

Kết luận

  • Cũng khá thú vị khi nhìn phần code base mình viết ra được thay đổi, trưởng thành theo dự án.
  • Có background backend thì phần thiết kế gọi API restful hoặc build môi trường dev ở local, API nhàn hơn. Cần thiết tự sửa API, tự sửa DB theo nhu cầu

PS, Việt Nam cố lên, thế giới cố lên!

Additional, Other Kubernetes related topics is here. https://tuantranf.me/tag/kubernetes/