> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Настройка клиента clickhouse-go: параметры подключения, TLS, аутентификация, пул соединений, логирование и сжатие.

# Конфигурация

<div id="connection-settings">
  ## Настройки соединения
</div>

<Tip>
  Подробное описание каждого параметра, включая значения по умолчанию, параметры DSN, рекомендации и устранение неполадок, см. в [Справочнике по конфигурации](/ru/integrations/language-clients/go/config-reference).
</Tip>

При открытии соединения для управления поведением клиента можно использовать структуру `Options`. Доступны следующие настройки:

| Параметр               | Тип                                                | По умолчанию       | Описание                                                                                                                                                                                |
| ---------------------- | -------------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Protocol`             | `Protocol`                                         | `Native`           | Транспортный протокол: `Native` (TCP) или `HTTP`. См. [TCP и HTTP](#tcp-vs-http).                                                                                                       |
| `Addr`                 | `[]string`                                         | —                  | Срез адресов в формате `host:port`. О подключении к нескольким узлам см. [Подключение к нескольким узлам](#connecting-to-multiple-nodes).                                               |
| `Auth`                 | `Auth`                                             | —                  | Учетные данные для аутентификации (`Database`, `Username`, `Password`). См. [Аутентификация](#authentication).                                                                          |
| `TLS`                  | `*tls.Config`                                      | `nil`              | Настройка TLS. Значение, отличное от `nil`, включает TLS. См. [TLS](#using-tls).                                                                                                        |
| `DialContext`          | `func(ctx, addr) (net.Conn, error)`                | —                  | Пользовательская функция dial для управления установкой TCP-соединений.                                                                                                                 |
| `DialTimeout`          | `time.Duration`                                    | `30s`              | Максимальное время ожидания при открытии нового соединения.                                                                                                                             |
| `MaxOpenConns`         | `int`                                              | `MaxIdleConns + 5` | Максимальное число одновременно открытых соединений.                                                                                                                                    |
| `MaxIdleConns`         | `int`                                              | `5`                | Количество бездействующих соединений, сохраняемых в пуле.                                                                                                                               |
| `ConnMaxLifetime`      | `time.Duration`                                    | `1h`               | Максимальное время жизни соединения в пуле. См. [Пул соединений](#connection-pooling).                                                                                                  |
| `ConnOpenStrategy`     | `ConnOpenStrategy`                                 | `ConnOpenInOrder`  | Стратегия выбора узла из `Addr`. См. [Подключение к нескольким узлам](#connecting-to-multiple-nodes).                                                                                   |
| `BlockBufferSize`      | `uint8`                                            | `2`                | Количество блоков, декодируемых параллельно. Более высокие значения повышают пропускную способность за счет памяти. Можно переопределить для каждого запроса через контекст.            |
| `Settings`             | `Settings`                                         | —                  | Карта настроек ClickHouse, применяемых ко всем запросам. Отдельные запросы могут переопределять их через [контекст](/ru/integrations/language-clients/go/clickhouse-api#using-context). |
| `Compression`          | `*Compression`                                     | `nil`              | Сжатие на уровне блоков. См. [Сжатие](#compression).                                                                                                                                    |
| `ReadTimeout`          | `time.Duration`                                    | —                  | Максимальное время ожидания чтения с сервера за один вызов.                                                                                                                             |
| `FreeBufOnConnRelease` | `bool`                                             | `false`            | Если установлено `true`, буфер памяти соединения возвращается в пул после каждого запроса. Снижает использование памяти ценой небольшой дополнительной нагрузки на CPU.                 |
| `Logger`               | `*slog.Logger`                                     | `nil`              | Структурированный логгер (Go `log/slog`). См. [Логирование](#logging).                                                                                                                  |
| `Debug`                | `bool`                                             | `false`            | **Устарело.** Используйте `Logger`. Включает устаревший отладочный вывод в stdout.                                                                                                      |
| `Debugf`               | `func(string, ...any)`                             | —                  | **Устарело.** Используйте `Logger`. Пользовательская функция отладочного логирования. Требует `Debug: true`.                                                                            |
| `GetJWT`               | `GetJWTFunc`                                       | —                  | Функция обратного вызова, возвращающая JWT-токен для аутентификации в ClickHouse Cloud (только HTTPS).                                                                                  |
| `HttpHeaders`          | `map[string]string`                                | —                  | Дополнительные HTTP-заголовки, отправляемые с каждым запросом (только HTTP-транспорт).                                                                                                  |
| `HttpUrlPath`          | `string`                                           | —                  | Дополнительный путь URL, добавляемый к HTTP-запросам (только HTTP-транспорт).                                                                                                           |
| `HttpMaxConnsPerHost`  | `int`                                              | —                  | Переопределяет `MaxConnsPerHost` в базовом `http.Transport` (только HTTP-транспорт).                                                                                                    |
| `TransportFunc`        | `func(*http.Transport) (http.RoundTripper, error)` | —                  | Пользовательская фабрика HTTP-транспорта. Транспорт по умолчанию передается для выборочного переопределения (только HTTP-транспорт).                                                    |
| `HTTPProxyURL`         | `*url.URL`                                         | —                  | URL HTTP-прокси для всех запросов (только HTTP-транспорт).                                                                                                                              |

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{fmt.Sprintf("%s:%d", env.Host, env.Port)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
    DialContext: func(ctx context.Context, addr string) (net.Conn, error) {
        dialCount++
        var d net.Dialer
        return d.DialContext(ctx, "tcp", addr)
    },
    Debug: true,
    Debugf: func(format string, v ...interface{}) {
        fmt.Printf(format, v)
    },
    Settings: clickhouse.Settings{
        "max_execution_time": 60,
    },
    Compression: &clickhouse.Compression{
        Method: clickhouse.CompressionLZ4,
    },
    DialTimeout:      time.Duration(10) * time.Second,
    MaxOpenConns:     5,
    MaxIdleConns:     5,
    ConnMaxLifetime:  time.Duration(10) * time.Minute,
    ConnOpenStrategy: clickhouse.ConnOpenInOrder,
    BlockBufferSize: 10,
})
if err != nil {
    return err
}
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/main/examples/clickhouse_api/connect_settings.go)

<div id="using-tls">
  ## TLS
</div>

На низком уровне все методы подключения клиента (`DSN/OpenDB/Open`) используют [пакет Go tls](https://pkg.go.dev/crypto/tls) для установки защищённого соединения. Клиент понимает, что нужно использовать TLS, если структура Options содержит ненулевой указатель `tls.Config`.

```go theme={null}
env, err := GetNativeTestEnvironment()
if err != nil {
    return err
}
cwd, err := os.Getwd()
if err != nil {
    return err
}
t := &tls.Config{}
caCert, err := ioutil.ReadFile(path.Join(cwd, "../../tests/resources/CAroot.crt"))
if err != nil {
    return err
}
caCertPool := x509.NewCertPool()
successful := caCertPool.AppendCertsFromPEM(caCert)
if !successful {
    return err
}
t.RootCAs = caCertPool
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{fmt.Sprintf("%s:%d", env.Host, env.SslPort)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
    TLS: t,
})
if err != nil {
    return err
}
v, err := conn.ServerVersion()
if err != nil {
    return err
}
fmt.Println(v.String())
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/main/examples/clickhouse_api/ssl.go)

Этой минимальной конфигурации `TLS.Config` обычно достаточно для подключения к защищённому native-порту (обычно 9440) на сервере ClickHouse. Если у сервера ClickHouse нет действительного сертификата (истёк срок действия, неверное имя хоста, сертификат не подписан общепризнанным корневым центром сертификации), для `InsecureSkipVerify` можно установить значение `true`, но делать это настоятельно не рекомендуется.

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{fmt.Sprintf("%s:%d", env.Host, env.SslPort)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
    TLS: &tls.Config{
        InsecureSkipVerify: true,
    },
})
if err != nil {
    return err
}
v, err := conn.ServerVersion()
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/main/examples/clickhouse_api/ssl_no_verify.go)

Если требуются дополнительные параметры TLS, прикладной код должен задать нужные поля в структуре `tls.Config`. Это может включать указание конкретных наборов шифров, принудительное использование определённой версии TLS (например, 1.2 или 1.3), добавление внутренней цепочки CA‑сертификатов, добавление клиентского сертификата (и приватного ключа), если этого требует сервер ClickHouse, а также большинство других параметров для более специализированной конфигурации безопасности.

<div id="authentication">
  ## Аутентификация
</div>

Укажите структуру Auth в сведениях о подключении, чтобы задать имя пользователя и пароль.

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{fmt.Sprintf("%s:%d", env.Host, env.Port)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
})
if err != nil {
    return err
}

v, err := conn.ServerVersion()
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/main/examples/clickhouse_api/auth.go)

<div id="connecting-to-multiple-nodes">
  ## Подключение к нескольким узлам
</div>

Можно указать несколько адресов с помощью структуры `Addr`.

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{"127.0.0.1:9001", "127.0.0.1:9002", fmt.Sprintf("%s:%d", env.Host, env.Port)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
})
if err != nil {
    return err
}
v, err := conn.ServerVersion()
if err != nil {
    return err
}
fmt.Println(v.String())
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/1c0d81d0b1388dbb9e09209e535667df212f4ae4/examples/clickhouse_api/multi_host.go#L26-L45)

Доступны три стратегии подключения:

* `ConnOpenInOrder` (по умолчанию)  - адреса используются по порядку. Последующие адреса задействуются только в случае сбоя при подключении к адресам, расположенным выше в списке. По сути, это стратегия переключения при отказе.
* `ConnOpenRoundRobin` - Нагрузка равномерно распределяется между адресами по стратегии round-robin.
* `ConnOpenRandom` - Узел случайным образом выбирается из списка адресов.

Этим можно управлять с помощью параметра `ConnOpenStrategy`

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr:             []string{"127.0.0.1:9001", "127.0.0.1:9002", fmt.Sprintf("%s:%d", env.Host, env.Port)},
    ConnOpenStrategy: clickhouse.ConnOpenRoundRobin,
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
})
if err != nil {
    return err
}
v, err := conn.ServerVersion()
if err != nil {
    return err
}
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/1c0d81d0b1388dbb9e09209e535667df212f4ae4/examples/clickhouse_api/multi_host.go#L50-L67)

<div id="connection-pooling">
  ## Пул соединений
</div>

Клиент поддерживает пул соединений и при необходимости повторно использует соединения между запросами. Одновременно используется не более `MaxOpenConns`, а максимальный размер пула задается параметром `MaxIdleConns`. Для выполнения каждого запроса клиент получает соединение из пула, а затем возвращает его обратно для повторного использования. Соединение используется на протяжении всего жизненного цикла батча и освобождается при вызове `Send()`.

Нет гарантии, что для последующих запросов из пула будет использоваться одно и то же соединение, если только пользователь не задаст `MaxOpenConns=1`. Это требуется редко, но может быть необходимо при использовании временных таблиц.

Также обратите внимание, что значение `ConnMaxLifetime` по умолчанию составляет 1 час. Это может приводить к неравномерному распределению нагрузки на ClickHouse, если узлы покидают кластер. Например, если узел становится недоступным, соединения перераспределяются на другие узлы. По умолчанию эти соединения сохраняются и не обновляются в течение 1 часа, даже если проблемный узел вернется в кластер. При высокой рабочей нагрузке стоит рассмотреть уменьшение этого значения.

Пул соединений поддерживается как для Native (TCP), так и для HTTP-протокола.

<div id="logging">
  ## Логирование
</div>

Клиент поддерживает структурированное логирование через стандартный пакет Go `log/slog`, используя поле `Logger` в `Options`. Поля `Debug` и `Debugf` считаются устаревшими, но по-прежнему работают для обратной совместимости (приоритет: `Debugf` > `Logger` > no-op).

```go theme={null}
import (
    "log/slog"
    "os"
)

// Структурированное логирование в формате JSON
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
    Level: slog.LevelDebug,
}))

conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{fmt.Sprintf("%s:%d", env.Host, env.Port)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
    Logger: logger,
})
```

Вы также можете добавить в логгер контекст уровня приложения:

