我编写了一个简单的 golang CRUD 示例,使用
cockroachdb
连接到 pgxpool/pgx
。
所有 CRUD 操作都使用 Gin 框架作为 REST api 公开。
通过使用curl命令或Postman,操作(GET/POST/DELETE)运行良好并且数据反映在数据库中。
接下来,我对这个简单的应用程序进行了 docker 化并尝试运行。该应用程序似乎在下面的代码中受到攻击
func Connection(conn_string string) gin.HandlerFunc {
log.Println("Connection: 0", conn_string)
config, err := pgxpool.ParseConfig(conn_string)
log.Println("Connection: 1", config.ConnString())
if err != nil {
log.Fatal(err)
}
log.Println("Connection: 2")
pool, err := pgxpool.ConnectConfig(context.Background(), config) // gets struck here
if err != nil {
log.Fatal(err)
}
log.Println("Connection: 3")
return func(c *gin.Context) {
c.Set("pool", pool)
c.Next()
}
}
在该行打印
Connection: 2
后,代码似乎被冻结了
pool, err := pgxpool.ConnectConfig(context.Background(), config)
几分钟后,我收到错误消息
FATA[0120] failed to connect to
host=192.165.xx.xxx user=user_name database=dbname`:拨号错误(超时:拨号 tcp 192.165.xx.xxx:5432:i/o 超时)。
下面是我的 docker 文件
FROM golang as builder
WORKDIR /catalog
COPY main.go ./
COPY go.mod ./
COPY go.sum ./
RUN go get .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o catalog .
# deployment image
FROM scratch
#FROM alpine:3.17.1
# copy ca-certificates from builder
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
WORKDIR /bin/
COPY --from=builder /catalog .
CMD [ "./catalog" ]
#CMD go run /catalog/main.go
EXPOSE 8080
注意,我尝试进入容器
bash
shell,并且可以 ping
目标 ip 192.165.xx.xxx
。
请告诉我为什么 pgxpool 无法连接到 docker 容器中的数据库,但在主机(ubuntu)中工作却没有任何问题。
Update-2:真正的问题是在启动应用程序时传递参数。当参数正确传递后,就开始工作了。
Update-1:我在运行查询时仍然看到问题,并且也可以在 docker 之外生成它。
我可以使用升级的 pgxpool v5 而不是 v4 来修复它。 我所做的只是
go get -u github.com/jackc/pgx/v5/pgxpool
,代码中也使用了它
它按预期工作。
这可能是一个已知的错误,但找不到任何相关问题将其包含在本文中。
下面是最终运行的代码
func Connection(conn_string string) gin.HandlerFunc {
log.Println("Connection: 0", conn_string)
config, err := pgxpool.ParseConfig(conn_string)
log.Println("Connection: 1", config.ConnString())
if err != nil {
log.Fatal(err)
}
log.Println("Connection: 2")
//pool, err := pgxpool.ConnectConfig(context.Background(), config)
pool, err := pgxpool.NewWithConfig(context.Background(), config)
if err != nil {
log.Fatal(err)
}
log.Println("Connection: 3")
return func(c *gin.Context) {
c.Set("pool", pool)
c.Next()
}
}