Я написал простой пример golang CRUD, подключающийся к cockroachdb
с помощью pgxpool/pgx
.
Все операции CRUD предоставляются как REST API с использованием Gin framework.
При использовании команды curl или Postman операции (GET/POST/DELETE) работают хорошо, и данные отражаются в базе данных.
Затем я докеризовал это простое приложение и попытался запустить его. Приложение кажется пораженным в приведенном ниже коде
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: время ожидания ввода/вывода).
Ниже мой файл докера
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
целевой ip 192.165.xx.xxx
.
Пожалуйста, дайте мне знать, почему pgxpool не может подключиться к БД в контейнере докера, но без проблем работает на хосте (ubuntu).
Обновление-2: реальная проблема заключается в передаче аргументов при запуске приложения. Когда аргументы передаются правильно, это начинает работать.
Обновление-1: я все еще вижу проблемы при выполнении запроса и могу также создать его вне докера.
Я мог бы исправить это с помощью обновленного 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()
}
}
Есть один такой связанный инцидент stackoverflow.com/questions/64065419/… и разница в том, что для меня CRDB уже существует и не может подключиться.