EQVPS

VPS-এ cron ও systemd টাইমার দিয়ে কাজ কীভাবে শিডিউল করবেন

ব্যাকআপ, পরিষ্কার আর স্ক্রিপ্ট সময়সূচি মেনে চালান। পাঁচ মিনিটে cron এবং যে তিনটি ফাঁদ নিঃশব্দে কাজ নষ্ট করে, তারপর লগ, বন্ধ থাকার পরে বাদ পড়া রান পূরণ ও সঠিক সময়ের জন্য systemd টাইমার। নিচের প্রতিটি আচরণ নতুন Ubuntu 24.04 সার্ভারে পরীক্ষিত।

আপনি ঘুমিয়ে থাকার সময় কাজ করেই সার্ভার তার দাম তোলে: ব্যাকআপ, লগ রোটেশন, সার্টিফিকেট নবায়ন, নটায় রিপোর্ট। Linux-এ এর জন্য দুটি শিডিউলার আছে। cron চল্লিশ বছরের পুরোনো এবং একটি লাইনই যথেষ্ট। systemd টাইমারের লাগে দুটি ছোট ফাইল, বিনিময়ে মেলে লগ, বন্ধ থাকার পরে বাদ পড়া রানের পূরণ আর সঠিক সময়। এই গাইড Ubuntu 24.04-এ দুটিই ব্যাখ্যা করে, প্রতিটি আচরণ আমাদের ইমেজ থেকে তৈরি নতুন সার্ভারে যাচাই করা, সেই তিনটি ভুলসহ যার জন্য cron-এর কাজ একটি শব্দও না বলে ব্যর্থ হয়।

আপনার sudo থাকা একজন ইউজার দরকার; Ubuntu সেটআপ গাইড একজন তৈরি করে।

1. পাঁচ মিনিটে cron

আমাদের Ubuntu ও Debian ইমেজে cron ইনস্টল করা এবং চালু। প্রতিটি ইউজারের নিজের কাজের টেবিল আছে; নিজেরটি এভাবে এডিট করুন:

crontab -e

প্রতিটি লাইনে পাঁচটি সময়ের ফিল্ড আর একটি কমান্ড:

# min hour day month weekday  command
  30  3    *   *     *        /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  */5 *    *   *     *        /usr/local/bin/check.sh
  0   9    *   *     1-5      /usr/local/bin/report.sh
  @reboot                     /usr/local/bin/start-tunnel.sh

অর্থাৎ: প্রতি রাতে 03:30-এ, প্রতি 5 মিনিটে, কর্মদিবসে 09:00-এ, আর প্রতিটি বুটের পরে একবার। */5 মানে প্রতি পঞ্চম মান, 1-5 একটি পরিসর, 1,15 একটি তালিকা। সার্ভারের টাইম জোন প্রযোজ্য, আমাদের ইমেজে UTC; নিজের জোন একবার হোস্টনেম ও টাইম জোন গাইড দিয়ে সেট করুন আর cron সেটিই মানবে।

কী চলেছে তা journalctl -u cron দিয়ে দেখুন। প্রতিটি রান ইউজার ও কমান্ড লগ করে, আর সেখানেই তিনটি ফাঁদ চোখে পড়ে।

ফাঁদ 1: আউটপুট হারিয়ে যায়। cron কাজের আউটপুট ইউজারকে ইমেল করে। আমাদের ইমেজে মেল সার্ভার নেই, তাই journal-এ এল (CRON) info (No MTA installed, discarding output) আর আউটপুট হারিয়ে গেল। নিজেই রিডাইরেক্ট করুন, যেমন প্রথম উদাহরণে >> /var/log/backup.log 2>&1 দিয়ে করা হয়েছে।

ফাঁদ 2: শতাংশ চিহ্ন। crontab-এ % কমান্ড শেষ করে এবং বাকি অংশকে স্ট্যান্ডার্ড ইনপুট বানায়। আমরা শিডিউল করেছিলাম date +%F > /tmp/today। journal দেখায় cron আসলে কী চালিয়েছে: CMD (date +)। কোনো ফাইল লেখা হয়নি, কোনো এরর আমাদের কাছে পৌঁছায়নি। \% লিখুন, অথবা কমান্ডটি স্ক্রিপ্টে রেখে স্ক্রিপ্টটি শিডিউল করুন।

ফাঁদ 3: ভিন্ন পরিবেশ। cron কাজ bash নয়, /bin/sh দিয়ে, আপনার হোম ফোল্ডারে এবং সীমিত পরিবেশে চালায়। Ubuntu 24.04-এ PATH তার সুনামের চেয়ে ভালো ছিল: /usr/local/bin ও /snap/bin সহ সম্পূর্ণ সিস্টেম পাথ, root ও সাধারণ ইউজার দুজনের জন্যই। যা এখনো নেই তা হল হোম ফোল্ডারের নিচের সবকিছু: ~/.local/bin, nvm-এর node, pipx ও cargo। কাজে পূর্ণ পাথ দিন বা লাইন . $HOME/.profile; দিয়ে শুরু করুন।

