-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
1Panel Version
2.0.17
Please describe your needs or suggestions for improvements
应用商店经过加日志测试,在 2c2g 美西小鸡(nvme磁盘)上测试结果如下
download_zip:≈ 1.06s 下载1panel.json.zip
decompress:≈ 0.024s 解压
json_decode:≈ 0.097s 序列化解码
sync_detail:03:40:21.361 → 03:42:35.716 ≈ 134.36s(> 99%) 从oss上同步资源信息
db: 0.24s
可见其实 1panel应用商店同步逻辑中,时间卡在了sync_detail上,对于其他数据入库其实几乎在一秒内完成
然而 sync_detail 这个并非是机器性能导致的问题,134s 全部在扫描目前 226 个 app,对于每个 app 检查和下载一次图标,有的会下载版本的 compose 文件。
sync_detail 具体问题:
- req_helper 里对包装函数的滥用
handle request函数里,每次请求调用都会新建一个 http client, 这个操作消耗是巨大的,对于 226 个 app 的同步,会创建 226 个 http client, 创建的时候至少有一倍的开销,并且每个 client 独立链接、无法复用链接.
#11691 进行了优化,把同步速度从 132s 优化到了 90s 左右,并且少创建了数百个 client,对性能的浪费更小
- icon 存储问题
这是一个灾难性问题
首先图标下载的端点,1panel oss 用的阿里云是有 etag 的支持,可以你传已有文件的 etag,让对面回 304,这样可以知道 oss 里数据没有更新,减少流量开支,同时 1panel 面板传图标给用户时也可以采用这个逻辑。由于存库导致了无法正常使用 etag,而如果需要强行支持 etag 则每次都得重算,不能复用。这也是为什么我当时关闭pr
#11136 的问题,治标不治本。
第二个icon 是 b64后存在 sqlite 里的,把数据库当做 s3 来用。数据库本身就不应该存这种东西,sqlite时结构化数据库,一个图标至少4-50kb,对db查询实际上会有拖累
并且db 阶段,在磁盘性能差的服务器上 batch 写入 200 个 icon 的 b64(大概 4MB+) 的数据,对数据库是灾难性,直接冲完了 sqlite 的 cache、并且由于数据库的写放大问题,实际读写开支可能远比 4mb要多,很大程度上锁死 busy 都是这个问题导致。
- 同步逻辑问题
1panel 最开始部署时和后期同步,全量同步可以做的更优雅。sync_detail 卡了 db 入库太久。
1panel.json里有个recommend值用于标注程序的优先级,实际上可以先同步优先级高的detail,比如小于 1000的 app(总共 31 个)
在不修改下载文件逻辑情况下,让 go 程序把 2m 的 json 中根据推荐值过滤,让同步优先更新完常用的(recommend<1000)。再起一个子任务更新不常用的(recommend>1000). 分成两个任务来执行
很多非高优先的 app 实际上用户平均只会用 1-2 个,其余根本一辈子都碰不到,然而这些需要用户付出性能去同步。
一个 demo 参考 https://github.com/HynoR/1Panel/tree/play/sy
后期如果可以改 oss 的文件格式,可以把1panel json分片,把优先级高的做一个json,其余按照类型(ai、云存储等)来分 json。按需更新才是最好的解决方案
19 03:40:20] [INFO] [AppStoreTiming] step=download_zip_start time=2026-01-19T03:40:20.079247308Z url=https://apps-assets.fit2cloud.com/dev/1panel.json.zip
[2026-01-19 03:40:20] [INFO] [AppStore] download file from https://apps-assets.fit2cloud.com/dev/1panel.json.zip
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=download_zip_done time=2026-01-19T03:40:21.137686422Z path=/opt/1panel/resource/1panel.json.zip
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=decompress_start time=2026-01-19T03:40:21.137747965Z zip=/opt/1panel/resource/1panel.json.zip
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=decompress_done time=2026-01-19T03:40:21.161343309Z dest=/opt/1panel/resource
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=json_decode_start time=2026-01-19T03:40:21.161488017Z path=/opt/1panel/resource/1panel.json
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=json_decode_done time=2026-01-19T03:40:21.258366801Z apps=226
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=sync_list_ready time=2026-01-19T03:40:21.258481174Z apps=226
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=sync_tags_done time=2026-01-19T03:40:21.265241295Z
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=sync_delete_custom_done time=2026-01-19T03:40:21.333696179Z
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=sync_load_old_apps_done time=2026-01-19T03:40:21.359801071Z old_apps=223
[2026-01-19 03:40:21] [INFO] [AppStoreTiming] step=sync_detail_start time=2026-01-19T03:40:21.361003865Z apps=226
[2026-01-19 03:42:35] [INFO] [AppStoreTiming] step=sync_detail_done time=2026-01-19T03:42:35.716323775Z
[2026-01-19 03:42:35] [INFO] [AppStoreTiming] step=sync_db_start time=2026-01-19T03:42:35.717148921Z
[2026-01-19 03:42:35] [DEBUG] [tx_1768794155786339776] tx start
github.com/1Panel-dev/1Panel/agent/utils/common.initializeTxWatch.func1/sqlite_tx_logs.go:22
github.com/1Panel-dev/1Panel/agent/app/repo.AppDetailRepo.BatchCreate/app_detail.go:61
github.com/1Panel-dev/1Panel/agent/app/service.AppService.SyncAppListFromRemote.func1/app.go:1152
github.com/1Panel-dev/1Panel/agent/app/task.(*SubTask).Execute.func1/task.go:238
[2026-01-19 03:42:35] [DEBUG] [tx_1768794155786339776] tx commit! time: 1.887128ms
[2026-01-19 03:42:35] [INFO] [AppStoreTiming] step=sync_db_commit_done time=2026-01-19T03:42:35.960385109Z
[2026-01-19 03:42:35] [INFO] [AppStoreTiming] step=sync_complete time=2026-01-19T03:42:35.963766422Z
Please describe the solution you suggest
- 已修复 refactor: improve code logic and format in app remote sync task #11691
- 最好是后期把图标放在 resource 文件夹下,后续新版逐步淘汰这个方案并清理,sqlite 记录路径和 etag,如果没有图标用默认图标占位。然后利用 etag 来进行增量更新。无需修改 oss 里任何数据格式。这个需要商讨迁移过程 (希望能在下个版本或者 2.0.19 解决)
- 在不改上游 oss数据格式或者分片的情况下,按照 recommend 拆分两个任务是可行并且几乎无损的。 分片可以等v3.
上述修改都是可以最小影响的情况下来改进 app sync 这个定时炸弹。