您的位置 首页 golang

本地搭建一个 pkg.go.dev:遇到的问题和解决

这是 pkg.go.dev 设计与实现的第二篇:本地搭建一个 pkg.go.dev。

为了更好了解这个项目,我们尝试在本地搭建一个。这里假定你在本地安装好了 postgres,同时设置了 postgres 账号的密码为 123456,并执行了上文提到的迁移程序,创建好了需要的数据表。

本地搭建可以基于 Docker,本文采用非 Docker 的方式。

Frontend

最简单的启动 Frontend 的方式是直接执行如下命令:

 $ go run cmd/frontend/main.go  

发现报错,提示 postgres 需要密码。

 2020/06/20 17:59:50 Error: database.Open("postgres-ocsql-0", "user='postgres' password=REDACTED host=' localhost ' port=5432 dbname='discovery-db' sslmode=disable options='-c statement_timeout=600000'"): pq: password authentication failed for user "postgres"
exit status 1  

我们先不处理这个问题,看看 frontend 程序有无 flag 可以设置。

 $ go run cmd/frontend/main.go -h  

输出如下:

   -dev
     enable developer mode (reload templates on each page load, serve non-minified JS/CSS, etc.)
  -direct_proxy
     if set to true, uses the module proxy referred to by this URL as a direct backend, bypassing the database
  -proxy_url string
     Uses the module proxy referred to by this URL for direct proxy mode and frontend fetches (default "#34;)
  - static  string
     path to  folder  containing static files served (default "content/static")
  -third_party string
     path to folder containing third-party libraries (default "third_party")
exit status 2  

不一一解释,英文说明很清楚。这里着重看 -direct_proxy 和 -proxy_url,通过 direct_proxy 似乎可以绕开 postgres,但由于默认的 proxy(proxy.golang.org)国内不可访问,因此同时设置一个 proxy:

 $ go run cmd/frontend/main.go -direct_proxy -proxy_url=  

输出如下:

  config : {
    "ProxyURL": "#34;,
    "IndexURL": "#34;,
    "Port": "",
    "DebugPort": "",
    "ProjectID": "",
    "ServiceID": "",
    "VersionID": "",
    "ZoneID": "",
    "InstanceID": "",
    "LocationID": "us-central1",
    "GaeEnv": "",
    "AppMonitoredResource": {
        "type": "gae_app",
        "labels": {
            "module_id": "",
            "project_id": "",
            "version_id": "",
            "zone": ""
        }
    },
    "FallbackVersionLabel": "20200620t181347",
    "DBSecret": "",
    "DBUser": "postgres",
    "DBHost": "localhost",
    "DBPort": "5432",
    "DBName": "discovery-db",
    "DBSecondaryHost": "",
    "RedisCacheHost": "",
    "RedisCachePort": "6379",
    "RedisHAHost": "",
    "RedisHAPort": "6379",
    "UseProfiler": false,
    "Quota": {
        "QPS": 10,
        "Burst": 20,
        "MaxEntries": 1000,
        "RecordOnly": true,
        "AcceptedURLs": null
    }
}
2020/06/20 18:13:47 Info: Not exporting to StackDriver: GOOGLE_CLOUD_PROJECT is unset.
2020/06/20 18:13:47 Info: Listening on addr localhost:8080  

打开浏览器访问 localhost:8080:

一切似乎很顺利。打开某个库,第一次稍微慢点,之后很快,从控制台输出的日志也能看到。

 2020/06/20 18:16:39 Info: 0 / github .com/gin-gonic/gin  request  start
2020/06/20 18:16:44 Debug: memory after fetch of github.com/gin-gonic/gin@v1.6.3: 24M
2020/06/20 18:16:44 Info: 302 /github.com/gin-gonic/gin request end
2020/06/20 18:16:44 Info: 0 /github.com/gin-gonic/gin request start
2020/06/20 18:16:45 Debug: memory after fetch of github.com/gin-gonic/gin@latest: 26M
2020/06/20 18:16:45 Info: 200 /github.com/gin-gonic/gin request end
2020/06/20 18:19:37 Info: 0 /github.com/gin-gonic/gin request start
2020/06/20 18:19:37 Info: 302 /github.com/gin-gonic/gin request end  

但访问标准库,如 database/ sql ,却报错:(同时页面显示 500)

 2020/06/20 18:24:05 Info: 0 /database/sql request start
2020/06/20 18:24:35 Debug: memory after fetch of std@latest: 17M
2020/06/20 18:24:35 Error: GetPackage("database/sql", "latest"): getModule("std", "latest"): FetchModule("std", "latest"): stdlib.Zip("latest"): Versions(): Get "#34;: dial tcp 216.239.37.1:443: i/o timeout
2020/06/20 18:24:35 Info: 500 /database/sql request end
2020/06/20 18:24:35 Info: 0 /static/img/gopher-airplane.svg request start
2020/06/20 18:24:35 Info: 200 /static/img/gopher-airplane.svg request end  

很显然,在去获取 Go 仓库信息时,因为 go.googlesource.com 在国内无法访问导致错误。然而我科学上网后并没有解决问题:

 2020/06/20 18:31:23 Info: 0 /database/sql request start
2020/06/20 18:31:25 Debug: memory after fetch of std@latest: 77M
2020/06/20 18:31:25 Error: GetPackage("database/sql", "latest"): getModule("std", "latest"): FetchModule("std", "latest"): stdlib.Zip("latest"): invalid argument: requested version unknown: "latest"
2020/06/20 18:31:25 Info: 500 /database/sql request end
2020/06/20 18:31:33 Info: 0 /database/sql request start
2020/06/20 18:31:33 Error: middleware.Panic: runtime error: invalid memory address or nil pointer dereference
2020/06/20 18:31:33 Info: 500 /database/sql request end  

我们先不细究这个问题。用上数据库试试。

现在解决数据库密码的问题。从启动时输出的 config 可以猜到,数据库信息在 config 中。前文提到,pkgsite 并没有用到配置文件,所有的配置通过环境变量来设置。

internal /config/config.go 文件中找到了这行代码:

 cfg.DBPassword = os.Getenv("GO_DISCOVERY_DATABASE_PASSWORD")  

因此这样启动 Frontend:

 $ GO_DISCOVERY_DATABASE_PASSWORD=123456 go run cmd/frontend/main.go  

这回成功了,访问 localhost:8080 也正常显示了。然而查看包都返回 404,包括标准库和第三方包。

前文讲解过,pkgsite 就是这么设计的,数据库现在是空的,需要通过 Worker 往里面填充数据。

Worker

同样的采用最简单的方式运行:

 $ GO_DISCOVERY_DATABASE_PASSWORD=123456 go run cmd/worker/main.go  
  • 注意上面 postgres 密码的问题

启动后,发现监听 8000 端口:

 2020/06/20 18:47:29 Info: Listening on addr localhost:8000  

看看长什么样:

顶部的一些链接,都是 google cloud 的,本地没有意义。

根据前面讲解,Worker 数据最终是从 Module Index 和 Module Proxy 来的,而且 Worker 不会自己触发,必须外界调用它提供的接口。上面界面中可以看到,通过点击上面的几个按钮可以执行拉取:

  • Enqueue From Module Index:从 Module Index 入队列以便处理;
  • Requeue Failed Versions:对失败的版本重入队列;
  • Reprocess Versions:重新处理;
  • Populate Standard Library:填充标准库数据;

很惨的是,Enqueue From Module Index 和 Populate Standard Library 都失败。

吐槽一句:在国内做技术真难!

除了这种方式,还有一种手动获取某个版本的办法,比如在浏览器请求 ,发现页面报 500,终端出现如下错误:

 2020/06/21 14:58:23 Error (map[fetch:github.com/gin-gonic/gin@v1.6.3]): Error executing fetch: FetchModule("github.com/gin-gonic/gin", "v1.6.3"): proxy.Client.GetInfo("github.com/gin-gonic/gin", "v1.6.3"): Client.readBody("github.com/gin-gonic/gin", "v1.6.3", "info"): ctxhttp.Get(ctx, client, "#34;): Get "#34;: dial tcp 34.64.4.113:443: i/o timeout (code 500)  

这是通过 proxy.golang.org 获取包模块信息。针对 Frontend,我们可以修改 proxy,Worker 可以修改吗?

可惜的是,Worker 并没有提供相关 flag 可以修改,但在 config.go 中发现了环境变量:GO_MODULE_PROXY_URL 和 GO_MODULE_INDEX_URL,默认分别是: 和 。proxy 我们可以设置为国内的 ,index 没有国内的可用。但对于手动获取某一个版本,设置 proxy 即可。通过如下方式重启 Worker:

 $ GO_MODULE_PROXY_URL=  

再次访问 ,显示成功:

 fetched and updated github.com/gin-gonic/gin@v1.6.3
OK  

回过头看看 ,发现正常显示了,数据库中也有相应的数据了。但这种方式一次只能搞定一个包的一个版本。

福利 :国内访问 pkg.go.dev 比较慢,有时甚至无法访问,因此我搭建了一个镜像:。

文章来源:智云一二三科技

文章标题:本地搭建一个 pkg.go.dev:遇到的问题和解决

文章地址:https://www.zhihuclub.com/99425.shtml

关于作者: 智云科技

热门文章

网站地图