概述
组合式协议让 ClickHouse server 的 TCP 访问配置更加灵活。此配置既可与传统配置并存,也可替代传统配置。
配置 组合式协议
组合式协议 可以在 XML 配置文件中进行配置。协议
部分在 XML 配置文件中由 protocols 标签标识:
<protocols>
</protocols>配置协议 layer
你可以使用基础模块来定义协议 layer。例如,要定义
HTTP layer,可以在 protocols 部分添加一个新的基础模块:
<protocols>
<!-- plain_http 模块 -->
<plain_http>
<type>http</type>
</plain_http>
</protocols>模块可按以下内容进行配置:
plain_http- 可供另一 layer 引用的名称type- 指定将被实例化以处理数据的协议处理程序。 可使用以下预定义协议处理程序:tcp- 原生 ClickHouse 协议处理程序http- HTTP ClickHouse 协议处理程序tls- TLS 加密 layerproxy1- PROXYv1 layermysql- MySQL 兼容协议处理程序postgres- PostgreSQL 兼容协议处理程序prometheus- Prometheus 协议处理程序interserver- ClickHouse 服务器间处理程序
端点 (监听端口) 用 <port> 和可选的 <host> 标签表示。
例如,要在前面添加的 HTTP layer 上配置端点,我们
可以按如下方式修改配置:
<protocols>
<plain_http>
<type>http</type>
<!-- 端点 -->
<host>127.0.0.1</host>
<port>8123</port>
</plain_http>
</protocols>如果省略 <host> 标签,则使用根配置中的 <listen_host>。
配置 layer 序列
layer 序列通过 <impl> 标签定义,并引用另一个
模块。例如,要在我们的 plain_http 模块之上配置一个 TLS layer,
可以进一步按如下方式修改配置:
<protocols>
<!-- http 模块 -->
<plain_http>
<type>http</type>
</plain_http>
<!-- https 模块配置为叠加在 plain_http 模块之上的 TLS layer -->
<https>
<type>tls</type>
<impl>plain_http</impl>
<host>127.0.0.1</host>
<port>8443</port>
</https>
</protocols>将端点绑定到 layer
端点可以绑定到任何 layer。例如,我们可以为 HTTP (端口 8123) 和 HTTPS (端口 8443) 定义端点:
<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>定义其他端点
通过引用任意模块并省略
<type> 标签,即可定义其他端点。例如,可以为
plain_http 模块定义一个 another_http 端点,如下所示:
<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>每个端点的自定义 HTTP 处理程序
默认情况下,所有 type=http 协议条目共享同一个 <http_handlers>
配置。你可以通过添加一个指向其他配置节的 <handlers> 标签
来覆盖这一默认行为。这样,每个 HTTP 端口都可以提供一组不同的 HTTP 路由规则。
例如,要在 8124 端口上运行一个使用独立处理程序的备用 HTTP API:
<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>。
自定义 handlers 部分的格式与
<http_handlers>
相同。重新加载 config 时,会检测到自定义 handlers 部分的更改,并自动重启
相应的端点。
每个端点的默认会话用户
如果客户端连接时未指定用户名 (例如,HTTP 请求
未包含 user 参数,或原生协议 Hello 数据包中的用户名
为空) ,服务器会将其认证为默认会话用户,即
default_session_user 服务器设置,
其默认值为 default。
<default_session_user> 标签会针对单个端点覆盖此设置。这样,
不同的监听端口即可为不同的匿名用户提供服务:
<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 端点) 无需身份验证,并会忽略此设置。使用固定用户的处理程序 (http_handlers 规则中 handler
内的 user 键,或 prometheus.handlers 规则中 handler 内的 user 键) 将以其配置的用户进行身份验证,同样会忽略此设置——尤其是,
空的 default_session_user 不会拒绝这些请求。此设置不能与
interserver 协议一起使用:服务器间连接通过集群
secret 和初始用户进行身份验证,绝不会使用默认会话用户。
指定额外的 layer 参数
某些模块可以包含额外的 layer 参数。例如,TLS layer
支持按如下方式指定私钥 (privateKeyFile) 和证书文件 (certificateFile) :
<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>