使用Golang如何从内置源码构建应用程序?
使用Golang如何从内置源码构建应用程序? 我们遇到的问题是,随着数据量的增加,从Go应用程序到PostgreSQL数据库的查询变得越来越慢。奇怪的是,即使是在约10行的表和另一个约400行的数据库中,也存在显著差异。一个简单的"SELECT * FROM table LIMIT 1 OFFSET 0"查询在较小的表上耗时0.001秒,但在较大的表上却需要约0.01秒。
我们发现问题不在于:
- 数据库本身(通过psql中的计时功能测量)- 在两种情况下耗时大致相同
- PostgreSQL驱动(lib/pg)- 我在此处进行了输出:
if len(args) == 0 {
start := time.Now()
r, err := cn.simpleQuery(query)
log.Printf("TIME ELAPSED simpleQuery for query \"%s\": %v\n", query, time.Since(start))
return r, err
}
也许这是错误的方法?但即便如此 - 在两种情况下耗时几乎相同。
这使得问题很难排查,因为它只出现在一些根本没有安装Go的服务器上。
所以我下一个想法是在sql包中添加一些类似的输出。问题显然在于编译时使用了内置源代码。
那么有没有人知道如何在编译后的二进制文件中测量内置包的耗时?
更多关于使用Golang如何从内置源码构建应用程序?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我已经解决了这个问题。你需要在 go build 命令中使用 -a 参数。
更多关于使用Golang如何从内置源码构建应用程序?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang中,要测量内置包的耗时,可以通过构建自定义的Go工具链来实现。这需要修改Go标准库的源代码并重新编译Go工具链。以下是具体步骤和示例代码:
1. 获取Go源代码
首先,下载Go的源代码:
git clone https://go.googlesource.com/go
cd go
git checkout <your-go-version> # 例如:go1.19
2. 修改内置包代码
以database/sql包为例,添加计时逻辑。编辑src/database/sql/sql.go文件,在关键函数中插入时间测量代码。例如,在(*DB).query方法中添加:
func (db *DB) query(ctx context.Context, query string, args []any, strategy connReuseStrategy) (*Rows, error) {
start := time.Now()
defer func() {
log.Printf("SQL QUERY TIME: %s, ELAPSED: %v", query, time.Since(start))
}()
// 原有代码保持不变
dc, err := db.conn(ctx, strategy)
if err != nil {
return nil, err
}
return db.queryDC(ctx, dc, dc.releaseConn, query, args)
}
3. 编译自定义Go工具链
在Go源代码根目录执行:
cd src
./make.bash
这将生成自定义的Go二进制文件,位于../bin/go。
4. 使用自定义工具链构建应用
使用新编译的Go工具链重新构建你的应用程序:
export PATH="/path/to/custom/go/bin:$PATH"
go build -o myapp main.go
5. 运行并分析输出
运行应用程序时,将输出类似:
SQL QUERY TIME: SELECT * FROM table LIMIT 1 OFFSET 0, ELAPSED: 10.5ms
注意事项
- 这种方法会修改整个Go工具链,影响所有使用该工具链编译的程序。
- 确保在生产环境使用前充分测试。
- 对于更精细的测量,可以只针对特定包(如
database/sql)进行修改。
通过这种方式,你可以精确测量内置包在查询执行过程中的耗时,帮助定位性能瓶颈。

