从docker容器连接时使用Golang与Gin, pgxpool和issue



我写了一个简单的golang CRUD示例,使用pgxpool/pgx连接到cockroachdb。所有CRUD操作都使用Gin框架公开为REST api。通过使用curl命令或Postman,操作(GET/POST/DELETE)运行良好,数据反映在数据库中。接下来,我对这个简单的应用程序进行了dockerized,并尝试运行它。应用程序似乎在以下代码

中受到攻击
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主机= 192.165.xx。XXX user=user_name database=dbname ': dial error (timeout: dial TCP 192.165.xx)。Xxx:5432: I/O timeout).

下面是我的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外壳,可以ping的目标ip192.165.xx.xxx

请让我知道为什么pgxpool无法连接到docker容器中的DB,但在主机(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()
}
}

最新更新