任務(wù)還活著嗎:用進(jìn)展租約區(qū)分卡住與依賴變慢)
一個(gè)任務(wù)每秒上報(bào)心跳十分鐘沒完成任何步驟。另一個(gè)任務(wù)正在等待供應(yīng)商生成視頻三分鐘沒有新輸出卻仍在預(yù)期時(shí)長(zhǎng)內(nèi)。只憑“幾秒沒動(dòng)靜就重啟”會(huì)把這兩種情況混在一起。活著、前進(jìn)、擁有寫權(quán)限我會(huì)分別記三件事heartbeat_at說明進(jìn)程仍能通信progress_at說明業(yè)務(wù)檢查點(diǎn)確實(shí)前進(jìn)generation決定誰(shuí)有權(quán)提交結(jié)果。心跳不能續(xù)期業(yè)務(wù)進(jìn)展日志刷屏也不能算完成步驟。Kubernetes 探針文檔區(qū)分啟動(dòng)、存活和就緒。它們是進(jìn)程管理背景不是業(yè)務(wù)任務(wù)完成度協(xié)議。任務(wù)層還需給各步驟定義正常等待區(qū)間例如“視頻供應(yīng)商處理中”和“結(jié)果已下載”是不同檢查點(diǎn)。接管必須讓舊 owner 失去提交資格下面用邏輯時(shí)間演示 fencing。它不是分布式租約實(shí)現(xiàn)真實(shí)系統(tǒng)要讓數(shù)據(jù)庫(kù)以條件更新原子地分配代次并在每次落庫(kù)時(shí)驗(yàn)證代次。class Task: def __init__(self): self.owner, self.gen, self.progress A, 1, 10 self.step 0 def take(self, new_owner, now, timeout): if now - self.progress timeout: return None self.owner, self.gen new_owner, self.gen 1 self.progress now return self.gen def commit(self, owner, gen, step, now): if (owner, gen) ! (self.owner, self.gen) or step self.step: return False self.step, self.progress step, now return True t Task() assert t.take(B, 15, 10) is None assert t.take(B, 30, 10) 2 assert not t.commit(A, 1, 1, 31) assert t.commit(B, 2, 1, 32) print(early takeover denied; stale owner fenced; new owner committed)本地 Python 3 執(zhí)行通過三項(xiàng)斷言沒有連接任務(wù)系統(tǒng)。這個(gè)實(shí)驗(yàn)把關(guān)鍵反例說清楚超時(shí)后舊進(jìn)程可能恢復(fù)如果存儲(chǔ)層不驗(yàn)代次它依然能覆蓋新結(jié)果。應(yīng)用里單獨(dú)檢查一次再寫入會(huì)留下競(jìng)爭(zhēng)窗口。慢依賴別用重啟“治療”每個(gè)檢查點(diǎn)保存預(yù)期工作、最后進(jìn)展證據(jù)和等待對(duì)象。超出觀察窗口先檢查供應(yīng)商任務(wù)狀態(tài)和本地積壓確認(rèn)需要接管后再撤銷舊代次、分配新 owner。外部扣款、視頻生成等副作用還要有穩(wěn)定冪等鍵否則 fencing 只能保護(hù)本地寫擋不住重復(fù)消費(fèi)。十月的視頻 Agent 熱點(diǎn)適合用這個(gè)框架審視但本文不虛構(gòu)某個(gè)平臺(tái)耗時(shí)或重啟收益。發(fā)布前應(yīng)補(bǔ)齊真實(shí)依賴的等待上限、取消能力及冪等合同未核實(shí)前“卡住”只是待驗(yàn)證假設(shè)。