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

> Составные протоколы обеспечивают более гибкую настройку TCP-доступа к серверу ClickHouse.

# Составные протоколы

<div id="overview">
  ## Обзор
</div>

Составные протоколы позволяют более гибко настраивать TCP-доступ к
серверу ClickHouse. Такая конфигурация может использоваться наряду с
обычной или полностью её заменять.

<div id="composable-protocols-section-is-denoted-as-protocols-in-configuration-xml">
  ## Настройка составных протоколов
</div>

Составные протоколы можно настраивать в XML-файле конфигурации. Раздел протоколов
в XML-файле конфигурации обозначается тегами `protocols`:

```xml theme={null}
<protocols>

</protocols>
```

<div id="basic-modules-define-protocol-layers">
  ### Настройка уровней протокола
</div>

Вы можете задавать уровни протокола с помощью базовых модулей. Например, чтобы задать
уровень HTTP, можно добавить новый базовый модуль в раздел `protocols`:

```xml theme={null}
<protocols>

  <!-- модуль plain_http -->
  <plain_http>
    <type>http</type>
  </plain_http>

</protocols>
```

Модули можно настраивать с помощью следующих параметров:

* `plain_http` - имя, на которое может ссылаться другой слой
* `type` - указывает обработчик протокола, который будет создан для обработки данных.
  Доступен следующий набор предопределённых обработчиков протоколов:
  * `tcp` - нативный обработчик протокола ClickHouse
  * `http` - HTTP-обработчик протокола ClickHouse
  * `tls` - слой шифрования TLS
  * `proxy1` - слой PROXYv1
  * `mysql` - обработчик протокола совместимости с MySQL
  * `postgres` - обработчик протокола совместимости с PostgreSQL
  * `prometheus` - обработчик протокола Prometheus
  * `interserver` - межсерверный обработчик ClickHouse

<Note>
  Обработчик протокола `gRPC` не реализован для `Composable protocols`
</Note>

<div id="endpoint-ie-listening-port-is-denoted-by-port-and-optional-host-tags">
  ### Настройка конечных точек
</div>

Конечные точки (прослушиваемые порты) обозначаются тегами `<port>` и необязательным тегом `<host>`.
Например, чтобы настроить конечную точку на ранее добавленном HTTP-слое, мы
можем изменить конфигурацию следующим образом:

```xml theme={null}
<protocols>

  <plain_http>

    <type>http</type>
    <!-- конечная точка -->
    <host>127.0.0.1</host>
    <port>8123</port>

  </plain_http>

</protocols>
```

Если тег `<host>` не указан, используется `<listen_host>` из корневой конфигурации.

<div id="layers-sequence-is-defined-by-impl-tag-referencing-another-module">
  ### Настройка последовательностей слоёв
</div>

Последовательности слоёв определяются с помощью тега `<impl>` и ссылки на другой
модуль. Например, чтобы настроить слой TLS поверх нашего модуля plain\_http,
мы можем дополнительно изменить конфигурацию следующим образом:

```xml theme={null}
<protocols>

  <!-- модуль http -->
  <plain_http>
    <type>http</type>
  </plain_http>

  <!-- модуль https, настроенный как слой tls поверх модуля plain_http -->
  <https>
    <type>tls</type>
    <impl>plain_http</impl>
    <host>127.0.0.1</host>
    <port>8443</port>
  </https>

</protocols>
```

<div id="endpoint-can-be-attached-to-any-layer">
  ### Подключение конечных точек к слоям
</div>

Конечные точки можно подключить к любому слою. Например, можно определить конечные точки для
HTTP (порт 8123) и HTTPS (порт 8443):

```xml theme={null}
<protocols>

  <plain_http>
    <type>http</type>
    <host>127.0.0.1</host>
    <port>8123</port>
  </plain_http>

  <https>
    <type>tls</type>
    <impl>plain_http</impl>
    <host>127.0.0.1</host>
    <port>8443</port>
  </https>

</protocols>
```

<div id="additional-endpoints-can-be-defined-by-referencing-any-module-and-omitting-type-tag">
  ### Определение дополнительных конечных точек
</div>

Дополнительные конечные точки можно задать, указав любой модуль и опустив
тег `<type>`. Например, можно определить конечную точку `another_http` для
модуля `plain_http` следующим образом:

```xml theme={null}
<protocols>

  <plain_http>
    <type>http</type>
    <host>127.0.0.1</host>
    <port>8123</port>
  </plain_http>

  <https>
    <type>tls</type>
    <impl>plain_http</impl>
    <host>127.0.0.1</host>
    <port>8443</port>
  </https>

  <another_http>
    <impl>plain_http</impl>
    <host>127.0.0.1</host>
    <port>8223</port>
  </another_http>

</protocols>
```

<div id="custom-http-handlers-per-endpoint">
  ### Пользовательские HTTP-обработчики для отдельных конечных точек
</div>

