From 37ea338a35aba680ec7eba6abf72afd4f77e1f94 Mon Sep 17 00:00:00 2001 From: qaq <1937228092@qq.com> Date: Thu, 20 Nov 2025 12:15:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DWAL=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E4=B8=8B=E4=B8=A2=E5=A4=B1=E6=95=B0=E6=8D=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-build.yml | 2 +- docker-compose-v4.yml | 6 ++- docker-compose-v6.yml | 6 ++- install.sh | 2 +- panel_install.sh | 14 +++++-- springboot-backend/Dockerfile | 2 +- .../admin/common/utils/WebSocketServer.java | 1 + .../java/com/admin/config/SQLiteConfig.java | 41 +++++++++++++++++++ .../admin/service/impl/NodeServiceImpl.java | 2 +- vite-frontend/src/config/site.ts | 2 +- 10 files changed, 66 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index d153b52..9cf81e7 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -2,7 +2,7 @@ name: Build and Push Images Based on Version # 在这里定义统一版本号 env: - VERSION: "2.0.3-beta" + VERSION: "2.0.4-beta" on: push: diff --git a/docker-compose-v4.yml b/docker-compose-v4.yml index 08e137f..9b09df4 100644 --- a/docker-compose-v4.yml +++ b/docker-compose-v4.yml @@ -1,6 +1,6 @@ services: backend: - image: bqlpfy/springboot-backend:2.0.3-beta + image: bqlpfy/springboot-backend:2.0.4-beta container_name: springboot-backend restart: unless-stopped environment: @@ -15,6 +15,8 @@ services: - sqlite_data:/app/data networks: - gost-network + stop_grace_period: 30s + stop_signal: SIGTERM healthcheck: test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://localhost:6365/flow/test || exit 1"] interval: 30s @@ -23,7 +25,7 @@ services: start_period: 60s frontend: - image: bqlpfy/vite-frontend:2.0.3-beta + image: bqlpfy/vite-frontend:2.0.4-beta container_name: vite-frontend restart: unless-stopped ports: diff --git a/docker-compose-v6.yml b/docker-compose-v6.yml index 65b53f7..b4d6058 100644 --- a/docker-compose-v6.yml +++ b/docker-compose-v6.yml @@ -1,6 +1,6 @@ services: backend: - image: bqlpfy/springboot-backend:2.0.3-beta + image: bqlpfy/springboot-backend:2.0.4-beta container_name: springboot-backend restart: unless-stopped environment: @@ -15,6 +15,8 @@ services: - sqlite_data:/app/data networks: - gost-network + stop_grace_period: 30s + stop_signal: SIGTERM healthcheck: test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://localhost:6365/flow/test || exit 1"] interval: 30s @@ -23,7 +25,7 @@ services: start_period: 60s frontend: - image: bqlpfy/vite-frontend:2.0.3-beta + image: bqlpfy/vite-frontend:2.0.4-beta container_name: vite-frontend restart: unless-stopped ports: diff --git a/install.sh b/install.sh index d1d5b6f..f111180 100644 --- a/install.sh +++ b/install.sh @@ -19,7 +19,7 @@ get_architecture() { # 构建下载地址 build_download_url() { local ARCH=$(get_architecture) - echo "https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/gost-${ARCH}" + echo "https://github.com/bqlpfy/flux-panel/releases/download/2.0.4-beta/gost-${ARCH}" } # 下载地址 diff --git a/panel_install.sh b/panel_install.sh index 423feb7..63cf52b 100755 --- a/panel_install.sh +++ b/panel_install.sh @@ -8,8 +8,8 @@ export LC_ALL=C # 全局下载地址配置 -DOCKER_COMPOSEV4_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/docker-compose-v4.yml" -DOCKER_COMPOSEV6_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/docker-compose-v6.yml" +DOCKER_COMPOSEV4_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.4-beta/docker-compose-v4.yml" +DOCKER_COMPOSEV6_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.4-beta/docker-compose-v6.yml" COUNTRY=$(curl -s https://ipinfo.io/country) if [ "$COUNTRY" = "CN" ]; then @@ -234,7 +234,15 @@ update_panel() { configure_docker_ipv6 fi - echo "🛑 停止当前服务..." + # 先发送 SIGTERM 信号,让应用优雅关闭 + docker stop -t 30 springboot-backend 2>/dev/null || true + docker stop -t 10 vite-frontend 2>/dev/null || true + + # 等待 WAL 文件同步 + echo "⏳ 等待数据同步..." + sleep 5 + + # 然后再完全停止 $DOCKER_CMD down echo "⬇️ 拉取最新镜像..." diff --git a/springboot-backend/Dockerfile b/springboot-backend/Dockerfile index 908e9f1..208217e 100644 --- a/springboot-backend/Dockerfile +++ b/springboot-backend/Dockerfile @@ -16,7 +16,7 @@ ENV LC_ALL=en_US.UTF-8 RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \ && sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \ && apt-get update \ - && apt-get install -y --no-install-recommends fontconfig fonts-dejavu \ + && apt-get install -y --no-install-recommends fontconfig fonts-dejavu sqlite3 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/springboot-backend/src/main/java/com/admin/common/utils/WebSocketServer.java b/springboot-backend/src/main/java/com/admin/common/utils/WebSocketServer.java index 40f9528..79ec6af 100644 --- a/springboot-backend/src/main/java/com/admin/common/utils/WebSocketServer.java +++ b/springboot-backend/src/main/java/com/admin/common/utils/WebSocketServer.java @@ -229,6 +229,7 @@ public class WebSocketServer extends TextWebSocketHandler { String socks = (String) session.getAttributes().get("socks"); log.info("节点 {} 尝试连接,开始处理连接逻辑", nodeId); + log.info("屏蔽协议数据:http->{}, tls->{}, socks->{}", http, tls, socks); // 检查是否已有该节点的连接,如果有则记录日志但直接覆盖 WebSocketSession existingSession = nodeSessions.get(nodeId); diff --git a/springboot-backend/src/main/java/com/admin/config/SQLiteConfig.java b/springboot-backend/src/main/java/com/admin/config/SQLiteConfig.java index 2d6cb0c..8d413da 100644 --- a/springboot-backend/src/main/java/com/admin/config/SQLiteConfig.java +++ b/springboot-backend/src/main/java/com/admin/config/SQLiteConfig.java @@ -3,8 +3,11 @@ package com.admin.config; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import javax.annotation.PreDestroy; import javax.sql.DataSource; import java.sql.Connection; import java.sql.Statement; @@ -12,9 +15,11 @@ import java.sql.Statement; /** * SQLite 数据库配置 * 启用 WAL (Write-Ahead Logging) 模式以提高并发性能 + * 添加定期 checkpoint 和优雅关闭处理 */ @Slf4j @Component +@EnableScheduling public class SQLiteConfig implements ApplicationRunner { private final DataSource dataSource; @@ -33,10 +38,46 @@ public class SQLiteConfig implements ApplicationRunner { statement.execute("PRAGMA cache_size=-64000;"); // 64MB 缓存 statement.execute("PRAGMA temp_store=MEMORY;"); statement.execute("PRAGMA busy_timeout=5000;"); // 5秒超时 + statement.execute("PRAGMA wal_autocheckpoint=1000;"); // 每1000页自动checkpoint + + log.info("SQLite WAL mode configured successfully"); } catch (Exception e) { log.error("Failed to configure SQLite database", e); throw e; } } + + /** + * 定期执行 checkpoint,确保 WAL 文件内容写入主数据库 + * 每5分钟执行一次 + */ + @Scheduled(fixedDelay = 300000, initialDelay = 300000) + public void performCheckpoint() { + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { + + statement.execute("PRAGMA wal_checkpoint(TRUNCATE);"); + log.debug("SQLite WAL checkpoint completed"); + } catch (Exception e) { + log.error("Failed to perform SQLite checkpoint", e); + } + } + + /** + * 应用关闭前执行最终的 checkpoint,确保所有数据都写入主数据库文件 + */ + @PreDestroy + public void onShutdown() { + log.info("Performing final SQLite checkpoint before shutdown..."); + try (Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement()) { + + // 强制执行 checkpoint,将所有 WAL 内容写入主数据库 + statement.execute("PRAGMA wal_checkpoint(TRUNCATE);"); + log.info("Final SQLite checkpoint completed successfully"); + } catch (Exception e) { + log.error("Failed to perform final SQLite checkpoint", e); + } + } } diff --git a/springboot-backend/src/main/java/com/admin/service/impl/NodeServiceImpl.java b/springboot-backend/src/main/java/com/admin/service/impl/NodeServiceImpl.java index 018d230..d2a315e 100644 --- a/springboot-backend/src/main/java/com/admin/service/impl/NodeServiceImpl.java +++ b/springboot-backend/src/main/java/com/admin/service/impl/NodeServiceImpl.java @@ -126,7 +126,7 @@ public class NodeServiceImpl extends ServiceImpl implements No ViteConfig viteConfig = viteConfigService.getOne(new QueryWrapper().eq("name", "ip")); if (viteConfig == null) return R.err("请先前往网站配置中设置ip"); StringBuilder command = new StringBuilder(); - command.append("curl -L https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/install.sh") + command.append("curl -L https://github.com/bqlpfy/flux-panel/releases/download/2.0.4-beta/install.sh") .append(" -o ./install.sh && chmod +x ./install.sh && "); String processedServerAddr = GostUtil.processServerAddress(viteConfig.getValue()); command.append("./install.sh") diff --git a/vite-frontend/src/config/site.ts b/vite-frontend/src/config/site.ts index 16d5b56..8b8ea01 100644 --- a/vite-frontend/src/config/site.ts +++ b/vite-frontend/src/config/site.ts @@ -4,7 +4,7 @@ export type SiteConfig = typeof siteConfig; // 缓存相关常量 const CACHE_PREFIX = 'vite_config_'; -const VERSION = "2.0.3-beta"; +const VERSION = "2.0.4-beta"; const APP_VERSION = "1.0.3"; const getInitialConfig = () => {