[Feature request] 队列组件是否可以支持,指定队列进程数量 #4589
Replies: 4 comments 12 replies
|
可以,这个场景我理解下来不一定需要在 bullmq 组件里新增“指定队列进程数量”的配置,更适合用不同启动入口来区分进程角色。 BullMQ 本身是基于 Redis 的分布式队列,producer 和 consumer 不要求在同一个 Node 进程里。也就是说,同一套代码可以拆两个 Midway 入口:
一个简化例子如下。 // src/common/task.service.ts
import { Inject, Provide } from '@midwayjs/core';
import * as bullmq from '@midwayjs/bullmq';
@Provide()
export class TaskService {
@Inject()
bullmqFramework: bullmq.Framework;
async submit(data: any) {
const queue = this.bullmqFramework.getQueue('image-task')
?? this.bullmqFramework.createQueue('image-task');
return queue.addJobToQueue(data);
}
}// src/processor/image.processor.ts
import { Processor, IProcessor } from '@midwayjs/bullmq';
@Processor('image-task', {}, { concurrency: 2 })
export class ImageProcessor implements IProcessor {
async execute(data: any) {
// 这里只在 worker 入口加载时消费任务
}
}// src/api/configuration.ts
import { Configuration } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import * as bullmq from '@midwayjs/bullmq';
@Configuration({
imports: [koa, bullmq],
importConfigs: ['./config'],
})
export class ApiConfiguration {}// src/worker/configuration.ts
import { Configuration } from '@midwayjs/core';
import * as bullmq from '@midwayjs/bullmq';
import '../processor/image.processor';
@Configuration({
imports: [bullmq],
importConfigs: ['./config'],
})
export class WorkerConfiguration {}然后用两个 bootstrap 指到不同入口目录,例如: // bootstrap-api.js
const { join } = require('path');
const { Bootstrap } = require('@midwayjs/bootstrap');
Bootstrap.configure({
baseDir: join(__dirname, 'dist/api'),
}).run();// bootstrap-worker.js
const { join } = require('path');
const { Bootstrap } = require('@midwayjs/bootstrap');
Bootstrap.configure({
baseDir: join(__dirname, 'dist/worker'),
}).run();PM2 里可以配两组 app: module.exports = {
apps: [
{ name: 'api', script: './bootstrap-api.js', instances: 4 },
{ name: 'queue-worker', script: './bootstrap-worker.js', instances: 2 },
],
};这样 如果后续要补充能力,我觉得更适合补文档/示例,说明如何用多入口拆分 producer/consumer;组件层面未必需要按 PM2 进程数再做一层分配逻辑。 |
|
这个场景建议再拆一层来看:repeat job 的“注册/调度”和 Worker 的“消费”不是一回事。 BullMQ 里同一个队列可以有多个 Worker,单个 job 正常只会被其中一个 Worker 拿到执行,所以普通任务不需要担心多个 worker 同时执行同一条 job。但 Midway 现在通过 所以更稳的拆法是:
也就是说,不一定所有 repeat 任务都要单线程入口:如果只是避免重复触发,关键是 repeat 注册入口单实例;如果业务要求同一类 repeat 任务绝对串行,再把对应 queue 的消费也限制为单 worker / concurrency 1。后续如果加 producer-only 或 worker-enable 开关,也应该把这类 repeat 注册场景一起考虑进去。 |
|
这个现象大概率还是和多入口后的 Midway 里的 TypeORM 建议优先保持 API / worker 使用同一个编译后的应用根目录作为 如果一定要把入口拆到 |
|
这个判断是对的。当前实现里 短期建议不要从
这样虽然 API 入口仍需要
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The feature, motivation(功能、动机)
例如,我用pm2多进程部署,假设开启进程数为6,我希望4个进程仅启用koa组件监听端口,2个进程仅处理队列任务,以防止队列任务运行时阻塞http请求或者http请求阻塞队列任务;但是,koa组件还可以需要允许动态投递队列任务。是否可以对应配置。
Alternatives(替代方案)
No response
Additional context(其他上下文)
No response
All reactions