我有一個運行Bull and express的作業服務器。
服務器要求
接收包含物件的請求并將該物件用作本地程式的輸入(別無選擇),該程式需要幾分鐘到幾個小時才能運行。作業必須按照收到的順序一個接一個地運行(不能繞開這個)。
TL;DR 服務器:
// Set up Bull queue and process
const osmQueue = new Bull("osm", {
redis: {
port: "6969",
},
});
osmQueue.process((job) => {
extractOms(job);
});
// Process function
const extractOms = (job) => {
// I have tried execSync also
spawnSync("programme", [
"this",
"programme",
"takes",
"~30",
"minutes",
"to",
"run",
"and",
"requires",
"full",
"system",
"resources (cannot share system resources with another job)",
]);
return
};
// Express server with single route
const app = express();
app.post("/create-map-job", (req, res) => {
console.log("fired"); // Fires on first request. Blocked on second until job done
osmQueue.add(req.body);
res.send("job successfully queued"); // Returns on first request. Blocked on second until job done
});
app.listen(PORT, () => {
console.log(`Listening on ${PORT}`);
});
問題:
- 當我將資料發送到這條路線時,一切都按預期作業。作業開始,我從服務器收到“作業成功排隊”。
- 當我第二次向服務器發送資料時(前一個作業仍在運行),路由中的 console.log 不會觸發,并且請求會掛起,直到現有作業完成。一旦現有作業完成,請求就會得到確認,并且下一個作業會排隊。
我嘗試過的事情:
使用 spawn() 而不是 spawnSync()。雖然這意味著請求不再被阻止,但這意味著所有作業都同時執行。我研究了 Bull 的并發性,但是當 child_process 像 spawn() 或 exec() 一樣異步時,一旦程式成功開始,作業就會被標記為完成 - 它不會等待 spawn() 完成。這意味著服務器認為該作業已完成并愉快地加載了另一個作業,并且我很快耗盡了記憶體并且系統崩潰了。我根本無法限制或控制記憶體使用量。如果我需要為每個行程提供更多記憶體,那么我一次只能運行 1 個
在 osmQueue.add() 之前簡單呼叫 res.send()。這對行為沒有任何改變。
在佇列中使用限制器:{max, duration} 選項。如果我將限制持續時間設定為 5 小時,這會起作用,但這會大大減少我一次可以做的作業量到無法接受的低水平。
我一直在閱讀并搜索了很長一段時間,但我找不到與我類似的問題。
問題:
- 為什么系統行程在執行 res.send() 之后會阻塞 node/express?
- 我應該使用另一個庫嗎?
- 非常感謝知情人士的任何見解。
讓我知道是否還有其他可以添加的內容,我會盡快完成。
TL;博士要求:
作為作業的一部分按順序執行系統行程,一個接一個地執行,而不會阻止服務器在現有作業運行時排隊更多作業或回應請求。
uj5u.com熱心網友回復:
解決了; 令人驚奇的是,完整地寫出一個問題可以激發大腦并讓您重新審視事物。留給未來的 Google 員工。
請參閱 Bull 檔案 > https://github.com/OptimalBits/bull#separate-processes
我需要呼叫 Bull 的獨立行程。這允許我在與 node/express 行程分開的行程中運行阻塞代碼,這意味著即使同步代碼正在運行,未來的請求也不會被阻塞。
// osm.processor.js
module.exports = extractOms (job) {
spawnSync("programme", [
"this",
"programme",
"takes",
"~30",
"minutes",
"to",
"run",
"and",
"requires",
"full",
"system",
"resources (cannot share system resources with another job)",
]);
return;
}
// queue.js
osmQueue.process(
"/path/to/file/above/job-server/processors/osm.processor.js"
);
這會在單獨的行程中產生阻塞作業。謝謝公牛!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/406251.html
標籤:
