feat(msg): 完整实现 msg 消息服务

包含 channels/preferences/templates/grpc/kafka/outbox/push/redis 等完整实现
This commit is contained in:
SpecialX
2026-07-10 19:09:52 +08:00
parent 21530dc7f6
commit 7b7abbb309
51 changed files with 5204 additions and 371 deletions

View File

@@ -5,11 +5,29 @@ import { GlobalErrorFilter } from "./shared/errors/global-error.filter.js";
import { initTracer, shutdownTracer } from "./shared/observability/tracer.js";
import { env } from "./config/env.js";
import { logger } from "./shared/observability/logger.js";
import { checkEsConnection, closeEs } from "./config/elasticsearch.js";
import { closeDb } from "./config/database.js";
import { checkEsConnection } from "./config/elasticsearch.js";
import { grpcMicroserviceOptions } from "./config/grpc.js";
import { metricsRegistry } from "./shared/observability/metrics.js";
import type { Request, Response } from "express";
/**
* msg 服务启动入口。
*
* 仲裁依据:
* - M1gRPC 50056 启用connectMicroservice
* - HTTP REST 3007 + gRPC 50056 双协议入口
* - enableShutdownHooks()NestJS 自动处理 SIGTERM/SIGINT → onApplicationShutdown
*
* 启动流程:
* 1. initTracers()OpenTelemetry 链路追踪
* 2. checkEsConnection()ES 探活(降级安全,不阻断启动)
* 3. NestFactory.create(AppModule):创建 app触发 onModuleInit
* - LifecycleService.onModuleInitconnectKafka + outboxPublisher.start
* - KafkaConsumerService.onModuleInitconnectKafka + consumer.run
* 4. connectMicroservice(grpcMicroserviceOptions):注册 gRPC 服务
* 5. startAllMicroservices():启动 gRPC 50056
* 6. listen(PORT):启动 HTTP REST 3007
*/
async function bootstrap(): Promise<void> {
initTracer();
@@ -23,32 +41,34 @@ async function bootstrap(): Promise<void> {
app.useGlobalFilters(new GlobalErrorFilter());
app.enableShutdownHooks();
// 注册 gRPC 微服务50056
app.connectMicroservice(grpcMicroserviceOptions);
// Prometheus 指标端点:不鉴权,供 Prometheus 抓取。
app.getHttpAdapter().get("/metrics", async (_req: Request, res: Response) => {
res.set("Content-Type", metricsRegistry.contentType);
res.end(await metricsRegistry.metrics());
});
// 启动 gRPC 微服务 + HTTP 服务
await app.startAllMicroservices();
await app.listen(env.PORT);
logger.info({ port: env.PORT }, "Msg service started");
process.on("SIGTERM", async () => {
logger.info("SIGTERM received, shutting down gracefully...");
logger.info(
{ httpPort: env.PORT, grpcPort: env.GRPC_PORT },
"Msg service started (HTTP + gRPC)",
);
// 兜底信号处理enableShutdownHooks 已处理 SIGTERM/SIGINT
// 此处仅确保进程退出(防止悬挂连接阻塞退出)。
const shutdown = async (signal: string): Promise<void> => {
logger.info({ signal }, "Shutting down gracefully...");
await app.close();
await closeEs();
await closeDb();
await shutdownTracer();
process.exit(0);
});
process.on("SIGINT", async () => {
logger.info("SIGINT received, shutting down gracefully...");
await app.close();
await closeEs();
await closeDb();
await shutdownTracer();
process.exit(0);
});
};
process.on("SIGTERM", () => void shutdown("SIGTERM"));
process.on("SIGINT", () => void shutdown("SIGINT"));
}
void bootstrap().catch((err: unknown) => {