feat(GOV-008): 采用 RocketMQ 消息队列架构
This commit is contained in:
@@ -4,7 +4,7 @@ import test from 'node:test';
|
||||
|
||||
const repoRoot = new URL('../../', import.meta.url);
|
||||
const processNames = ['api', 'scheduler', 'worker', 'web'];
|
||||
const sensitiveKeyPattern = /(PASSWORD|API_KEY|TOKEN|SECRET|RABBITMQ_URL)$/;
|
||||
const sensitiveKeyPattern = /(PASSWORD|API_KEY|TOKEN|SECRET)$/;
|
||||
|
||||
async function readRepoFile(relativePath) {
|
||||
return readFile(new URL(relativePath, repoRoot), 'utf8');
|
||||
@@ -53,7 +53,21 @@ test('模板不包含敏感值且 Web 只暴露 VITE 变量', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('生产模板禁止模拟数据并保持 MySQL 5.7 配置契约', async () => {
|
||||
test('生产模板禁止模拟数据并保持 MySQL 5.7 与 RocketMQ 配置契约', async () => {
|
||||
const rocketMqTemplates = new Map();
|
||||
for (const environment of ['development', 'production']) {
|
||||
for (const processName of ['scheduler', 'worker']) {
|
||||
rocketMqTemplates.set(
|
||||
`${environment}/${processName}`,
|
||||
parseEnvTemplate(
|
||||
await readRepoFile(`deploy/env/${environment}/${processName}.env.example`),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
const developmentScheduler = rocketMqTemplates.get('development/scheduler');
|
||||
const developmentWorker = rocketMqTemplates.get('development/worker');
|
||||
const productionScheduler = rocketMqTemplates.get('production/scheduler');
|
||||
const worker = parseEnvTemplate(await readRepoFile('deploy/env/production/worker.env.example'));
|
||||
|
||||
assert.equal(worker.get('APP_ENV'), 'production');
|
||||
@@ -61,7 +75,27 @@ test('生产模板禁止模拟数据并保持 MySQL 5.7 配置契约', async ()
|
||||
assert.equal(worker.get('MYSQL_ENABLED'), 'false');
|
||||
assert.equal(worker.get('MYSQL_CHARSET'), 'utf8mb4');
|
||||
assert.equal(worker.get('MYSQL_COLLATION'), 'utf8mb4_general_ci');
|
||||
assert.equal(worker.get('RABBITMQ_ENABLED'), 'false');
|
||||
assert.equal(worker.get('ROCKETMQ_ENABLED'), 'false');
|
||||
assert.equal(worker.get('ROCKETMQ_ENDPOINT'), '');
|
||||
assert.equal(worker.get('ROCKETMQ_TOPIC_PREFIX'), 'a-share-analysis');
|
||||
assert.equal(worker.get('ROCKETMQ_CONSUMER_GROUP'), 'a-share-analysis-worker');
|
||||
for (const [templateName, entries] of rocketMqTemplates) {
|
||||
assert.equal(
|
||||
[...entries.keys()].some((key) => key.startsWith('RABBITMQ_')),
|
||||
false,
|
||||
`${templateName} 禁止保留 RabbitMQ 变量`,
|
||||
);
|
||||
assert.equal(entries.has('ROCKETMQ_PRODUCER_GROUP'), false);
|
||||
assert.equal(entries.has('ROCKETMQ_MAX_RECONSUME_TIMES'), false);
|
||||
}
|
||||
for (const entries of [developmentScheduler, developmentWorker]) {
|
||||
assert.equal(entries.get('ROCKETMQ_NAMESRV_ADDR'), '127.0.0.1:9876');
|
||||
assert.equal(entries.get('ROCKETMQ_ENDPOINT'), '127.0.0.1:8081');
|
||||
}
|
||||
for (const entries of [productionScheduler, worker]) {
|
||||
assert.equal(entries.get('ROCKETMQ_NAMESRV_ADDR'), '');
|
||||
assert.equal(entries.get('ROCKETMQ_ENDPOINT'), '');
|
||||
}
|
||||
});
|
||||
|
||||
test('本地 Compose 仅启动 Redis 并提供健康检查', async () => {
|
||||
@@ -70,7 +104,22 @@ test('本地 Compose 仅启动 Redis 并提供健康检查', async () => {
|
||||
assert.match(compose, /services:\s*\n\s+redis:/);
|
||||
assert.match(compose, /healthcheck:/);
|
||||
assert.match(compose, /127\.0\.0\.1:/);
|
||||
assert.doesNotMatch(compose, /^\s{2}(mysql|rabbitmq|api|worker|scheduler|web):/m);
|
||||
assert.doesNotMatch(compose, /^\s{2}(mysql|rocketmq|api|worker|scheduler|web):/m);
|
||||
});
|
||||
|
||||
test('活动架构与部署文档只采用 RocketMQ 5.x', async () => {
|
||||
for (const relativePath of [
|
||||
'README.md',
|
||||
'docs/architecture/system-architecture.md',
|
||||
'docs/governance/code-development-standards.md',
|
||||
'docs/deployment/local-development.md',
|
||||
'docs/deployment/docker-compose-production.md',
|
||||
'docs/deployment/ubuntu-source-production.md',
|
||||
]) {
|
||||
const content = await readRepoFile(relativePath);
|
||||
assert.match(content, /RocketMQ 5\.x|RocketMQ/);
|
||||
assert.doesNotMatch(content, /RabbitMQ/);
|
||||
}
|
||||
});
|
||||
|
||||
test('生产源码部署使用独立 EnvironmentFile 并提供 Nginx 代理', async () => {
|
||||
|
||||
Reference in New Issue
Block a user