По умолчанию все записи протокола `type=http` используют одну и ту же конфигурацию
`<http_handlers>`. Это можно переопределить, добавив тег `<handlers>`, который ссылается
на другой раздел конфигурации. Благодаря этому каждый HTTP-порт может обслуживать
свой набор правил HTTP-маршрутизации.

Например, чтобы запустить альтернативный HTTP API на порту 8124 с собственными обработчиками:

```xml theme={null}
<protocols>

  <plain_http>
    <type>http</type>
    <host>127.0.0.1</host>
    <port>8123</port>
  </plain_http>

  <alt_http>
    <type>http</type>
    <host>127.0.0.1</host>
    <port>8124</port>
    <handlers>http_handlers_alt</handlers>
  </alt_http>

</protocols>

<!-- Default handlers used by plain_http (port 8123) -->
<http_handlers>
    <defaults/>
</http_handlers>

<!-- Alternative handlers used by alt_http (port 8124) -->
<http_handlers_alt>
    <rule>
        <url>/custom</url>
        <handler>
            <type>predefined_query_handler</type>
            <query>SELECT 'custom_endpoint'</query>
        </handler>
    </rule>
    <defaults/>
</http_handlers_alt>
```

В этом примере запросы к порту 8123 используют стандартные правила `<http_handlers>`,
а запросы к порту 8124 — правила `<http_handlers_alt>`. Если `<handlers>`
не указан, конечная точка использует значение по умолчанию — `<http_handlers>`.

Раздел пользовательских обработчиков имеет тот же формат, что и
[`<http_handlers>`](/ru/reference/settings/server-settings/settings/http#http_handlers).
Изменения в разделе пользовательских обработчиков отслеживаются при перезагрузке конфигурации, и
соответствующая конечная точка автоматически перезапускается.

<div id="default-session-user-per-endpoint">
  ### Пользователь сеанса по умолчанию для каждой конечной точки
</div>

Если клиент подключается, не указав имя пользователя (например, в HTTP-запросе
без параметра `user` или в пакете `Hello` собственного протокола с пустым именем
пользователя), сервер аутентифицирует его как пользователя сеанса по умолчанию —
`default_session_user`, [настройку сервера](/ru/reference/settings/server-settings/settings)
со значением по умолчанию `default`.

Тег `<default_session_user>` переопределяет эту настройку для отдельной конечной точки. Это
позволяет разным прослушиваемым портам обслуживать разных анонимных пользователей:

```xml theme={null}
<protocols>

  <plain_http>
    <type>http</type>
    <host>127.0.0.1</host>
    <port>8123</port>
  </plain_http>

  <readonly_http>
    <impl>plain_http</impl>
    <host>127.0.0.1</host>
    <port>8124</port>
    <default_session_user>readonly_user</default_session_user>
  </readonly_http>

</protocols>
```

В этом примере запросы без учетных данных на порту 8123 аутентифицируются от имени
глобально настроенного пользователя сеанса по умолчанию, а на порту 8124 — от имени
`readonly_user`. Клиент, явно указывающий имя пользователя, не затрагивается.

Тег ищется от модуля конечной точки в направлении модулей, на которые ссылается `impl`,
и приоритет имеет значение, расположенное ближе всего к конечной точке. Эта настройка применяется к обработчикам протоколов `tcp`, `http`,
`mysql` и `postgres`, а также к обработчикам `prometheus`, которые
аутентифицируют запросы (`remote_write`, `remote_read`, `query` и `api_v1`); конечные точки
экспорта метрик (включая конечные точки Keeper, предоставляющие только метрики) обслуживаются
без аутентификации и игнорируют эту настройку. Обработчики с фиксированным пользователем (ключ `user`
внутри `handler` правила `http_handlers` или ключ `user` внутри `handler`
правила `prometheus.handlers`) аутентифицируют запросы от имени настроенного пользователя и также игнорируют эту настройку —
в частности, пустое значение `default_session_user` не приводит к их отклонению. Эту настройку нельзя использовать с протоколом
`interserver`: межсерверные подключения аутентифицируются с помощью секрета
кластера и начального пользователя и никогда не используют пользователя сеанса по умолчанию.

<div id="some-modules-can-contain-specific-for-its-layer-parameters">
  ### Указание дополнительных параметров слоя
</div>

Некоторые модули могут содержать дополнительные параметры слоя. Например, для слоя TLS
можно указать закрытый ключ (`privateKeyFile`) и файлы сертификатов (`certificateFile`)
следующим образом:

```xml theme={null}
<protocols>

  <plain_http>
    <type>http</type>
    <host>127.0.0.1</host>
    <port>8123</port>
  </plain_http>

  <https>
    <type>tls</type>
    <impl>plain_http</impl>
    <host>127.0.0.1</host>
    <port>8443</port>
    <privateKeyFile>another_server.key</privateKeyFile>
    <certificateFile>another_server.crt</certificateFile>
  </https>

</protocols>
```
