[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdeploy":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdeploy":2190,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdeploy":2216},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2186,"stem":2187,"id":2188,"extension":2189},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdeploy","部署与运维","生产环境：nest build 输出 dist，用进程管理器与反向代理部署。","技能小册",[12,13],"nestjs","deploy","2023-01-24",false,{"type":17,"value":18,"toc":2174},"minimark",[19,22,35,38,48,54,76,79,107,114,152,156,159,166,183,190,193,210,215,227,231,251,255,258,262,265,315,325,593,597,603,675,680,720,728,735,738,752,789,964,1461,1475,1480,1587,1591,1594,1598,1601,1605,1668,1673,1681,1735,1740,1744,1747,1755,1765,1769,1785,1843,1863,1867,1870,1874,1877,2017,2020,2109,2112,2116,2119,2170],[20,21,8],"h1",{"id":8},[23,24,25,26,30,31,34],"p",{},"生产环境：",[27,28,29],"code",{},"nest build"," 输出 ",[27,32,33],{},"dist","，用进程管理器与反向代理部署。",[23,36,37],{},"将 NestJS 应用部署到生产环境，不仅需要构建出优化后的产物，还需配置合适的运行参数、进程管理、健康检查、日志聚合和安全策略。以下是各个关键环节的最佳实践。",[39,40,42,43,30,45,47],"h3",{"id":41},"一构建nest-build-输出-dist-目录","一、构建：",[27,44,29],{},[27,46,33],{}," 目录",[23,49,50,51,53],{},"NestJS CLI 内置了打包功能，可将 TypeScript 编译为 JavaScript 并输出到 ",[27,52,33],{}," 目录。",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","nest build\n","bash","",[27,62,63],{"__ignoreMap":60},[64,65,68,72],"span",{"class":66,"line":67},"line",1,[64,69,71],{"class":70},"sbgvK","nest",[64,73,75],{"class":74},"s_sjI"," build\n",[23,77,78],{},"该命令会：",[80,81,82,94,100],"ul",{},[83,84,85,86,89,90,93],"li",{},"读取 ",[27,87,88],{},"tsconfig.json","（通常为 ",[27,91,92],{},"tsconfig.build.json","）编译项目。",[83,95,96,97,99],{},"将生成的 JS 文件输出到 ",[27,98,33],{}," 文件夹。",[83,101,102,103,106],{},"可选地支持 webpack 模式（",[27,104,105],{},"nest build --webpack","），用于微服务或部署包优化，但多数情况下默认配置即可。",[23,108,109,113],{},[110,111,112],"strong",{},"生产环境构建优化","：",[80,115,116,123,141],{},[83,117,118,119,122],{},"设置 ",[27,120,121],{},"NODE_ENV=production"," 环境变量，使某些依赖（如 TypeORM、Mongoose）使用生产配置。",[83,124,125,126,128,129,132,133,136,137,140],{},"确保 ",[27,127,92],{}," 中 ",[27,130,131],{},"compilerOptions.removeComments"," 和 ",[27,134,135],{},"declaration"," 选项按需设置（生产可移除注释，不生成 ",[27,138,139],{},".d.ts","）。",[83,142,143,144,147,148,151],{},"使用 ",[27,145,146],{},"--optimization"," 标志启用 webpack 的优化（如代码压缩、作用域提升等），但仅在使用了 ",[27,149,150],{},"--webpack"," 时才生效。",[39,153,155],{"id":154},"二生产环境-node-配置","二、生产环境 Node 配置",[23,157,158],{},"Node.js 运行时参数对稳定性和性能至关重要。",[160,161,163,164],"h4",{"id":162},"_1-node_envproduction","1. ",[27,165,121],{},[80,167,168],{},[83,169,170,171,174,175],{},"明确设置为 ",[27,172,173],{},"production","，使 NestJS 和第三方库（如 TypeORM、Express）启用生产模式：\n",[80,176,177,180],{},[83,178,179],{},"禁用调试日志、缓存模板、减少错误堆栈细节。",[83,181,182],{},"某些库会进行性能优化（如连接池调优）。",[160,184,186,187],{"id":185},"_2-内存限制-max-old-space-size","2. 内存限制：",[27,188,189],{},"--max-old-space-size",[23,191,192],{},"Node.js 默认内存限制约为 1.4GB（64位系统），对于大型应用可能不足。可通过参数调整老生代内存大小：",[55,194,196],{"className":57,"code":195,"language":59,"meta":60,"style":60},"node --max-old-space-size=2048 dist\u002Fmain.js\n",[27,197,198],{"__ignoreMap":60},[64,199,200,203,207],{"class":66,"line":67},[64,201,202],{"class":70},"node",[64,204,206],{"class":205},"stzsN"," --max-old-space-size=2048",[64,208,209],{"class":74}," dist\u002Fmain.js\n",[23,211,212,113],{},[110,213,214],{},"建议",[80,216,217,220],{},[83,218,219],{},"根据服务器可用内存和应用负载设置，通常设置为服务器内存的 70%~80%，避免 OOM Killer 介入。",[83,221,222,223,226],{},"在容器环境（Docker\u002FK8s）中，应将此值与容器内存限制（",[27,224,225],{},"memory limit","）匹配，预留一部分给其他进程。",[160,228,230],{"id":229},"_3-其他有用标志","3. 其他有用标志",[80,232,233,239,245],{},[83,234,235,238],{},[27,236,237],{},"--enable-source-maps","：生产环境启用源码映射，便于错误堆栈定位（需确保 source map 文件不被泄露）。",[83,240,241,244],{},[27,242,243],{},"--trace-warnings","：跟踪警告来源，辅助排查潜在问题。",[83,246,247,250],{},[27,248,249],{},"--max-http-header-size","：若客户端发送较大头部，可适当增加默认 16KB 限制。",[39,252,254],{"id":253},"三进程管理","三、进程管理",[23,256,257],{},"保证 Node.js 进程在崩溃后自动重启、多核服务器负载均衡。",[160,259,261],{"id":260},"_1-pm2常用进程管理器","1. PM2（常用进程管理器）",[23,263,264],{},"安装并启动：",[55,266,268],{"className":57,"code":267,"language":59,"meta":60,"style":60},"npm install -g pm2\npm2 start dist\u002Fmain.js --name my-app --instances 2 --max-memory-restart 500M\n",[27,269,270,284],{"__ignoreMap":60},[64,271,272,275,278,281],{"class":66,"line":67},[64,273,274],{"class":70},"npm",[64,276,277],{"class":74}," install",[64,279,280],{"class":205}," -g",[64,282,283],{"class":74}," pm2\n",[64,285,287,290,293,296,299,302,305,309,312],{"class":66,"line":286},2,[64,288,289],{"class":70},"pm2",[64,291,292],{"class":74}," start",[64,294,295],{"class":74}," dist\u002Fmain.js",[64,297,298],{"class":205}," --name",[64,300,301],{"class":74}," my-app",[64,303,304],{"class":205}," --instances",[64,306,308],{"class":307},"srdBf"," 2",[64,310,311],{"class":205}," --max-memory-restart",[64,313,314],{"class":74}," 500M\n",[23,316,317,320,321,324],{},[110,318,319],{},"常用配置","（",[27,322,323],{},"ecosystem.config.js","）：",[55,326,330],{"className":327,"code":328,"language":329,"meta":60,"style":60},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","module.exports = {\n  apps: [\n    {\n      name: \"nest-app\",\n      script: \"dist\u002Fmain.js\",\n      instances: \"max\", \u002F\u002F 启用所有 CPU 核心\n      exec_mode: \"cluster\", \u002F\u002F 集群模式\n      max_memory_restart: \"1G\",\n      env: { NODE_ENV: \"production\" },\n      error_file: \".\u002Flogs\u002Ferr.log\",\n      out_file: \".\u002Flogs\u002Fout.log\",\n      merge_logs: true,\n      kill_timeout: 5000, \u002F\u002F 强制杀死前等待时间（秒）\n      listen_timeout: 3000, \u002F\u002F 应用监听超时\n    },\n  ],\n};\n","js",[27,331,332,352,365,371,392,409,431,451,468,493,510,527,541,557,573,579,587],{"__ignoreMap":60},[64,333,334,338,342,345,349],{"class":66,"line":67},[64,335,337],{"class":336},"s39Yj","module",[64,339,341],{"class":340},"sP7_E",".",[64,343,344],{"class":336},"exports",[64,346,348],{"class":347},"smGrS"," =",[64,350,351],{"class":340}," {\n",[64,353,354,358,361],{"class":66,"line":286},[64,355,357],{"class":356},"skxfh","  apps",[64,359,360],{"class":340},":",[64,362,364],{"class":363},"su5hD"," [\n",[64,366,368],{"class":66,"line":367},3,[64,369,370],{"class":340},"    {\n",[64,372,374,377,379,383,386,389],{"class":66,"line":373},4,[64,375,376],{"class":356},"      name",[64,378,360],{"class":340},[64,380,382],{"class":381},"sjJ54"," \"",[64,384,385],{"class":74},"nest-app",[64,387,388],{"class":381},"\"",[64,390,391],{"class":340},",\n",[64,393,395,398,400,402,405,407],{"class":66,"line":394},5,[64,396,397],{"class":356},"      script",[64,399,360],{"class":340},[64,401,382],{"class":381},[64,403,404],{"class":74},"dist\u002Fmain.js",[64,406,388],{"class":381},[64,408,391],{"class":340},[64,410,412,415,417,419,422,424,427],{"class":66,"line":411},6,[64,413,414],{"class":356},"      instances",[64,416,360],{"class":340},[64,418,382],{"class":381},[64,420,421],{"class":74},"max",[64,423,388],{"class":381},[64,425,426],{"class":340},",",[64,428,430],{"class":429},"sutJx"," \u002F\u002F 启用所有 CPU 核心\n",[64,432,434,437,439,441,444,446,448],{"class":66,"line":433},7,[64,435,436],{"class":356},"      exec_mode",[64,438,360],{"class":340},[64,440,382],{"class":381},[64,442,443],{"class":74},"cluster",[64,445,388],{"class":381},[64,447,426],{"class":340},[64,449,450],{"class":429}," \u002F\u002F 集群模式\n",[64,452,454,457,459,461,464,466],{"class":66,"line":453},8,[64,455,456],{"class":356},"      max_memory_restart",[64,458,360],{"class":340},[64,460,382],{"class":381},[64,462,463],{"class":74},"1G",[64,465,388],{"class":381},[64,467,391],{"class":340},[64,469,471,474,476,479,482,484,486,488,490],{"class":66,"line":470},9,[64,472,473],{"class":356},"      env",[64,475,360],{"class":340},[64,477,478],{"class":340}," {",[64,480,481],{"class":356}," NODE_ENV",[64,483,360],{"class":340},[64,485,382],{"class":381},[64,487,173],{"class":74},[64,489,388],{"class":381},[64,491,492],{"class":340}," },\n",[64,494,496,499,501,503,506,508],{"class":66,"line":495},10,[64,497,498],{"class":356},"      error_file",[64,500,360],{"class":340},[64,502,382],{"class":381},[64,504,505],{"class":74},".\u002Flogs\u002Ferr.log",[64,507,388],{"class":381},[64,509,391],{"class":340},[64,511,513,516,518,520,523,525],{"class":66,"line":512},11,[64,514,515],{"class":356},"      out_file",[64,517,360],{"class":340},[64,519,382],{"class":381},[64,521,522],{"class":74},".\u002Flogs\u002Fout.log",[64,524,388],{"class":381},[64,526,391],{"class":340},[64,528,530,533,535,539],{"class":66,"line":529},12,[64,531,532],{"class":356},"      merge_logs",[64,534,360],{"class":340},[64,536,538],{"class":537},"syTEX"," true",[64,540,391],{"class":340},[64,542,544,547,549,552,554],{"class":66,"line":543},13,[64,545,546],{"class":356},"      kill_timeout",[64,548,360],{"class":340},[64,550,551],{"class":307}," 5000",[64,553,426],{"class":340},[64,555,556],{"class":429}," \u002F\u002F 强制杀死前等待时间（秒）\n",[64,558,560,563,565,568,570],{"class":66,"line":559},14,[64,561,562],{"class":356},"      listen_timeout",[64,564,360],{"class":340},[64,566,567],{"class":307}," 3000",[64,569,426],{"class":340},[64,571,572],{"class":429}," \u002F\u002F 应用监听超时\n",[64,574,576],{"class":66,"line":575},15,[64,577,578],{"class":340},"    },\n",[64,580,582,585],{"class":66,"line":581},16,[64,583,584],{"class":363},"  ]",[64,586,391],{"class":340},[64,588,590],{"class":66,"line":589},17,[64,591,592],{"class":340},"};\n",[160,594,596],{"id":595},"_2-docker-kubernetes容器化","2. Docker + Kubernetes（容器化）",[23,598,599,602],{},[110,600,601],{},"Dockerfile 示例","（多阶段构建，保证镜像小）：",[55,604,608],{"className":605,"code":606,"language":607,"meta":60,"style":60},"language-dockerfile shiki shiki-themes material-theme-lighter github-light github-dark","FROM node:20-alpine AS builder\nWORKDIR \u002Fapp\nCOPY package*.json .\u002F\nRUN npm ci --only=production && npm cache clean --force\nCOPY . .\nRUN npm run build\n\nFROM node:20-alpine\nWORKDIR \u002Fapp\nCOPY --from=builder \u002Fapp\u002Fdist .\u002Fdist\nCOPY --from=builder \u002Fapp\u002Fnode_modules .\u002Fnode_modules\nEXPOSE 3000\nCMD [\"node\", \"--max-old-space-size=512\", \"dist\u002Fmain.js\"]\n","dockerfile",[27,609,610,615,620,625,630,635,640,646,651,655,660,665,670],{"__ignoreMap":60},[64,611,612],{"class":66,"line":67},[64,613,614],{},"FROM node:20-alpine AS builder\n",[64,616,617],{"class":66,"line":286},[64,618,619],{},"WORKDIR \u002Fapp\n",[64,621,622],{"class":66,"line":367},[64,623,624],{},"COPY package*.json .\u002F\n",[64,626,627],{"class":66,"line":373},[64,628,629],{},"RUN npm ci --only=production && npm cache clean --force\n",[64,631,632],{"class":66,"line":394},[64,633,634],{},"COPY . .\n",[64,636,637],{"class":66,"line":411},[64,638,639],{},"RUN npm run build\n",[64,641,642],{"class":66,"line":433},[64,643,645],{"emptyLinePlaceholder":644},true,"\n",[64,647,648],{"class":66,"line":453},[64,649,650],{},"FROM node:20-alpine\n",[64,652,653],{"class":66,"line":470},[64,654,619],{},[64,656,657],{"class":66,"line":495},[64,658,659],{},"COPY --from=builder \u002Fapp\u002Fdist .\u002Fdist\n",[64,661,662],{"class":66,"line":512},[64,663,664],{},"COPY --from=builder \u002Fapp\u002Fnode_modules .\u002Fnode_modules\n",[64,666,667],{"class":66,"line":529},[64,668,669],{},"EXPOSE 3000\n",[64,671,672],{"class":66,"line":543},[64,673,674],{},"CMD [\"node\", \"--max-old-space-size=512\", \"dist\u002Fmain.js\"]\n",[23,676,677,113],{},[110,678,679],{},"Kubernetes 部署关键点",[80,681,682,692,702,711],{},[83,683,118,684,687,688,691],{},[27,685,686],{},"Deployment"," 的 ",[27,689,690],{},"replicas"," 数量（水平扩展）。",[83,693,694,695,132,698,701],{},"添加 ",[27,696,697],{},"livenessProbe",[27,699,700],{},"readinessProbe","（利用健康检查端点）。",[83,703,143,704,132,707,710],{},[27,705,706],{},"ConfigMap",[27,708,709],{},"Secret"," 管理环境变量。",[83,712,118,713,716,717,719],{},[27,714,715],{},"resources.limits.memory","，配合 ",[27,718,189],{}," 预留内存。",[39,721,723,724,727],{"id":722},"四健康检查nestjsterminus-模块","四、健康检查：",[27,725,726],{},"@nestjs\u002Fterminus"," 模块",[23,729,730,731,734],{},"NestJS 官方提供的 ",[27,732,733],{},"Terminus"," 模块可以方便地集成健康检查端点，用于容器探针或负载均衡监控。",[23,736,737],{},"安装：",[55,739,741],{"className":57,"code":740,"language":59,"meta":60,"style":60},"npm install @nestjs\u002Fterminus\n",[27,742,743],{"__ignoreMap":60},[64,744,745,747,749],{"class":66,"line":67},[64,746,274],{"class":70},[64,748,277],{"class":74},[64,750,751],{"class":74}," @nestjs\u002Fterminus\n",[23,753,754,756,757,756,760,763,764,767,768,771,772,320,775,778,779,778,782,778,785,788],{},[27,755,726],{}," ",[110,758,759],{},"没有",[27,761,762],{},"TerminusModule.forRoot({ healthChecks: {...} })"," 这种配置式 API；正确用法是把 ",[27,765,766],{},"TerminusModule"," 直接导入模块，再用 ",[27,769,770],{},"HealthCheckService"," + 各类 ",[27,773,774],{},"HealthIndicator",[27,776,777],{},"HttpHealthIndicator","、",[27,780,781],{},"TypeOrmHealthIndicator",[27,783,784],{},"MemoryHealthIndicator",[27,786,787],{},"DiskHealthIndicator"," 等）在控制器中组合检查项：",[55,790,794],{"className":791,"code":792,"language":793,"meta":60,"style":60},"language-typescript shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F health.module.ts\nimport { Module } from \"@nestjs\u002Fcommon\";\nimport { TerminusModule } from \"@nestjs\u002Fterminus\";\nimport { HttpModule } from \"@nestjs\u002Faxios\";\nimport { HealthController } from \".\u002Fhealth.controller\";\n\n@Module({\n  imports: [TerminusModule, HttpModule],\n  controllers: [HealthController],\n})\nexport class HealthModule {}\n","typescript",[27,795,796,801,828,849,871,893,897,912,929,941,949],{"__ignoreMap":60},[64,797,798],{"class":66,"line":67},[64,799,800],{"class":429},"\u002F\u002F health.module.ts\n",[64,802,803,807,809,812,815,818,820,823,825],{"class":66,"line":286},[64,804,806],{"class":805},"sVHd0","import",[64,808,478],{"class":340},[64,810,811],{"class":363}," Module",[64,813,814],{"class":340}," }",[64,816,817],{"class":805}," from",[64,819,382],{"class":381},[64,821,822],{"class":74},"@nestjs\u002Fcommon",[64,824,388],{"class":381},[64,826,827],{"class":340},";\n",[64,829,830,832,834,837,839,841,843,845,847],{"class":66,"line":367},[64,831,806],{"class":805},[64,833,478],{"class":340},[64,835,836],{"class":363}," TerminusModule",[64,838,814],{"class":340},[64,840,817],{"class":805},[64,842,382],{"class":381},[64,844,726],{"class":74},[64,846,388],{"class":381},[64,848,827],{"class":340},[64,850,851,853,855,858,860,862,864,867,869],{"class":66,"line":373},[64,852,806],{"class":805},[64,854,478],{"class":340},[64,856,857],{"class":363}," HttpModule",[64,859,814],{"class":340},[64,861,817],{"class":805},[64,863,382],{"class":381},[64,865,866],{"class":74},"@nestjs\u002Faxios",[64,868,388],{"class":381},[64,870,827],{"class":340},[64,872,873,875,877,880,882,884,886,889,891],{"class":66,"line":394},[64,874,806],{"class":805},[64,876,478],{"class":340},[64,878,879],{"class":363}," HealthController",[64,881,814],{"class":340},[64,883,817],{"class":805},[64,885,382],{"class":381},[64,887,888],{"class":74},".\u002Fhealth.controller",[64,890,388],{"class":381},[64,892,827],{"class":340},[64,894,895],{"class":66,"line":411},[64,896,645],{"emptyLinePlaceholder":644},[64,898,899,902,906,909],{"class":66,"line":433},[64,900,901],{"class":340},"@",[64,903,905],{"class":904},"sGLFI","Module",[64,907,908],{"class":363},"(",[64,910,911],{"class":340},"{\n",[64,913,914,917,919,922,924,927],{"class":66,"line":453},[64,915,916],{"class":356},"  imports",[64,918,360],{"class":340},[64,920,921],{"class":363}," [TerminusModule",[64,923,426],{"class":340},[64,925,926],{"class":363}," HttpModule]",[64,928,391],{"class":340},[64,930,931,934,936,939],{"class":66,"line":470},[64,932,933],{"class":356},"  controllers",[64,935,360],{"class":340},[64,937,938],{"class":363}," [HealthController]",[64,940,391],{"class":340},[64,942,943,946],{"class":66,"line":495},[64,944,945],{"class":340},"}",[64,947,948],{"class":363},")\n",[64,950,951,954,958,961],{"class":66,"line":512},[64,952,953],{"class":805},"export",[64,955,957],{"class":956},"sbsja"," class",[64,959,960],{"class":70}," HealthModule",[64,962,963],{"class":340}," {}\n",[55,965,967],{"className":791,"code":966,"language":793,"meta":60,"style":60},"\u002F\u002F health.controller.ts\nimport { Controller, Get } from \"@nestjs\u002Fcommon\";\nimport {\n  HealthCheckService,\n  HealthCheck,\n  HttpHealthIndicator,\n  TypeOrmHealthIndicator,\n  MemoryHealthIndicator,\n} from \"@nestjs\u002Fterminus\";\n\n@Controller(\"health\")\nexport class HealthController {\n  constructor(\n    private health: HealthCheckService,\n    private http: HttpHealthIndicator,\n    private db: TypeOrmHealthIndicator,\n    private memory: MemoryHealthIndicator,\n  ) {}\n\n  \u002F\u002F 就绪探针：检查依赖（数据库、下游服务等）是否可用\n  @Get(\"readiness\")\n  @HealthCheck()\n  readiness() {\n    return this.health.check([\n      () => this.db.pingCheck(\"database\", { timeout: 1500 }),\n      () => this.http.pingCheck(\"downstream-api\", \"https:\u002F\u002Fapi.example.com\u002Fping\"),\n    ]);\n  }\n\n  \u002F\u002F 存活探针：只做轻量自检，不依赖外部服务\n  @Get(\"liveness\")\n  @HealthCheck()\n  liveness() {\n    return this.health.check([() => this.memory.checkHeap(\"memory_heap\", 300 * 1024 * 1024)]);\n  }\n}\n",[27,968,969,974,1000,1006,1013,1020,1027,1034,1041,1055,1059,1077,1087,1095,1111,1125,1139,1153,1161,1166,1172,1192,1203,1215,1236,1285,1325,1333,1339,1344,1350,1368,1377,1387,1450,1455],{"__ignoreMap":60},[64,970,971],{"class":66,"line":67},[64,972,973],{"class":429},"\u002F\u002F health.controller.ts\n",[64,975,976,978,980,983,985,988,990,992,994,996,998],{"class":66,"line":286},[64,977,806],{"class":805},[64,979,478],{"class":340},[64,981,982],{"class":363}," Controller",[64,984,426],{"class":340},[64,986,987],{"class":363}," Get",[64,989,814],{"class":340},[64,991,817],{"class":805},[64,993,382],{"class":381},[64,995,822],{"class":74},[64,997,388],{"class":381},[64,999,827],{"class":340},[64,1001,1002,1004],{"class":66,"line":367},[64,1003,806],{"class":805},[64,1005,351],{"class":340},[64,1007,1008,1011],{"class":66,"line":373},[64,1009,1010],{"class":363},"  HealthCheckService",[64,1012,391],{"class":340},[64,1014,1015,1018],{"class":66,"line":394},[64,1016,1017],{"class":363},"  HealthCheck",[64,1019,391],{"class":340},[64,1021,1022,1025],{"class":66,"line":411},[64,1023,1024],{"class":363},"  HttpHealthIndicator",[64,1026,391],{"class":340},[64,1028,1029,1032],{"class":66,"line":433},[64,1030,1031],{"class":363},"  TypeOrmHealthIndicator",[64,1033,391],{"class":340},[64,1035,1036,1039],{"class":66,"line":453},[64,1037,1038],{"class":363},"  MemoryHealthIndicator",[64,1040,391],{"class":340},[64,1042,1043,1045,1047,1049,1051,1053],{"class":66,"line":470},[64,1044,945],{"class":340},[64,1046,817],{"class":805},[64,1048,382],{"class":381},[64,1050,726],{"class":74},[64,1052,388],{"class":381},[64,1054,827],{"class":340},[64,1056,1057],{"class":66,"line":495},[64,1058,645],{"emptyLinePlaceholder":644},[64,1060,1061,1063,1066,1068,1070,1073,1075],{"class":66,"line":512},[64,1062,901],{"class":340},[64,1064,1065],{"class":904},"Controller",[64,1067,908],{"class":363},[64,1069,388],{"class":381},[64,1071,1072],{"class":74},"health",[64,1074,388],{"class":381},[64,1076,948],{"class":363},[64,1078,1079,1081,1083,1085],{"class":66,"line":529},[64,1080,953],{"class":805},[64,1082,957],{"class":956},[64,1084,879],{"class":70},[64,1086,351],{"class":340},[64,1088,1089,1092],{"class":66,"line":543},[64,1090,1091],{"class":956},"  constructor",[64,1093,1094],{"class":340},"(\n",[64,1096,1097,1100,1104,1106,1109],{"class":66,"line":559},[64,1098,1099],{"class":956},"    private",[64,1101,1103],{"class":1102},"s99_P"," health",[64,1105,360],{"class":347},[64,1107,1108],{"class":70}," HealthCheckService",[64,1110,391],{"class":340},[64,1112,1113,1115,1118,1120,1123],{"class":66,"line":575},[64,1114,1099],{"class":956},[64,1116,1117],{"class":1102}," http",[64,1119,360],{"class":347},[64,1121,1122],{"class":70}," HttpHealthIndicator",[64,1124,391],{"class":340},[64,1126,1127,1129,1132,1134,1137],{"class":66,"line":581},[64,1128,1099],{"class":956},[64,1130,1131],{"class":1102}," db",[64,1133,360],{"class":347},[64,1135,1136],{"class":70}," TypeOrmHealthIndicator",[64,1138,391],{"class":340},[64,1140,1141,1143,1146,1148,1151],{"class":66,"line":589},[64,1142,1099],{"class":956},[64,1144,1145],{"class":1102}," memory",[64,1147,360],{"class":347},[64,1149,1150],{"class":70}," MemoryHealthIndicator",[64,1152,391],{"class":340},[64,1154,1156,1159],{"class":66,"line":1155},18,[64,1157,1158],{"class":340},"  )",[64,1160,963],{"class":340},[64,1162,1164],{"class":66,"line":1163},19,[64,1165,645],{"emptyLinePlaceholder":644},[64,1167,1169],{"class":66,"line":1168},20,[64,1170,1171],{"class":429},"  \u002F\u002F 就绪探针：检查依赖（数据库、下游服务等）是否可用\n",[64,1173,1175,1178,1181,1183,1185,1188,1190],{"class":66,"line":1174},21,[64,1176,1177],{"class":340},"  @",[64,1179,1180],{"class":904},"Get",[64,1182,908],{"class":363},[64,1184,388],{"class":381},[64,1186,1187],{"class":74},"readiness",[64,1189,388],{"class":381},[64,1191,948],{"class":363},[64,1193,1195,1197,1200],{"class":66,"line":1194},22,[64,1196,1177],{"class":340},[64,1198,1199],{"class":904},"HealthCheck",[64,1201,1202],{"class":363},"()\n",[64,1204,1206,1210,1213],{"class":66,"line":1205},23,[64,1207,1209],{"class":1208},"sVXei","  readiness",[64,1211,1212],{"class":340},"()",[64,1214,351],{"class":340},[64,1216,1218,1221,1224,1226,1228,1230,1233],{"class":66,"line":1217},24,[64,1219,1220],{"class":805},"    return",[64,1222,1223],{"class":336}," this",[64,1225,341],{"class":340},[64,1227,1072],{"class":363},[64,1229,341],{"class":340},[64,1231,1232],{"class":904},"check",[64,1234,1235],{"class":356},"([\n",[64,1237,1239,1242,1245,1247,1249,1252,1254,1257,1259,1261,1264,1266,1268,1270,1273,1275,1278,1280,1283],{"class":66,"line":1238},25,[64,1240,1241],{"class":340},"      ()",[64,1243,1244],{"class":956}," =>",[64,1246,1223],{"class":336},[64,1248,341],{"class":340},[64,1250,1251],{"class":363},"db",[64,1253,341],{"class":340},[64,1255,1256],{"class":904},"pingCheck",[64,1258,908],{"class":356},[64,1260,388],{"class":381},[64,1262,1263],{"class":74},"database",[64,1265,388],{"class":381},[64,1267,426],{"class":340},[64,1269,478],{"class":340},[64,1271,1272],{"class":356}," timeout",[64,1274,360],{"class":340},[64,1276,1277],{"class":307}," 1500",[64,1279,814],{"class":340},[64,1281,1282],{"class":356},")",[64,1284,391],{"class":340},[64,1286,1288,1290,1292,1294,1296,1299,1301,1303,1305,1307,1310,1312,1314,1316,1319,1321,1323],{"class":66,"line":1287},26,[64,1289,1241],{"class":340},[64,1291,1244],{"class":956},[64,1293,1223],{"class":336},[64,1295,341],{"class":340},[64,1297,1298],{"class":363},"http",[64,1300,341],{"class":340},[64,1302,1256],{"class":904},[64,1304,908],{"class":356},[64,1306,388],{"class":381},[64,1308,1309],{"class":74},"downstream-api",[64,1311,388],{"class":381},[64,1313,426],{"class":340},[64,1315,382],{"class":381},[64,1317,1318],{"class":74},"https:\u002F\u002Fapi.example.com\u002Fping",[64,1320,388],{"class":381},[64,1322,1282],{"class":356},[64,1324,391],{"class":340},[64,1326,1328,1331],{"class":66,"line":1327},27,[64,1329,1330],{"class":356},"    ])",[64,1332,827],{"class":340},[64,1334,1336],{"class":66,"line":1335},28,[64,1337,1338],{"class":340},"  }\n",[64,1340,1342],{"class":66,"line":1341},29,[64,1343,645],{"emptyLinePlaceholder":644},[64,1345,1347],{"class":66,"line":1346},30,[64,1348,1349],{"class":429},"  \u002F\u002F 存活探针：只做轻量自检，不依赖外部服务\n",[64,1351,1353,1355,1357,1359,1361,1364,1366],{"class":66,"line":1352},31,[64,1354,1177],{"class":340},[64,1356,1180],{"class":904},[64,1358,908],{"class":363},[64,1360,388],{"class":381},[64,1362,1363],{"class":74},"liveness",[64,1365,388],{"class":381},[64,1367,948],{"class":363},[64,1369,1371,1373,1375],{"class":66,"line":1370},32,[64,1372,1177],{"class":340},[64,1374,1199],{"class":904},[64,1376,1202],{"class":363},[64,1378,1380,1383,1385],{"class":66,"line":1379},33,[64,1381,1382],{"class":1208},"  liveness",[64,1384,1212],{"class":340},[64,1386,351],{"class":340},[64,1388,1390,1392,1394,1396,1398,1400,1402,1405,1407,1409,1411,1413,1416,1418,1421,1423,1425,1428,1430,1432,1435,1438,1441,1443,1445,1448],{"class":66,"line":1389},34,[64,1391,1220],{"class":805},[64,1393,1223],{"class":336},[64,1395,341],{"class":340},[64,1397,1072],{"class":363},[64,1399,341],{"class":340},[64,1401,1232],{"class":904},[64,1403,1404],{"class":356},"([",[64,1406,1212],{"class":340},[64,1408,1244],{"class":956},[64,1410,1223],{"class":336},[64,1412,341],{"class":340},[64,1414,1415],{"class":363},"memory",[64,1417,341],{"class":340},[64,1419,1420],{"class":904},"checkHeap",[64,1422,908],{"class":356},[64,1424,388],{"class":381},[64,1426,1427],{"class":74},"memory_heap",[64,1429,388],{"class":381},[64,1431,426],{"class":340},[64,1433,1434],{"class":307}," 300",[64,1436,1437],{"class":347}," *",[64,1439,1440],{"class":307}," 1024",[64,1442,1437],{"class":347},[64,1444,1440],{"class":307},[64,1446,1447],{"class":356},")])",[64,1449,827],{"class":340},[64,1451,1453],{"class":66,"line":1452},35,[64,1454,1338],{"class":340},[64,1456,1458],{"class":66,"line":1457},36,[64,1459,1460],{"class":340},"}\n",[23,1462,1463,1466,1467,1470,1471,1474],{},[27,1464,1465],{},"@HealthCheck()"," 会让路由返回标准的 Terminus 响应格式：所有检查通过时状态码 ",[27,1468,1469],{},"200","，任一检查失败则为 ",[27,1472,1473],{},"503","。",[23,1476,1477,113],{},[110,1478,1479],{},"在 Kubernetes 中使用",[55,1481,1485],{"className":1482,"code":1483,"language":1484,"meta":60,"style":60},"language-yaml shiki shiki-themes material-theme-lighter github-light github-dark","livenessProbe:\n  httpGet:\n    path: \u002Fhealth\u002Fliveness\n    port: 3000\n  initialDelaySeconds: 10\n  periodSeconds: 10\nreadinessProbe:\n  httpGet:\n    path: \u002Fhealth\u002Freadiness\n    port: 3000\n  initialDelaySeconds: 5\n  periodSeconds: 5\n","yaml",[27,1486,1487,1495,1502,1512,1522,1532,1541,1547,1553,1562,1570,1579],{"__ignoreMap":60},[64,1488,1489,1492],{"class":66,"line":67},[64,1490,697],{"class":1491},"sQzsp",[64,1493,1494],{"class":340},":\n",[64,1496,1497,1500],{"class":66,"line":286},[64,1498,1499],{"class":1491},"  httpGet",[64,1501,1494],{"class":340},[64,1503,1504,1507,1509],{"class":66,"line":367},[64,1505,1506],{"class":1491},"    path",[64,1508,360],{"class":340},[64,1510,1511],{"class":74}," \u002Fhealth\u002Fliveness\n",[64,1513,1514,1517,1519],{"class":66,"line":373},[64,1515,1516],{"class":1491},"    port",[64,1518,360],{"class":340},[64,1520,1521],{"class":307}," 3000\n",[64,1523,1524,1527,1529],{"class":66,"line":394},[64,1525,1526],{"class":1491},"  initialDelaySeconds",[64,1528,360],{"class":340},[64,1530,1531],{"class":307}," 10\n",[64,1533,1534,1537,1539],{"class":66,"line":411},[64,1535,1536],{"class":1491},"  periodSeconds",[64,1538,360],{"class":340},[64,1540,1531],{"class":307},[64,1542,1543,1545],{"class":66,"line":433},[64,1544,700],{"class":1491},[64,1546,1494],{"class":340},[64,1548,1549,1551],{"class":66,"line":453},[64,1550,1499],{"class":1491},[64,1552,1494],{"class":340},[64,1554,1555,1557,1559],{"class":66,"line":470},[64,1556,1506],{"class":1491},[64,1558,360],{"class":340},[64,1560,1561],{"class":74}," \u002Fhealth\u002Freadiness\n",[64,1563,1564,1566,1568],{"class":66,"line":495},[64,1565,1516],{"class":1491},[64,1567,360],{"class":340},[64,1569,1521],{"class":307},[64,1571,1572,1574,1576],{"class":66,"line":512},[64,1573,1526],{"class":1491},[64,1575,360],{"class":340},[64,1577,1578],{"class":307}," 5\n",[64,1580,1581,1583,1585],{"class":66,"line":529},[64,1582,1536],{"class":1491},[64,1584,360],{"class":340},[64,1586,1578],{"class":307},[39,1588,1590],{"id":1589},"五日志聚合","五、日志聚合",[23,1592,1593],{},"生产环境需要收集来自多个实例的日志，并集中分析。",[160,1595,1597],{"id":1596},"_1-推荐使用结构化日志如-pino-或-winston","1. 推荐使用结构化日志（如 pino 或 winston）",[23,1599,1600],{},"见前面“日志记录”章节，生产应输出 JSON 格式，便于工具解析。",[160,1602,1604],{"id":1603},"_2-日志聚合方案","2. 日志聚合方案",[1606,1607,1608,1624],"table",{},[1609,1610,1611],"thead",{},[1612,1613,1614,1618,1621],"tr",{},[1615,1616,1617],"th",{},"方案",[1615,1619,1620],{},"适用场景",[1615,1622,1623],{},"特点",[1625,1626,1627,1642,1655],"tbody",{},[1612,1628,1629,1636,1639],{},[1630,1631,1632,1635],"td",{},[110,1633,1634],{},"ELK Stack"," (Elasticsearch, Logstash, Kibana)",[1630,1637,1638],{},"大规模、高复杂度",[1630,1640,1641],{},"功能强大，支持全文检索和可视化",[1612,1643,1644,1649,1652],{},[1630,1645,1646],{},[110,1647,1648],{},"Loki + Grafana",[1630,1650,1651],{},"轻量级，与 Kubernetes 集成好",[1630,1653,1654],{},"日志与 Prometheus 指标共享标签，查询高效",[1612,1656,1657,1662,1665],{},[1630,1658,1659],{},[110,1660,1661],{},"Datadog",[1630,1663,1664],{},"商业 SaaS，全栈监控",[1630,1666,1667],{},"开箱即用，集成 APM、日志、基础设施监控",[23,1669,1670,113],{},[110,1671,1672],{},"实现方式",[80,1674,1675,1678],{},[83,1676,1677],{},"将日志输出到 stdout\u002Fstderr，由容器运行时收集并转发到日志代理（如 Filebeat、Fluentd、Promtail）。",[83,1679,1680],{},"在代码中使用 JSON 格式打印：",[55,1682,1684],{"className":791,"code":1683,"language":793,"meta":60,"style":60},"this.logger.info({ reqId: uuid(), userId }, \"User action\");\n",[27,1685,1686],{"__ignoreMap":60},[64,1687,1688,1691,1693,1696,1698,1701,1703,1706,1709,1711,1714,1716,1718,1721,1724,1726,1729,1731,1733],{"class":66,"line":67},[64,1689,1690],{"class":336},"this",[64,1692,341],{"class":340},[64,1694,1695],{"class":363},"logger",[64,1697,341],{"class":340},[64,1699,1700],{"class":904},"info",[64,1702,908],{"class":363},[64,1704,1705],{"class":340},"{",[64,1707,1708],{"class":356}," reqId",[64,1710,360],{"class":340},[64,1712,1713],{"class":904}," uuid",[64,1715,1212],{"class":363},[64,1717,426],{"class":340},[64,1719,1720],{"class":363}," userId ",[64,1722,1723],{"class":340},"},",[64,1725,382],{"class":381},[64,1727,1728],{"class":74},"User action",[64,1730,388],{"class":381},[64,1732,1282],{"class":363},[64,1734,827],{"class":340},[80,1736,1737],{},[83,1738,1739],{},"确保使用异步日志驱动（如 pino），避免阻塞事件循环。",[39,1741,1743],{"id":1742},"六环境变量确保安全","六、环境变量确保安全",[23,1745,1746],{},"禁止在代码中硬编码任何凭证、API 密钥、数据库密码等敏感信息。",[160,1748,1750,1751,1754],{"id":1749},"_1-使用-env-文件本地开发","1. 使用 ",[27,1752,1753],{},".env"," 文件（本地开发）",[23,1756,1757,1758,1761,1762,1764],{},"配合 ",[27,1759,1760],{},"@nestjs\u002Fconfig"," 模块，但 ",[27,1763,1753],{}," 文件不应提交到版本控制。",[160,1766,1768],{"id":1767},"_2-生产环境注入方式","2. 生产环境注入方式",[80,1770,1771],{},[83,1772,1773,1776,1777,1780,1781,1784],{},[110,1774,1775],{},"Docker\u002FK8s","：通过 ",[27,1778,1779],{},"env"," 或 ",[27,1782,1783],{},"secret"," 对象注入。例如：",[55,1786,1788],{"className":1482,"code":1787,"language":1484,"meta":60,"style":60},"env:\n  - name: DB_PASSWORD\n    valueFrom:\n      secretKeyRef:\n        name: db-secret\n        key: password\n",[27,1789,1790,1796,1809,1816,1823,1833],{"__ignoreMap":60},[64,1791,1792,1794],{"class":66,"line":67},[64,1793,1779],{"class":1491},[64,1795,1494],{"class":340},[64,1797,1798,1801,1804,1806],{"class":66,"line":286},[64,1799,1800],{"class":340},"  -",[64,1802,1803],{"class":1491}," name",[64,1805,360],{"class":340},[64,1807,1808],{"class":74}," DB_PASSWORD\n",[64,1810,1811,1814],{"class":66,"line":367},[64,1812,1813],{"class":1491},"    valueFrom",[64,1815,1494],{"class":340},[64,1817,1818,1821],{"class":66,"line":373},[64,1819,1820],{"class":1491},"      secretKeyRef",[64,1822,1494],{"class":340},[64,1824,1825,1828,1830],{"class":66,"line":394},[64,1826,1827],{"class":1491},"        name",[64,1829,360],{"class":340},[64,1831,1832],{"class":74}," db-secret\n",[64,1834,1835,1838,1840],{"class":66,"line":411},[64,1836,1837],{"class":1491},"        key",[64,1839,360],{"class":340},[64,1841,1842],{"class":74}," password\n",[80,1844,1845,1857],{},[83,1846,1847,1850,1851,1853,1854,1856],{},[110,1848,1849],{},"PM2","：在 ",[27,1852,323],{}," 中设置 ",[27,1855,1779],{}," 字段。",[83,1858,1859,1862],{},[110,1860,1861],{},"系统环境变量","：直接在启动命令前设置（安全性较低，不推荐多租户环境）。",[160,1864,1866],{"id":1865},"_3-使用密钥管理服务vault","3. 使用密钥管理服务（Vault）",[23,1868,1869],{},"对于高安全要求场景，可集成 HashiCorp Vault、AWS Secrets Manager 或 Azure Key Vault，应用启动时动态获取密钥。",[160,1871,1873],{"id":1872},"_4-校验环境变量","4. 校验环境变量",[23,1875,1876],{},"在应用启动时，使用 Joi 或 class-validator 验证所有必需的环境变量是否已设置且格式正确，避免运行时因缺失配置而崩溃。",[55,1878,1880],{"className":791,"code":1879,"language":793,"meta":60,"style":60},"\u002F\u002F main.ts 或 config.module.ts\nconst requiredEnv = [\"DB_HOST\", \"DB_PASSWORD\", \"API_KEY\"];\nrequiredEnv.forEach((key) => {\n  if (!process.env[key]) throw new Error(`Missing env ${key}`);\n});\n",[27,1881,1882,1887,1931,1954,2009],{"__ignoreMap":60},[64,1883,1884],{"class":66,"line":67},[64,1885,1886],{"class":429},"\u002F\u002F main.ts 或 config.module.ts\n",[64,1888,1889,1892,1896,1898,1901,1903,1906,1908,1910,1912,1915,1917,1919,1921,1924,1926,1929],{"class":66,"line":286},[64,1890,1891],{"class":956},"const",[64,1893,1895],{"class":1894},"s_hVV"," requiredEnv",[64,1897,348],{"class":347},[64,1899,1900],{"class":363}," [",[64,1902,388],{"class":381},[64,1904,1905],{"class":74},"DB_HOST",[64,1907,388],{"class":381},[64,1909,426],{"class":340},[64,1911,382],{"class":381},[64,1913,1914],{"class":74},"DB_PASSWORD",[64,1916,388],{"class":381},[64,1918,426],{"class":340},[64,1920,382],{"class":381},[64,1922,1923],{"class":74},"API_KEY",[64,1925,388],{"class":381},[64,1927,1928],{"class":363},"]",[64,1930,827],{"class":340},[64,1932,1933,1936,1938,1941,1943,1945,1948,1950,1952],{"class":66,"line":367},[64,1934,1935],{"class":363},"requiredEnv",[64,1937,341],{"class":340},[64,1939,1940],{"class":904},"forEach",[64,1942,908],{"class":363},[64,1944,908],{"class":340},[64,1946,1947],{"class":1102},"key",[64,1949,1282],{"class":340},[64,1951,1244],{"class":956},[64,1953,351],{"class":340},[64,1955,1956,1959,1962,1965,1968,1970,1972,1975,1977,1980,1983,1986,1989,1991,1994,1997,2000,2002,2005,2007],{"class":66,"line":373},[64,1957,1958],{"class":805},"  if",[64,1960,1961],{"class":356}," (",[64,1963,1964],{"class":347},"!",[64,1966,1967],{"class":363},"process",[64,1969,341],{"class":340},[64,1971,1779],{"class":363},[64,1973,1974],{"class":356},"[",[64,1976,1947],{"class":363},[64,1978,1979],{"class":356},"]) ",[64,1981,1982],{"class":805},"throw",[64,1984,1985],{"class":347}," new",[64,1987,1988],{"class":904}," Error",[64,1990,908],{"class":356},[64,1992,1993],{"class":381},"`",[64,1995,1996],{"class":74},"Missing env ",[64,1998,1999],{"class":381},"${",[64,2001,1947],{"class":363},[64,2003,2004],{"class":381},"}`",[64,2006,1282],{"class":356},[64,2008,827],{"class":340},[64,2010,2011,2013,2015],{"class":66,"line":394},[64,2012,945],{"class":340},[64,2014,1282],{"class":363},[64,2016,827],{"class":340},[39,2018,2019],{"id":2019},"总结表",[1606,2021,2022,2032],{},[1609,2023,2024],{},[1612,2025,2026,2029],{},[1615,2027,2028],{},"环节",[1615,2030,2031],{},"关键措施",[1625,2033,2034,2049,2063,2073,2089,2099],{},[1612,2035,2036,2041],{},[1630,2037,2038],{},[110,2039,2040],{},"构建",[1630,2042,2043,2045,2046,2048],{},[27,2044,29],{},"，设置 ",[27,2047,121],{},"，使用 webpack 优化（可选）",[1612,2050,2051,2056],{},[1630,2052,2053],{},[110,2054,2055],{},"Node 配置",[1630,2057,2058,2060,2061],{},[27,2059,189],{}," 设置内存上限，开启 ",[27,2062,237],{},[1612,2064,2065,2070],{},[1630,2066,2067],{},[110,2068,2069],{},"进程管理",[1630,2071,2072],{},"PM2 集群模式，或 Docker + K8s 编排（设置管理探针）",[1612,2074,2075,2080],{},[1630,2076,2077],{},[110,2078,2079],{},"健康检查",[1630,2081,2082,2084,2085,2088],{},[27,2083,726],{}," 提供 ",[27,2086,2087],{},"\u002Fhealth"," 端点，支持 liveness\u002Freadiness",[1612,2090,2091,2096],{},[1630,2092,2093],{},[110,2094,2095],{},"日志聚合",[1630,2097,2098],{},"使用 JSON 格式日志，集成 ELK\u002FLoki\u002FDatadog 集中收集",[1612,2100,2101,2106],{},[1630,2102,2103],{},[110,2104,2105],{},"环境变量安全",[1630,2107,2108],{},"禁止硬编码，通过 Secrets、Vault 注入；启动时强制校验",[23,2110,2111],{},"遵循这些实践，可以确保 NestJS 应用在生产环境中稳定、安全、可观测。",[2113,2114,2115],"h2",{"id":2115},"参考文献",[23,2117,2118],{},"以下链接在编写时均可正常访问：",[1606,2120,2121,2131],{},[1609,2122,2123],{},[1612,2124,2125,2128],{},[1615,2126,2127],{},"资料",[1615,2129,2130],{},"说明",[1625,2132,2133,2147,2158],{},[1612,2134,2135,2144],{},[1630,2136,2137],{},[2138,2139,2143],"a",{"href":2140,"rel":2141},"https:\u002F\u002Fdocs.nestjs.com\u002F",[2142],"nofollow","NestJS 文档",[1630,2145,2146],{},"官方",[1612,2148,2149,2155],{},[1630,2150,2151],{},[2138,2152,686],{"href":2153,"rel":2154},"https:\u002F\u002Fdocs.nestjs.com\u002Ffaq\u002Fdeployment",[2142],[1630,2156,2157],{},"本章主题",[1612,2159,2160,2167],{},[1630,2161,2162],{},[2138,2163,2166],{"href":2164,"rel":2165},"https:\u002F\u002Fdocs.nestjs.com\u002Ffaq\u002Frequest-lifecycle",[2142],"Request lifecycle",[1630,2168,2169],{},"执行顺序",[2171,2172,2173],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":60,"searchDepth":286,"depth":286,"links":2175},[2176,2178,2179,2180,2182,2183,2184,2185],{"id":41,"depth":367,"text":2177},"一、构建：nest build 输出 dist 目录",{"id":154,"depth":367,"text":155},{"id":253,"depth":367,"text":254},{"id":722,"depth":367,"text":2181},"四、健康检查：@nestjs\u002Fterminus 模块",{"id":1589,"depth":367,"text":1590},{"id":1742,"depth":367,"text":1743},{"id":2019,"depth":367,"text":2019},{"id":2115,"depth":286,"text":2115},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNestJS\u002Fnew\u002Fdeploy","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNestJS\u002Fnew\u002Fdeploy.md","md",{"items":2191},[2192,2196,2200,2204,2208,2212],{"path":2193,"title":2194,"description":2195,"category":10,"score":411},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fauth","认证与授权","认证（Authentication）：确认「你是谁」（如 JWT、Session）。 - 授权（Authorization）：确认「你能做什么」（如 RBAC、策略检查）。",{"path":2197,"title":2198,"description":2199,"category":10,"score":411},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcache","缓存","@nestjs\u002Fcache-manager 统一缓存 API，存储实现可插拔。",{"path":2201,"title":2202,"description":2203,"category":10,"score":411},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fservice","提供者与服务","Service 是最常见的 Provider，封装业务逻辑。见 module。",{"path":2205,"title":2206,"description":2207,"category":10,"score":411},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fguards","守卫 (Guards) 与授权","守卫决定是否放行请求，常用于认证与授权。见 auth。",{"path":2209,"title":2210,"description":2211,"category":10,"score":411},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fconfig","配置管理（Config 模块）","@nestjs\u002Fconfig 加载 .env 并提供 ConfigService。见 工程化 env。",{"path":2213,"title":2214,"description":2215,"category":10,"score":411},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdatabase","数据库集成（以 TypeORM 为例）","Nest 通过 @nestjs\u002Ftypeorm 等包集成 ORM；生产环境用 migration，慎用 synchronize。亦可选用 Prisma、MikroORM 等（见 官方 Database）。",{"series":2217,"title":2218,"items":2219,"index":453,"prev":2280,"next":2281},"booklet\u002Fend\u002Fnestjs\u002Fnew","new",[2220,2222,2226,2228,2230,2234,2238,2242,2244,2245,2249,2251,2255,2259,2263,2267,2270,2274,2276],{"path":2193,"title":2194,"date":2221,"pinned":15},"2025-12-23",{"path":2223,"title":2224,"date":2225,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fbase","NestJS 基础","2021-03-09",{"path":2197,"title":2198,"date":2227,"pinned":15},"2025-07-04",{"path":2209,"title":2210,"date":2229,"pinned":15},"2023-08-26",{"path":2231,"title":2232,"date":2233,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcontroller","控制器与路由","2020-07-18",{"path":2235,"title":2236,"date":2237,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcron","定时任务","2023-04-12",{"path":2239,"title":2240,"date":2241,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcustom-decorators","自定义装饰器","2021-09-19",{"path":2213,"title":2214,"date":2243,"pinned":15},"2023-05-26",{"path":7,"title":8,"date":14,"pinned":15},{"path":2246,"title":2247,"date":2248,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Ferror","异常处理","2020-01-28",{"path":2205,"title":2206,"date":2250,"pinned":15},"2023-09-09",{"path":2252,"title":2253,"date":2254,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fintercept","拦截器 (Interceptors)","2021-04-26",{"path":2256,"title":2257,"date":2258,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Flogger","日志记录","2022-10-10",{"path":2260,"title":2261,"date":2262,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fmiddleware","中间件 (Middleware)","2021-11-26",{"path":2264,"title":2265,"date":2266,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fmodule","模块系统与依赖注入","2022-06-15",{"path":2268,"title":2269,"date":2233,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fpipes","管道 (Pipes) 与数据验证",{"path":2271,"title":2272,"date":2273,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fqueue","队列（Bull）","2021-07-01",{"path":2201,"title":2202,"date":2275,"pinned":15},"2024-12-02",{"path":2277,"title":2278,"date":2279,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fwebsocket","WebSocket（网关）","2022-12-14",{"path":2213,"title":2214,"date":2243,"pinned":15},{"path":2246,"title":2247,"date":2248,"pinned":15}]