fix: address code review feedback - startup validation, error context, security notes
- Fail fast on startup if ZY_CN_RELAY_API_KEY is not configured - Add model endpoint context to error messages for debugging - Make API timeout configurable via environment variable - Deduplicate health check curl in workflow - Add security note about VPN-encrypted relay channel Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/f6db708e-8b10-4339-b48f-db5f111ae5cd Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
91c957d85e
commit
6146dd3aea
|
|
@ -111,9 +111,10 @@ jobs:
|
|||
|
||||
# 健康检查
|
||||
sleep 3
|
||||
if curl -sf http://127.0.0.1:3900/health > /dev/null 2>&1; then
|
||||
HEALTH_RESULT=$(curl -s http://127.0.0.1:3900/health 2>/dev/null || echo "")
|
||||
if [ -n "$HEALTH_RESULT" ]; then
|
||||
echo "✅ CN LLM Relay 健康检查通过"
|
||||
curl -s http://127.0.0.1:3900/health | head -c 500
|
||||
echo "$HEALTH_RESULT" | head -c 500
|
||||
else
|
||||
echo "⚠️ 健康检查未通过 · 查看日志"
|
||||
pm2 logs cn-llm-relay --lines 20 --nostream
|
||||
|
|
|
|||
|
|
@ -208,6 +208,10 @@ function callDomesticLLM(modelConfig, messages) {
|
|||
* 通过广州CN中继调用国内模型API
|
||||
* 架构: SG(新加坡) → 广州(ZY-SVR-003):3900 → 国内API
|
||||
* 对称于硅谷Claude中继: SG → SV(SSH隧道) → Claude API
|
||||
*
|
||||
* 安全: SG↔广州通信走HTTP但通过已有的VPN/内网隧道加密
|
||||
* (setup-cn-relay.sh 建立的 CN:2053→SG:443 Xray通道)
|
||||
* 中继鉴权密钥通过 Bearer Token 传递
|
||||
*/
|
||||
function callViaCNRelay(messages, selected, fallbackOrder) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
@ -250,7 +254,7 @@ function callViaCNRelay(messages, selected, fallbackOrder) {
|
|||
|
||||
req.setTimeout(CN_RELAY_TIMEOUT, () => {
|
||||
req.destroy();
|
||||
reject(new Error(`广州中继超时(${CN_RELAY_TIMEOUT}ms)`));
|
||||
reject(new Error(`广州中继超时(${CN_RELAY_TIMEOUT}ms) · 目标模型: ${selected.id}`));
|
||||
});
|
||||
req.on('error', (err) => {
|
||||
reject(new Error(`广州中继连接失败: ${err.message}`));
|
||||
|
|
|
|||
|
|
@ -32,6 +32,16 @@ const app = express();
|
|||
const PORT = process.env.RELAY_PORT || 3900;
|
||||
const RELAY_API_KEY = process.env.ZY_CN_RELAY_API_KEY || '';
|
||||
|
||||
// 启动时校验: 鉴权密钥必须配置
|
||||
if (!RELAY_API_KEY) {
|
||||
console.error('[CN中继] ❌ ZY_CN_RELAY_API_KEY 未配置 · 服务拒绝启动');
|
||||
console.error('[CN中继] 请在 .env.relay 中设置 ZY_CN_RELAY_API_KEY');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// API请求超时(可通过环境变量调整)
|
||||
const API_TIMEOUT_MS = parseInt(process.env.ZY_CN_API_TIMEOUT || '60000', 10);
|
||||
|
||||
// ─── 国内模型配置 ───
|
||||
const DOMESTIC_MODELS = {
|
||||
ds: {
|
||||
|
|
@ -162,21 +172,23 @@ function callDomesticAPI(modelConfig, apiKey, requestBody) {
|
|||
try {
|
||||
const body = JSON.parse(Buffer.concat(chunks).toString());
|
||||
if (body.error) {
|
||||
reject(new Error(body.error.message || JSON.stringify(body.error)));
|
||||
reject(new Error(`${modelConfig.endpoint}: ${body.error.message || JSON.stringify(body.error)}`));
|
||||
} else {
|
||||
resolve(body);
|
||||
}
|
||||
} catch (e) {
|
||||
reject(new Error('响应解析失败'));
|
||||
reject(new Error(`${modelConfig.endpoint} 响应解析失败 (HTTP ${res.statusCode})`));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.setTimeout(60000, () => {
|
||||
req.setTimeout(API_TIMEOUT_MS, () => {
|
||||
req.destroy();
|
||||
reject(new Error('国内API请求超时(60s)'));
|
||||
reject(new Error(`${modelConfig.endpoint} 请求超时(${API_TIMEOUT_MS}ms)`));
|
||||
});
|
||||
req.on('error', (err) => {
|
||||
reject(new Error(`${modelConfig.endpoint} 连接失败: ${err.message}`));
|
||||
});
|
||||
req.on('error', reject);
|
||||
req.write(bodyStr);
|
||||
req.end();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue