ustclug / discussions

Issue Tracker for USTC LUG
47 stars 4 forks source link

Rubygems 速度缓慢 #438

Closed taoky closed 2 months ago

taoky commented 11 months ago

问题描述 / Bug description

Ref:

tldr: rubygems 同步单纯同步包是不够的,虽然也「能用」,但是速度甚至会显著慢于官方源,因为每个依赖的每个版本都要被检查。直接在文件系统上同步 API 相关文件也不现实(相比于 homebrew,rubygems 包太多了,超过十万个),如果要解决的话只能做反代。

但是需要反代哪些路径?单纯如 https://github.com/tuna/issues/issues/374 所述只反代 https://api.rubygems.org/api/v1/dependencies 可能不够——gem 下载依赖时似乎还会访问别的文件。同时,同步采用的 gem rubygems-mirror 最后一次 commit 是 2021 年,尚不清楚它同步是否有遗漏什么东西。

iBug commented 2 months ago

在服务器上加了这些 302 重定向:

location /rubygems/ {
    rewrite ^/rubygems(/versions|/info/.*)$ $scheme://rubygems.org$1 redirect;
    rewrite ^/rubygems(/api/.*)$ $scheme://api.rubygems.org$1 redirect;
}

在我的 Jekyll 网站仓库里删除 Gemfile.lockvendor/ 后,测试 time bundle -V 比直接使用 rubygems.org 快了一些,并且其中的 Resolving dependencies... 这一行输出也很快就过去了。

$ bundle --version
Bundler version 2.4.20

不过从 nginx 日志来看,这个版本的 Bundler 只访问了 /rubygems/versions 这一个路径,应该可以考虑在每次同步之后把它也下载下来。另外的 /info//api/ 可能是旧版本 Bundler 用的。

taoky commented 2 months ago

不过从 nginx 日志来看,这个版本的 Bundler 只访问了 /rubygems/versions 这一个路径,应该可以考虑在每次同步之后把它也下载下来。另外的 /info//api/ 可能是旧版本 Bundler 用的。

可能需要修改 https://github.com/rubygems/rubygems-mirror

iBug commented 2 months ago

我刚手动下载了 https://rubygems.org/versions 放服务器上,然后 Bundler 说

The checksum of /versions does not match the checksum provided by the server! Something is wrong (local checksum is "\"725c1287c97f42497f6d57d7a1490ca0\"", was expecting "\"66bb51b6-12fd945\"").

有点不知道怎么回事。

从 HTTP response header 来看,https://mirrors.tencent.com/rubygems/versions 应该是直接反代了 https://rubygems.org/versions,多了 digestrepr-digest 两个 header。

taoky commented 2 months ago

或者 versions 就反代,剩下的文件用 yukina 做 caching?

iBug commented 2 months ago

另外,这个版本的 Bundler 在使用 /versions 失败后会回退到 /api/v1/dependencies,但是这个 API 已经下线了

然后仔细观察 Bundler 的报错,发现 725c1287c97f42497f6d57d7a1490ca0 正是文件的 MD5,而 66bb51b6-12fd945 是 Nginx 返回的 ETag,它是个简单的 mtime + length 组合(无语了)

考虑搓点 Lua 把 RubyGems 想要的 header 加上就差不多了。

iBug commented 2 months ago
$ curl -vso /dev/null https://mirrors.ustc.edu.cn/rubygems/versions
[...]
< HTTP/2 200
< server: openresty
< date: Tue, 13 Aug 2024 13:32:57 GMT
< content-type: application/octet-stream
< content-length: 19913405
< last-modified: Tue, 13 Aug 2024 13:31:04 GMT
< etag: "b564ec94028e6c43b72bb48730880e08"
< accept-ranges: bytes
<
$ bundle
HTTP GET https://mirrors.ustc.edu.cn/rubygems/versions
HTTP 206 Partial Content https://mirrors.ustc.edu.cn/rubygems/versions
Fetching gem metadata from https://mirrors.ustc.edu.cn/rubygems/
Looking up gems [...]
iBug commented 2 months ago

服务器配置我在 tuna 的 issue 那里回复了。

经过反复测试,确认实际需要的配置是(路径全部相对于 /rubygems/):

相关 issue: