Я реализовал Redis и микросервис для запуска с интервалом в 1 час, используя cron. Иногда задания начинаются, иногда нет, и я не совсем уверен, почему это происходит.
У меня есть файл server.js
, который запускает мой бэкэнд rest api, файл queue.js
, который обрабатывает Queue
и файл rates.js
, который добавляет задания на сервер Queue
:
. js:
import express from "express";
import cors from "cors";
import morgan from "morgan";
import BullBoard from "bull-board";
import Queue from "./lib/Queue.js";
import routes from "./routes.js";
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// use morgan if in development
if (process.env.ENVIRONMENT === "development") app.use(morgan("dev"));
// starts the Bull Dashboard
BullBoard.setQueues(Queue.queues.map(queue => queue.bull));
app.use("/api", routes);
app.use("/admin/queues", BullBoard.UI);
app.listen(3333);
очередь. js:
import Queue from "./lib/Queue.js";
Queue.process();
норма. js:
import rateJobs from "./jobs/exchangeRates/addToQueue.js";
import Queue from "./lib/Queue.js";
// clean queues
Queue.empty("SetArgentinaRate");
Queue.empty("SetBtcPrice");
Queue.empty("SetBrazilRate");
Queue.empty("SetIndiaRate");
Queue.empty("SetSouthAfricaRate");
Queue.empty("SetVenezuelaRate");
// add job to check rates
Object.keys(rateJobs).forEach(job => job);
lib/Queue.js
импортирует все задания в один объект:
import Queue from "bull";
import redisConfig from "../config/redis.js";
import * as jobs from "../jobs/index.js";
const queues = Object.values(jobs).map(job => ({
bull: new Queue(job.key, { redis: redisConfig }),
name: job.key,
handle: job.handle,
options: job.options
}));
export default {
queues,
add(name, data) {
const queue = this.queues.find(queue => queue.name === name);
return queue.bull.add(data, queue.options);
},
empty(name) {
const queue = this.queues.find(queue => queue.name === name);
return queue.bull.empty();
},
process() {
return this.queues.forEach(queue => {
queue.bull.process(queue.handle);
});
}
};
Одно из заданий, т. Е. Для задания курс обмена:
import Currencies from "../../models/currencies.js";
import rp from "request-promise";
export default {
key: "SetArgentinaRate",
options: {
repeat: { cron: "0 * * * *" },
backoff: { type: "exponential", delay: 30000 },
attempts: 10
},
async handle() {
// Promise all to get btc price in dest country, spread and btc price
const [btcArs, { spread }, btc] = await Promise.all([
rp.get({
uri:
"https://localbitcoins.com/bitcoinaverage/ticker-all-currencies/",
json: true
}),
Currencies.findOne({ currency: "ARS" }).select("spread"),
Currencies.findOne({ currency: "BTC" }).select("exchange_rate")
]);
// calculate exchange rate
const exchange_rate = (
(btcArs.ARS.avg_1h / btc.exchange_rate) *
(1 - spread)
).toFixed(2);
// set exchange rate to database
await Currencies.findOneAndUpdate(
{ currency: "ARS" },
{
exchange_rate,
lastUpdate: Date.now(),
$push: {
history: {
date: Date.now(),
rate: exchange_rate
}
}
}
);
}
};
Вот пример codesandbox
: https://codesandbox.io/s/youthful-kapitsa-x5vyz Он не полностью функционален, потому что не запущен экземпляр Redis, но он такой же, как я
Когда задания запускаются, они выполняются без ошибок.
Я использую npm-run-all
, чтобы запустить 3 микросервиса параллельно:
"prod:server": "node --require dotenv/config src/server.js",
"prod:queue": "node --require dotenv/config src/queue.js",
"prod:rates": "node --require dotenv/config src/rates.js",
"start": "npm-run-all -p prod:*",
На локальном хосте, иногда работа начинается, иногда нет. На производстве они никогда не запускаются. Я не понимаю, почему.
Любая помощь приветствуется. Заранее спасибо!