feat(msg): 完整实现 msg 消息服务
包含 channels/preferences/templates/grpc/kafka/outbox/push/redis 等完整实现
This commit is contained in:
@@ -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 服务启动入口。
|
||||
*
|
||||
* 仲裁依据:
|
||||
* - M1:gRPC 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.onModuleInit:connectKafka + outboxPublisher.start
|
||||
* - KafkaConsumerService.onModuleInit:connectKafka + 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) => {
|
||||
|
||||
Reference in New Issue
Block a user