```go theme={null}
baseLogger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
    Level: slog.LevelInfo,
}))
enrichedLogger := baseLogger.With(
    slog.String("service", "my-service"),
    slog.String("environment", "production"),
)

conn, err := clickhouse.Open(&clickhouse.Options{
    // ...
    Logger: enrichedLogger,
})
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/main/examples/clickhouse_api/logger_test.go)

<div id="compression">
  ## Сжатие
</div>

Поддержка методов сжатия зависит от используемого протокола. Для собственного протокола клиент поддерживает сжатие `LZ4` и `ZSTD`. Оно выполняется только на уровне блоков. Сжатие можно включить, добавив конфигурацию `Compression` к соединению.

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr: []string{fmt.Sprintf("%s:%d", env.Host, env.Port)},
    Auth: clickhouse.Auth{
        Database: env.Database,
        Username: env.Username,
        Password: env.Password,
    },
    Compression: &clickhouse.Compression{
        Method: clickhouse.CompressionZSTD,
    },
    MaxOpenConns: 1,
})
ctx := context.Background()
defer func() {
    conn.Exec(ctx, "DROP TABLE example")
}()
conn.Exec(context.Background(), "DROP TABLE IF EXISTS example")
if err = conn.Exec(ctx, `
    CREATE TABLE example (
            Col1 Array(String)
    ) Engine Memory
    `); err != nil {
    return err
}
batch, err := conn.PrepareBatch(ctx, "INSERT INTO example")
if err != nil {
    return err
}
defer batch.Close()

for i := 0; i < 1000; i++ {
    if err := batch.Append([]string{strconv.Itoa(i), strconv.Itoa(i + 1), strconv.Itoa(i + 2), strconv.Itoa(i + 3)}); err != nil {
        return err
    }
}
if err := batch.Send(); err != nil {
    return err
}
```

[Полный пример](https://github.com/ClickHouse/clickhouse-go/blob/main/examples/clickhouse_api/compression.go)

При использовании HTTP-транспорта доступны дополнительные методы сжатия: `gzip`, `deflate` и `br`. Подробнее см. в разделе [Database/SQL API — Compression](/ru/integrations/language-clients/go/database-sql-api#compression).

<div id="tcp-vs-http">
  ## TCP vs HTTP
</div>

Транспорт переключается одним параметром конфигурации — всё остальное в этом руководстве применимо к обоим вариантам. Вот что меняется:

|                                | TCP (собственный протокол)              | HTTP                                                                          |
| :----------------------------- | :-------------------------------------- | :---------------------------------------------------------------------------- |
| **Порт по умолчанию**          | 9000 (без шифрования), 9440 (TLS)       | 8123 (без шифрования), 8443 (TLS)                                             |
| **Включение**                  | По умолчанию — не указывайте `Protocol` | `Protocol: clickhouse.HTTP` или используйте DSN с `http://`                   |
| **Сжатие**                     | `lz4`, `zstd`                           | `lz4`, `zstd`, `gzip`, `deflate`, `br`                                        |
| **Сеансы**                     | Встроены (всегда активны)               | Явно — передавайте `session_id` как параметр настройки                        |
| **HTTP-заголовки**             | —                                       | `HttpHeaders`, `HttpUrlPath`, `HttpMaxConnsPerHost`                           |
| **Пользовательский транспорт** | —                                       | `TransportFunc`                                                               |
| **JWT-аутентификация**         | —                                       | `GetJWT` (HTTPS в ClickHouse Cloud)                                           |
| **OpenTelemetry (`WithSpan`)** | ✅                                       | Сервер это поддерживает, но клиент пока не отправляет заголовок `traceparent` |

Чтобы переключить любой API на HTTP:

```go theme={null}
// API ClickHouse через HTTP
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr:     []string{"host:8123"},
    Protocol: clickhouse.HTTP,
    // ... аутентификация и т.д.
})

// database/sql через HTTP — через Options
conn := clickhouse.OpenDB(&clickhouse.Options{
    Addr:     []string{"host:8123"},
    Protocol: clickhouse.HTTP,
    // ... аутентификация и т.д.
})

// database/sql через HTTP — через DSN
conn, err := sql.Open("clickhouse", "http://host:8123?username=user&password=pass")
```
