嗨,各位鐵人夥伴! 👋
這是一篇專為新手設計的文章。如果你是經驗豐富的開發者,可以考慮跳過,或將它分享給需要入門指引的新人,有效節省您寶貴的指導時間! 😉
本文將以最淺顯易懂的方式,解釋以下概念:
與 AI 生成的文稿不同,我會說明甲方實務上的用語及常見案例。本文內容皆由本人撰寫,AI 僅輔助美化排版。讀者若有不理解之處,可搭配 AI 查詢。
前幾篇寫得比較辛苦,這篇內容相對輕鬆,請輕鬆閱讀。
我們一樣先參考維基百科的定義:
批次處理任務(英語:batch processing),又稱批處理任務,是指在電腦上無須人工干預而執行系列程式的作業。
而業界所說的「跑批」,就是執行批次的意思。
這次維基百科的解釋算是相當好懂,我再口語補充說明:
什麼叫做「無人工干預」?你可能會想,軟體或系統本來就是自動化,不是嗎?本來就沒有人工干預啊?
不,請思考一下常見的 Web Application,例如公司內部的客服系統。是不是需要內部工作人員透過瀏覽器點選頁面上的按鈕或輸入文字,系統才會執行相對應的命令?這就是所謂的「人工干預」。
從廣義來看,還記得前幾章提到的,大部分基於 Web Application 的系統,基於 HTTP 會有 HTTP Request 與 HTTP Response。這個 Request 大部分是由使用者觸發(少部分例外),系統收到 Request 後才執行任務並回覆 Response,這就是有人為介入。
你可能會問,難道有不需要人為介入就能執行的作業嗎?
有!而且非常多。以下列舉業界常見的案例:
銀行系統的日終清算 (End-of-Day Settlement) 🏦
銀行系統是批次處理最經典的應用場景。想像一下,每天營業時間結束後,銀行需要進行大量的後台工作。這時候,會啟動一個日終清算批次來自動處理。
電信公司的帳單產生 (Billing Generation) 📞
電信公司每個月都需要為數百萬甚至數千萬用戶產生帳單。這是一個龐大且複雜的作業,如果人工操作會耗費大量時間與人力,且極易出錯。因此,電信公司會使用帳單產生批次。
企業人力資源系統 (HR System) 的薪資計算 (Payroll Calculation) 💰
許多大型企業,特別是員工人數眾多的製造業或服務業,其薪資計算也是典型的批次作業。
跑批產出檔案進行交換 📁
甲方系統中非常常見的檔案交換方式。例如,A 系統透過批次產出 B 系統所需的資料檔案,然後透過 FTP 協定傳送給對方。這是超級、超級、超級常見的系統架構。
跑批產出報表 📊
有時候許多系統會有報表分析的需求,也會透過批次來產生。但有時候會將資料傳送給 ODS 或資料倉儲,交由它們來產生(詳見後面篇章說明)。
跑批清理 OS 空間或 Server Log 🧹
對,這也絕對可以算作批次。所以批次未必都與業務邏輯相關,也很常在作業系統上透過批次進行維運相關的工作。
透過跑批機制處理預約任務 ⏰
這是一種有時會見到的設計。例如,某系統可以預約早上 10 點才寄送簡訊,但現在才半夜。這時候有些系統會在資料庫中註記該任務是早上十點才能執行,批次可能每分鐘或每小時執行,每次執行就讀取資料庫檢查是否時間到了可以發送簡訊。這也是批次的一種小變形。
看完以上例子,你會發現:
我們上面提到批次通常是固定時間執行,例如每天半夜、每小時、每分鐘。這個固定時間在系統架構中通常會稱為 排程器 (Scheduler)。
而在 Linux 主機部署的架構上,非常非常常見且好用的 Scheduler 就是 Cronjob。這個關鍵字在許多 Linux 主機架構維運上很常出現,務必記住。
Cronjob 是一個在 Unix-like 系統(如 Linux)中非常常見的排程服務。你可以用一個特定的語法,來設定一個定時執行的任務。
請記得,它只是排程,也就是它主要負責設定時間執行某個東西,並不是負責要執行什麼。至於執行什麼,則取決於你後面的指令。
我們直接看範例:
0 2 * * * /path/to/your/billing_script.sh
30 1 * * * /usr/bin/java -jar /home/user/app/DailyReport.jar >> /home/user/log/daily_report.log 2>&1
0 6 * * 0 /usr/bin/python3 /home/user/scripts/data_sync.py >> /home/user/log/data_sync.log 2>&1
上面是三個 Cronjob 的範例。你可以直接省略後面那串,後面那串是要執行的指令,而前面的數字才是排程的精髓。
這五個欄位從左到右,依序代表了時間的各個單位:
其實你根本不用背,要用到的時候查一下就好,或是到網站 https://crontab.guru/ 查詢。
為什麼上面這五個數字需要了解一下?因為許多程式語言或框架的 Scheduler 表達方式也差不多是用類似的方式,如下所示。
補充 : Cronjob 在維運上有時要特別去檢查,因為他寫在主機 OS 上,所以有時候老系統會藏有一些意外驚喜 ,本人曾經踩過坑,如果你接手的是老系統,建議盤點一下你的所有主機帳號並檢查是否有隱藏版的 cronjob ,否則突然哪些跑了什麼奇怪的批次你都不知道,與您分享
批次的排程是不是只能用 Cronjob?不,其實主流的程式語言或框架,本身大多有支援排程。
例如常見的 Spring Framework:
@Scheduled(cron = "0 30 1 * * *")
public void dailyReportJob() {
// 這是你的批次處理邏輯
System.out.println("執行每日報表任務...");
}
Python APScheduler:
from apscheduler.schedulers.blocking import BlockingScheduler
def my_job():
print('執行資料同步任務...')
scheduler = BlockingScheduler()
scheduler.add_job(my_job, 'cron', hour=6, minute=0, day_of_week='sun')
scheduler.start()
使用程式語言或框架內建的排程器,其優點顯而易見:
排程超簡單,不就是一個簡單的事情:固定時間執行某個東西?
對,但也不完全對。如果你面對的是一個大型甲方的系統,動不動就是數十個系統串接。
我們用上面出現過的例子來說明:A 系統半夜批次產出檔案給 B 系統,B 系統收到後總不會什麼都不做吧?通常 B 系統收到檔案後也會執行其他批次。
那如果 A 系統的批次失敗怎麼辦?B 系統的批次會不會依賴於 A 系統產出的批次?萬一 B 系統的作業還要等待其他更多批次,那就會變成複雜的相依關係。
因此,有時候你會看到企業有專門負責批次排程的系統。
簡單的企業版排程管理工具例如:
開源的還有 Apache Airflow,我相信還有其他的,但這裡不多加說明。
當然也可以透過系統設計架構的方式去處理,只能說兩種方式都有。但要知道,有些情況下會有專職軟體來處理。