29 lines
1.5 KiB
JavaScript
29 lines
1.5 KiB
JavaScript
const [origin,environment]=process.argv.slice(2);
|
|
if(!origin||!['test','production'].includes(environment))throw new Error('Usage: node scripts/check-health.mjs <origin> test|production');
|
|
async function read(path) {
|
|
const response=await fetch(new URL(path,origin),{signal:AbortSignal.timeout(5000),redirect:'error',cache:'no-store'});
|
|
if(response.status!==200)throw new Error(`${path} HTTP ${response.status}`);
|
|
let text='',size=0;
|
|
const decoder=new TextDecoder();
|
|
for await(const part of response.body) {
|
|
size+=part.length;if(size>1048576)throw new Error(`${path} 响应超过检查上限`);
|
|
text+=decoder.decode(part,{stream:true});
|
|
if(path==='/'&&text.includes('/_next/'))break;
|
|
}
|
|
return {text,type:response.headers.get('content-type')||''};
|
|
}
|
|
let healthy=false;
|
|
for(let attempt=1;attempt<=5;attempt++) {
|
|
try {
|
|
const health=await read('/healthz'),status=JSON.parse(health.text);
|
|
if(status.status!=='ok'||status.environment!==environment||status.application!=='jha-1049-sgdj-web')throw new Error('/healthz 未命中本站对应环境');
|
|
const home=await read('/');
|
|
if(!/^text\/html(?:;|$)/i.test(home.type)||!home.text.includes('/_next/'))throw new Error('首页不是 Next HTML');
|
|
healthy=true;console.log('/healthz 与 Next 首页检查通过');break;
|
|
}catch(error) {
|
|
console.error(`健康检查 ${attempt}/5 失败:${error.message}`);
|
|
if(attempt<5)await new Promise(resolve=>setTimeout(resolve,1000));
|
|
}
|
|
}
|
|
process.exitCode=healthy?0:1;
|