যে কাজ ইউজারের নয়, সিস্টেমের, সেগুলো /etc/cron.d/-এ একটি অতিরিক্ত ফিল্ড অর্থাৎ ইউজারসহ ফাইল হিসেবে রাখা হয়:

30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ubuntu /etc/cron.hourly, cron.daily, cron.weekly ও cron.monthly-এ থাকা সবকিছুও চালায়: প্রতি ঘণ্টার 17তম মিনিটে, 06:25-এ, রবিবার 06:47-এ এবং মাসের 1 তারিখে 06:52-এ। সেখানে একটি এক্সিকিউটেবল স্ক্রিপ্ট রাখুন, বাকিগুলোর সঙ্গে সেটিও চলবে।

2. systemd টাইমার

টাইমার দুটি ইউনিট: একটি সার্ভিস যা কাজ করে আর একটি টাইমার যা বলে কখন। আগে স্ক্রিপ্ট, তারপর ইউনিট তৈরি করুন।

sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30

[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target

সার্ভিস নয়, টাইমার চালু করুন:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

list-timers পরের রান, তার বাকি সময় আর শেষ রান দেখায়। লগের জন্য কোনো সেটআপ লাগে না: journalctl -u backup.service-এ প্রতিটি শুরু, প্রতিটি শেষ আর আউটপুটের প্রতিটি লাইন সময়সহ থাকে। কাজটি এখনই চালাতে sudo systemctl start backup.service; সময়সূচির ওপর ভরসা করার আগে স্ক্রিপ্টটিও এভাবে পরীক্ষা করুন।

ক্যালেন্ডার সিনট্যাক্স। OnCalendar এভাবে পড়া হয়: সপ্তাহের-দিন বছর-মাস-দিন ঘণ্টা:মিনিট:সেকেন্ড, আর * যেকোনো মানের জন্য। ব্যবহারের আগে এক্সপ্রেশন পরীক্ষা করুন:

systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2

এটি নরমালাইজড রূপ আর পরের তারিখগুলো ছাপে। কিছু এক্সপ্রেশন যা আমরা যাচাই করেছি:

OnCalendarঅর্থ
*-*-* 03:30প্রতিদিন 03:30-এ
Mon..Fri *-*-* 09:00কর্মদিবসে 09:00-এ
*:0/15প্রতি 15 মিনিটে
weeklyসোমবার 00:00-এ
*-*-01 04:00প্রতি মাসের 1 তারিখে 04:00-এ
*-*-* 03:00 Europe/Kyivকিয়েভের সময় 03:00; আমাদের পরীক্ষায় 01:00 UTC-তে চলেছিল

জানার মতো তিনটি সেটিং। Persistent=true শেষ রান ডিস্কে সংরক্ষণ করে এবং সার্ভার বন্ধ থাকা বা টাইমার থেমে থাকার সময় বাদ পড়া রান পূরণ করে। আমরা আমাদের প্রতি দুই মিনিটের টাইমার থামিয়ে, একটি নির্ধারিত রান পার হতে দিয়ে আবার চালু করেছিলাম: বাদ পড়া রান একই সেকেন্ডে শুরু হল। Persistent ছাড়া টাইমার শুধু পরের পালার অপেক্ষা করে।

আসল চমক AccuracySec। ডিফল্টভাবে systemd সিস্টেমকে কম জাগাতে টাইমারগুলোকে এক মিনিটের জানালায় একত্র করে, তাই আমাদের প্রথম রান 07:42:00 নয়, 07:42:18-এ এসেছিল। AccuracySec=1s দিয়ে পরের রানগুলো ঠিক সেকেন্ড মেনে 07:46:00 ও 07:48:00-এ পড়ল। মিনিট জরুরি হলে এটি সেট করুন; রাতের ব্যাকআপের জন্য ডিফল্ট রাখুন।

RandomizedDelaySec=10m ইচ্ছে করেই উল্টো করে: শুরুর সময় একটি জানালায় ছড়িয়ে দেয়, যাতে দশটি সার্ভার একই সেকেন্ডে একই ব্যাকআপ স্টোরেজে আছড়ে না পড়ে।

একবারের কাজের জন্য কোনো ফাইলই লাগে না:

sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh

এটি একটি অস্থায়ী টাইমার তৈরি করে যা একবার চলে আর মিলিয়ে যায়; ততক্ষণ systemctl list-timers সেটি দেখায়।

3. কোনটি ব্যবহার করবেন

cronsystemd টাইমার
সেটআপ1 লাইন2টি ফাইল
লগশুধু আউটপুট রিডাইরেক্ট করলেjournalctl -u name.service
সার্ভার বন্ধ থাকার সময় বাদ পড়া রানহারিয়ে যায়Persistent=true দিয়ে বুটে চলে
পরের পালায় কাজ এখনো চলছেদ্বিতীয় কপি শুরু হয়প্রথমটি শেষ না হওয়া পর্যন্ত বাদ
সঠিক সময়মিনিট পর্যন্তAccuracySec=1s দিয়ে সেকেন্ড পর্যন্ত
স্ট্যাটাসনেইlist-timers ও systemctl status

এমন দ্রুত লাইনের জন্য cron ব্যবহার করুন যা এক বছর পরেও চিনবেন। টাইমার ব্যবহার করুন এমন সবকিছুর জন্য যার ব্যর্থতা আপনাকে দেখতে হবে, যা ওভারল্যাপ করা চলবে না বা বাদ পড়া রিস্টার্টের পরেও চালাতে হবে: ব্যাকআপ, সার্টিফিকেট নবায়ন, ডেটাবেস পরিষ্কার। cron-এর কাজ ওভারল্যাপ করতে পারলে মুড়ে দিন: flock -n /tmp/backup.lock /usr/local/bin/backup.sh, তাহলে দ্বিতীয় কপি সঙ্গে সঙ্গে বেরিয়ে যাবে।

দুটি শিডিউলারই একটি কাজ চালিয়ে থেমে যায়। যে প্রোগ্রামকে চব্বিশ ঘণ্টা চলতে আর ক্র্যাশের পরে ফিরে আসতে হবে, তার জন্য সময়সূচি নয়, সার্ভিস লাগে; দেখুন systemd সার্ভিস কীভাবে তৈরি করবেন আর Windows-এর জন্য Windows Server-এ স্ক্রিপ্ট 24/7 কীভাবে চালাবেন। একটি ভালো প্রথম টাইমার হল আমাদের restic দিয়ে ব্যাকআপ গাইডের টাইমারটি; স্বয়ংক্রিয় নিরাপত্তা আপডেট এমন একটি টাইমার যা Ubuntu আগে থেকেই দেয়, apt-daily-upgrade.timer, নতুন সার্ভারে চলা 17টির একটি।

FAQ

আমার কাজ টার্মিনালে চলে কিন্তু cron-এ চলে না, কেন?

তিনটি সাধারণ কারণ। cron কাজটি bash নয়, sh দিয়ে চালায়, তাই শুধু bash-এর সিনট্যাক্স ব্যর্থ হয়। হোম ফোল্ডারে ইনস্টল করা টুল যেমন nvm, pipx বা cargo, cron-এর PATH-এ থাকে না, তাই পূর্ণ পাথ ব্যবহার করুন। আর কমান্ড লাইনে যেকোনো % কমান্ড শেষ করে দেয়: আমাদের সার্ভারে date +%F হয়ে গেল date +। এটিকে \% লিখুন বা কমান্ডটি স্ক্রিপ্টে নিয়ে যান।

cron-এর আউটপুট কোথায় যায়?

ডিফল্টভাবে ইমেলে। আমাদের ইমেজে মেল সার্ভার নেই, তাই cron লগে লেখে 'No MTA installed, discarding output' আর আউটপুট হারিয়ে যায়। কাজে >> /var/log/myjob.log 2>&1 যোগ করুন, অথবা systemd টাইমারে যান যার আউটপুট নিজে থেকেই journal-এ যায়।

cron-এর তুলনায় systemd টাইমারের সুবিধা কী?

journalctl-এ লগ, চলমান কাজের দ্বিতীয় কপি শুরু হয় না, সার্ভার বন্ধ থাকার সময় বাদ পড়া রান Persistent=true দিয়ে পূরণ হয়, আর স্ট্যাটাস লাইন পরের ও শেষ রান দেখায়। সংক্ষিপ্ততায় cron জেতে: দুটি ফাইলের বদলে একটি লাইন।

আমার টাইমার 18 সেকেন্ড দেরিতে চলল। কেন?

ডিফল্টভাবে systemd সিস্টেমকে কম জাগাতে টাইমারগুলোকে এক মিনিটের জানালায় একত্র করে; এটাই AccuracySec সেটিং। আমাদের প্রতি দুই মিনিটের টাইমার 07:42:00-এর বদলে 07:42:18-এ চলেছিল। AccuracySec=1s দিয়ে এটি ঠিক 07:46:00-এ চলল। সঠিক মিনিট জরুরি হলে এটি সেট করুন।

cron আর টাইমার কোন টাইম জোন ব্যবহার করে?

সার্ভারের, যা আমাদের ইমেজে UTC। timedatectl দিয়ে একবার সেট করুন, হোস্টনেম ও টাইম জোন নিয়ে আমাদের গাইড দেখুন, তাহলে cron ও টাইমার সেটিই মানবে। টাইমার নিজের জোনও রাখতে পারে: OnCalendar=*-*-* 03:00 Europe/Kyiv আমাদের পরীক্ষায় 01:00 UTC-তে চলেছিল।

মন্তব্য

এখনো কোনো মন্তব্য নেই। প্রথম হোন।

একটি মন্তব্য দিন

মন্তব্য প্রকাশের আগে মডারেট করা হয়।