JJianFeeeeechore: v0.1.4 — 版本号收拢(6 处)
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat(cluster,webapi): 集群页可切换负载均衡模式(每节点一个开关) ## 为什么之前没有开关(以及为什么现在这么加) 模式原本只读一次环境变量 W4F_BALANCE_MODE,UI 只显示「观察模式 / 已启用」。 把开关加进来时有两个坑必须一起解决,否则开关是个摆设: 1. **不持久化就等于骗人**:只用 env,页面上翻一下、重启一次就回到默认, 而页面已经显示成功了。 2. **不能做成集群级开关**:每个成员只释放自己的转发,根本没有一个动作能把它们 一起翻过来。做成集群开关就是撒谎。 所以:**每节点一个开关**,写的是本节点自己的设置。 ## 持久化与优先级 - 新增 settings 表的 balance_mode 列 + Store.BalanceMode()。**单独一列**, 不是塞进 settings JSON:那个 JSON 是整份重写的,而这是会被各节点同时写、必须 各自收敛的状态,跟 nodeKey/settings 同一类处理。 - **存了就以存的为准**,env 只作首次启动的默认值;Settings() 读回时带上它, 但 UpdateSettings 只在非空时镜像到列,所以一次无关的设置保存不会把它清掉。 - SetModeFromUI **先落盘再应用**:写失败就什么都不改,否则节点会运行一个重启后 复现不出来的模式——开关就成了谎言。 - 认不出的模式一律拒绝(400),不猜。 ## 报告新增两个字段 - modeSource: env | stored —— 说清当前模式是启动参数给的还是有人在这里选的。 - canControl: 由**调用者的权限**决定,只读身份不会看到一个点了会 403 的开关。 PUT /cluster/balance/mode 走 **write** 级鉴权:释放会停 worker、断活连接。 ## 两处我自己抓到并修掉的错 1. **ModeSource() 一开始写成「能存就算 stored」**(判据是 persist != nil), 于是**每个有 store 的节点都自称 stored**,哪怕从没人设过。canary 第一轮就露了: mode=dry-run source=stored。改成看「是否真的存过值」。 2. **启动日志打的是 env 变量而不是生效值**,存过 on 之后仍打 DRY-RUN—— 上一行的 loaded from settings 还在,两行自相矛盾,正好会让人以为释放是关的 而它其实开着。 ## 测试 新增 6 条:存的模式压过 env、没存就回落 env、落盘失败则模式不变、乱值被拒、 UI 切换同时落盘并生效、无持久化能力时不宣称可控制。 canary 实跑 6 步:初始 dry-run/env → 设 on → 复查 on/stored → 乱值 400 → 乱值后模式不变 → **重启后仍 on/stored**,启动日志 load balancing ON (source=stored …)。 vue-tsc 干净;go build / vet / go test ./... 全绿。 | 14 天前 | |
feat(cluster,webapi): 集群页可切换负载均衡模式(每节点一个开关) ## 为什么之前没有开关(以及为什么现在这么加) 模式原本只读一次环境变量 W4F_BALANCE_MODE,UI 只显示「观察模式 / 已启用」。 把开关加进来时有两个坑必须一起解决,否则开关是个摆设: 1. **不持久化就等于骗人**:只用 env,页面上翻一下、重启一次就回到默认, 而页面已经显示成功了。 2. **不能做成集群级开关**:每个成员只释放自己的转发,根本没有一个动作能把它们 一起翻过来。做成集群开关就是撒谎。 所以:**每节点一个开关**,写的是本节点自己的设置。 ## 持久化与优先级 - 新增 settings 表的 balance_mode 列 + Store.BalanceMode()。**单独一列**, 不是塞进 settings JSON:那个 JSON 是整份重写的,而这是会被各节点同时写、必须 各自收敛的状态,跟 nodeKey/settings 同一类处理。 - **存了就以存的为准**,env 只作首次启动的默认值;Settings() 读回时带上它, 但 UpdateSettings 只在非空时镜像到列,所以一次无关的设置保存不会把它清掉。 - SetModeFromUI **先落盘再应用**:写失败就什么都不改,否则节点会运行一个重启后 复现不出来的模式——开关就成了谎言。 - 认不出的模式一律拒绝(400),不猜。 ## 报告新增两个字段 - modeSource: env | stored —— 说清当前模式是启动参数给的还是有人在这里选的。 - canControl: 由**调用者的权限**决定,只读身份不会看到一个点了会 403 的开关。 PUT /cluster/balance/mode 走 **write** 级鉴权:释放会停 worker、断活连接。 ## 两处我自己抓到并修掉的错 1. **ModeSource() 一开始写成「能存就算 stored」**(判据是 persist != nil), 于是**每个有 store 的节点都自称 stored**,哪怕从没人设过。canary 第一轮就露了: mode=dry-run source=stored。改成看「是否真的存过值」。 2. **启动日志打的是 env 变量而不是生效值**,存过 on 之后仍打 DRY-RUN—— 上一行的 loaded from settings 还在,两行自相矛盾,正好会让人以为释放是关的 而它其实开着。 ## 测试 新增 6 条:存的模式压过 env、没存就回落 env、落盘失败则模式不变、乱值被拒、 UI 切换同时落盘并生效、无持久化能力时不宣称可控制。 canary 实跑 6 步:初始 dry-run/env → 设 on → 复查 on/stored → 乱值 400 → 乱值后模式不变 → **重启后仍 on/stored**,启动日志 load balancing ON (source=stored …)。 vue-tsc 干净;go build / vet / go test ./... 全绿。 | 14 天前 | |
webui4frpc: 独立可用的可视化 frpc 控制器 (M0) - 零 frp 源码依赖,单二进制 (Go + Vue3 + VueFlow + Element Plus) - 画布多对多连线,渲染 tcp/udp/http/https frpc 配置 - worker 进程管理:自愈、日志轮转、崩溃退避重启 - frpc 一键安装 (GitHub Releases) + 手动指定路径 - 三页 UI:状态(默认)/连接配置/设置 - 状态页实时节点/转发状态,节点可增删改启停 - 画布冲突检查:端口/域名冲突标红 + 弹窗拦截保存 - backend 单测覆盖 store/render/process/httpapi/install - plan.md + FRPC_FEATURES_AUDIT.md 文档 | 2 个月前 | |
feat: per-forward worker 模型 — 每条转发独立 frpc 配置+独立进程 核心改动(ring 协议不变,Task 本来就是 {Local,Remote,Link} 三元组): - process.WorkerKey: worker 键改为 'local~remote~port' 三元组 - renderForward: 每条 forward 渲染只含 1 个 proxy 的独立 frpc 配置 (替代 renderRemote 把该 remote 全部 forwards 塞进一个进程) - ClaimFn/RevokeFn: 认领/撤销只操作这一条 forward 自己的进程 - SyncWorkers/auto-start: 只拉起 localOnly 转发的独立进程, 集群转发由 ring 认领节点拉起 (消除三台争抢 proxy already exists) - RemoteStatus/StartRemote/StopRemote/RestartRemote: remote 级聚合辅助, 保持 /profiles API 形状不变, 前端零改动 - handleStatus/logs: 按 worker key 解析真实 remote 名 效果: 三台节点的 frpc 各自只注册自己拥有的 proxy, 单条转发故障不再波及兄弟 | 1 个月前 | |
feat: M3 load balancing + health check (model/render/admin API status/UI) | 2 个月前 | |
feat(cluster,webapi): 集群页可切换负载均衡模式(每节点一个开关) ## 为什么之前没有开关(以及为什么现在这么加) 模式原本只读一次环境变量 W4F_BALANCE_MODE,UI 只显示「观察模式 / 已启用」。 把开关加进来时有两个坑必须一起解决,否则开关是个摆设: 1. **不持久化就等于骗人**:只用 env,页面上翻一下、重启一次就回到默认, 而页面已经显示成功了。 2. **不能做成集群级开关**:每个成员只释放自己的转发,根本没有一个动作能把它们 一起翻过来。做成集群开关就是撒谎。 所以:**每节点一个开关**,写的是本节点自己的设置。 ## 持久化与优先级 - 新增 settings 表的 balance_mode 列 + Store.BalanceMode()。**单独一列**, 不是塞进 settings JSON:那个 JSON 是整份重写的,而这是会被各节点同时写、必须 各自收敛的状态,跟 nodeKey/settings 同一类处理。 - **存了就以存的为准**,env 只作首次启动的默认值;Settings() 读回时带上它, 但 UpdateSettings 只在非空时镜像到列,所以一次无关的设置保存不会把它清掉。 - SetModeFromUI **先落盘再应用**:写失败就什么都不改,否则节点会运行一个重启后 复现不出来的模式——开关就成了谎言。 - 认不出的模式一律拒绝(400),不猜。 ## 报告新增两个字段 - modeSource: env | stored —— 说清当前模式是启动参数给的还是有人在这里选的。 - canControl: 由**调用者的权限**决定,只读身份不会看到一个点了会 403 的开关。 PUT /cluster/balance/mode 走 **write** 级鉴权:释放会停 worker、断活连接。 ## 两处我自己抓到并修掉的错 1. **ModeSource() 一开始写成「能存就算 stored」**(判据是 persist != nil), 于是**每个有 store 的节点都自称 stored**,哪怕从没人设过。canary 第一轮就露了: mode=dry-run source=stored。改成看「是否真的存过值」。 2. **启动日志打的是 env 变量而不是生效值**,存过 on 之后仍打 DRY-RUN—— 上一行的 loaded from settings 还在,两行自相矛盾,正好会让人以为释放是关的 而它其实开着。 ## 测试 新增 6 条:存的模式压过 env、没存就回落 env、落盘失败则模式不变、乱值被拒、 UI 切换同时落盘并生效、无持久化能力时不宣称可控制。 canary 实跑 6 步:初始 dry-run/env → 设 on → 复查 on/stored → 乱值 400 → 乱值后模式不变 → **重启后仍 on/stored**,启动日志 load balancing ON (source=stored …)。 vue-tsc 干净;go build / vet / go test ./... 全绿。 | 14 天前 | |
chore: v0.1.4 — 版本号收拢(6 处) internal/version/version.go(ldflags 示例 + 默认值)、scripts/release.sh(注释 + 默认值)、 scripts/build_installers.sh、packaging/rpm/webui4frpc.spec(Version + changelog,含本次 负载均衡四条)、README.md 与 packaging/windows/README.md 的安装示例。 漏一处就会让某个安装包的示例文件名指向不存在的产物,所以按 v0.1.3 的 5 处清单逐个核对, 并补上 084ef62 才纳入的 packaging/windows/README.md,共 6 个文件。 | 14 天前 |