Slack 自己幹的 Cron System

在 HN 上看到「Executing Cron Scripts Reliably at Scale (slack.engineering)」,發現是去年九月的文章:「Executing Cron Scripts Reliably At Scale」(話說 Slack 的 engineering blog 可讀性變差好多,不過這又是另外一回事了...)。

夠大的組織的 cron job system 都會自己幹一套出來用,因為檯面上的都不好用 XD

Slack 的搞法是組合三個內部系統:

  • 一個 container-based 管理實際執行資源的系統,基於 Bedrock,而 Bedrock 則是基於 k8s 上的系統。
  • 一個 job queue 子系統,後面是 Kafka + Redis 組成的。
  • 一組在 Vitess 上的表格,所以後面是 MySQL

這樣的系統也注定這是 Slack-only 的系統了,看一下知道用什麼就好了...

Amazon Aurora PostgreSQL 多支援了一些 extension

Amazon Aurora PostgreSQL 多支援了一些 extension,剛好看到一些對我還蠻有用的東西。

第一個是 pg_cron,就如同名字所說的,可以拿來安排 cron job:「Amazon Aurora PostgreSQL supports pg_cron extension for scheduling database jobs」。

第二個是 pg_proctab,可以拿來看系統狀態,這在 Aurora 裡面算是沒有 shell 的替代方案:「Amazon Aurora PostgreSQL Supports the pg_proctab Extension to access PostgreSQL system stats」。

第三個是 pg_partman,可以對 serial id 切到不同的 partition:「Amazon Aurora PostgreSQL supports the pg_partman extension for managing time or serial id based table partitioning」。

這幾個在一定的量下應該都用的到...

Cloudflare 推出 Cron Triggers

Cloudflare 推出了 Cron Triggers,有兩篇說明:「Introducing Cron Triggers for Cloudflare Workers」、「Making Time for Cron Triggers: A Look Inside」。

底層架構上是用 Nomad 做的:

To consume the schedules and actually trigger the Worker, we built a new service in Rust and deployed to our edge using HashiCorp Nomad. Nomad ensures that the schedule runner remains running in the edge node and can move it between machines as necessary.

多了定時跑程式的能力後,整個 serverless 平台的拼圖又多了一塊,現在看起來應該是要發展 storage 與 database-like 系統...

當程式沒問題時就會吃掉輸出的 chronic

跑 cron job 的時候,希望程式有問題的時候通知管理者 (或是執行者),這個可以透過 moreutils 內的 chronic 來達成:

chronic - runs a command quietly unless it fails

chronic 會將 stdout 與 stderr 的輸出結果暫存起來,如果程式正常結束 (exit 0) 就不管他,但如果有問題的時候就會 output 出來 (exit 不是 0,或是 crash),而 cron 在收到 stdout/stderr 有東西時,會寄信給管理者或是執行者,這剛好就是我們要的行為。

算是很好用的指令,沒事你不會想管他輸出什麼啊... XD

Ubuntu 上的 Cron (Vixie Cron 與 Cronie...)

想用 CRON_TZ 這個變數但發現系統不支援 XD

找資料的時候發現一堆奇怪的文章,像是說可以在 Ubuntu 上用 apt install cronie 這種指令安裝 cronie 的,不知道他到底是用什麼系統... (參考「Debian -- Package Search Results -- cronie」與「Ubuntu – Package Search Results -- cronie」,應該是沒出現過?)

在 man cron 時可以看到 Ubuntu 還是用 Vixie Cron,而在 Launchpad 上可以看到,在 2009 年有人提案想要換成 cronie,但一直都沒有下文:「Replace (vixie) cron with cronie」,這麼久完全沒動靜,這大概沒救了 XD

還是乖乖的照 UTC 設吧,只是這樣 Trac 開票的時間好像不太好搞...

Amazon ECS 可以跑 cron job 了...

Amazon ECS 上面固定時間跑某些東西,以前得自己用 AWS Lambda 帶 (或是自己架,不過這樣就要自己考慮 High Availability 架構了),現在則是直接支援:「Amazon ECS Now Supports Time and Event-Based Task Scheduling」。

Previously, you could start and stop Amazon ECS tasks manually, but running tasks on a schedule required writing and integrating an external scheduler with the Amazon ECS API.

Now you can schedule tasks through the Amazon ECS console on fixed time intervals (e.g.: number of minutes, hours, or days). Additionally, you can now set Amazon ECS as a CloudWatch Events target, allowing you to launch tasks by using CloudWatch Events.

AWS 的 scheduled events 可以設定為一分鐘一次了

Twitter 上看到 AWS 的 scheduled events 可以設定為一分鐘一次了:

在 AWS 的相關文件上也發現相關的限制都拿掉了:「Using AWS Lambda with Scheduled Events」。

實際測試也發現沒問題了,之前用 */1 會被擋下來,現在是 ok 的:

aws events put-rule --schedule-expression 'cron(*/1 * * * ? *)' --name test

cron 裡面的百分比符號 % 有特殊意義...

在試了一陣子後才發現的問題,crontab 裡的百分比符號 % 是特殊字元:「escaping double quotes and percent signs (%) in cron」。

取自 Debian 上的 crontab(5)

Percent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.

有點奇怪就是了,因為有 echo 可以用才對?

AWS Lambda 大躍進

AWS Lambda 丟出了一卡車超級基本的功能 (所以超級實用):「AWS Lambda Update – Python, VPC, Increased Function Duration, Scheduling, and More」。

首先是 AWS Lambda 可以跑在 VPC 裡了,這使得 Lambda 可以呼叫內部的 HTTP API 而不需要對 internet 打洞再用其他方式保護。

再來是 AWS Lambda 支援 Python 2.7 了,什麼?你問為什麼不是支援 Python 3?(頭轉過去)

然後可以跑 Cron 了!可以跑 Cron 了!可以跑 Cron 了!(很重要所以要說三次)