fix(tenant-service): 自动修复 nginx 更新接口 60s 超时

patchNginxUpdateTimeout 为 /api/system/update 注入精确匹配 location,
proxy_read_timeout 设为 600s,避免 docker pull 静默期断连。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-05-21 17:19:55 +08:00
父节点 4a38147cb9
当前提交 c9c50038bf

查看文件

@ -87,9 +87,45 @@ public class SystemUpdateService {
private void patchConfigs(Consumer<String> emit) { private void patchConfigs(Consumer<String> emit) {
emit.accept(">>> 检查并修复配置文件..."); emit.accept(">>> 检查并修复配置文件...");
patchNginxFileRoute(emit); patchNginxFileRoute(emit);
patchNginxUpdateTimeout(emit);
patchDockerComposeFileService(emit); patchDockerComposeFileService(emit);
} }
/**
* nginx: add exact-match location for /api/system/update with 600s timeout so that
* docker pull (which may be silent for minutes) doesn't hit the 60s proxy_read_timeout
* on the generic /api/ block and cause ERR_INCOMPLETE_CHUNKED_ENCODING.
*/
private void patchNginxUpdateTimeout(Consumer<String> emit) {
Path conf = Paths.get(deployRoot, "config", "nginx", "conf.d", "xuqm.conf");
if (!Files.exists(conf)) return;
try {
String content = Files.readString(conf);
if (content.contains("location = /api/system/update")) return;
String anchor = " # 核心 API兜底,在所有具体 /api/xxx/ 之后)\n location /api/ {";
if (!content.contains(anchor)) {
emit.accept(" [跳过] nginx 更新超时补丁锚点未找到,请手动检查");
return;
}
String injection = " # 一键更新docker pull 可能耗时数分钟,需要更长超时(精确匹配,优先于 /api/ 前缀)\n"
+ " location = /api/system/update {\n"
+ " set $svc tenant-service;\n"
+ " proxy_pass http://$svc:9001;\n"
+ " proxy_set_header Host $host;\n"
+ " proxy_set_header X-Real-IP $remote_addr;\n"
+ " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"
+ " proxy_read_timeout 600s;\n"
+ " proxy_send_timeout 600s;\n"
+ " }\n\n"
+ anchor;
String patched = content.replace(anchor, injection);
Files.writeString(conf, patched, StandardOpenOption.TRUNCATE_EXISTING);
emit.accept(" [已修复] nginx: 补齐 /api/system/update 600s 超时");
} catch (IOException e) {
emit.accept(" [警告] nginx 更新超时修复失败: " + e.getMessage());
}
}
/** nginx: location /file/ must be location /api/file/ to match the file controller path. */ /** nginx: location /file/ must be location /api/file/ to match the file controller path. */
private void patchNginxFileRoute(Consumer<String> emit) { private void patchNginxFileRoute(Consumer<String> emit) {
Path conf = Paths.get(deployRoot, "config", "nginx", "conf.d", "xuqm.conf"); Path conf = Paths.get(deployRoot, "config", "nginx", "conf.d", "xuqm.conf");