客户端

ClickHouse提供了两个网络接口(两个都可以选择包装在TLS中以增加安全性):

  • HTTP, 包含文档,易于使用。
  • Native TCP,简单,方便使用。

在大多数情况下,建议使用适当的工具或库,而不是直接与它们交互。Yandex官方支持的项目有:

  • 命令行客户端
  • JDBC驱动
  • ODBC驱动
  • C++客户端

还有一些广泛的第三方库可供ClickHouse使用:

  • 客户端库
  • 第三方集成库
  • 可视化UI

命令行客户端

ClickHouse提供了一个原生命令行客户端clickhouse-client客户端支持命令行支持的更多信息详见Configuring。

安装部署后,系统默认会安装clickhouse-client(同时它属于clickhouse-client安装包中)。

$ clickhouse-client
ClickHouse client version 19.17.1.1579 (official build).
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 19.17.1 revision 54428.

:)

不同的客户端和服务器版本彼此兼容,但是一些特性可能在旧客户机中不可用。我们建议使用与服务器应用相同版本的客户端。当你尝试使用旧版本的客户端时,服务器上的clickhouse-client会显示如下信息:

ClickHouse client version is older than ClickHouse server. It may lack support for new features.

使用方式

客户端可以在交互和非交互(批处理)模式下使用。要使用批处理模式,请指定query参数,或将数据发送到stdin(它会验证stdin是否是终端),或两者同时进行。与HTTP接口类似,当使用query参数并向stdin发送数据时,客户端请求就是一行一行的stdin输入作为query的参数。这种方式在大规模的插入请求中非常方便。

使用客户端插入数据的示例:

$ echo -ne "1, 'some text', '2016-08-14 00:00:00'\n2, 'some more text', '2016-08-14 00:00:01'" | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";

$ cat <<_EOF | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";
3, 'some text', '2016-08-14 00:00:00'
4, 'some more text', '2016-08-14 00:00:01'
_EOF

$ cat file.csv | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";

在批量模式中,默认的数据格式是TabSeparated分隔的。您可以根据查询来灵活设置FORMAT格式。

默认情况下,在批量模式中只能执行单个查询。为了从一个Script中执行多个查询,可以使用--multiquery参数。除了INSERT请求外,这种方式在任何地方都有用。查询的结果会连续且不含分隔符地输出。 同样的,为了执行大规模的查询,您可以为每个查询执行一次clickhouse-client。但注意到每次启动clickhouse-client程序都需要消耗几十毫秒时间。

在交互模式下,每条查询过后,你可以直接输入下一条查询命令。

如果multiline没有指定(默认没指定):为了执行查询,按下Enter即可。查询语句不是必须使用分号结尾。如果需要写一个多行的查询语句,可以在换行之前输入一个反斜杠\,然后在您按下Enter键后,您就可以输入当前语句的下一行查询了。

如果指定了multiline:为了执行查询,需要以分号结尾并且按下Enter键。如果行末没有分号,将认为当前语句并没有输入完而要求继续输入下一行。

若只运行单个查询,分号后面的所有内容都会被忽略。

您可以指定\G来替代分号或者在分号后面,这表示使用Vertical的格式。在这种格式下,每一个值都会打印在不同的行中,这种方式对于宽表来说很方便。这个不常见的特性是为了兼容MySQL命令而加的。

命令行客户端是基于replxx(类似于readline)。换句话说,它可以使用我们熟悉的快捷键方式来操作以及保留历史命令。 历史命令会写入在~/.clickhouse-client-history中。

默认情况下,输出的格式是PrettyCompact。您可以通过FORMAT设置根据不同查询来修改格式,或者通过在查询末尾指定\G字符,或通过在命令行中使用--format--vertical参数,或使用客户端的配置文件。

若要退出客户端,使用Ctrl+D(或Ctrl+C),或者输入以下其中一个命令:exitquitlogoutучшейгшедщпщгеexit;quit;logout;qQ:q

当执行一个查询的时候,客户端会显示:

  1. 进度, 进度会每秒更新十次(默认情况下)。对于很快的查询,进度可能没有时间显示。
  2. 为了调试会显示解析且格式化后的查询语句。
  3. 指定格式的输出结果。
  4. 输出结果的行数的行数,经过的时间,以及查询处理的速度。

您可以通过Ctrl+C来取消一个长时间的查询。然而,您依然需要等待服务端来中止请求。在某个阶段去取消查询是不可能的。如果您不等待并再次按下Ctrl + C,客户端将会退出。

命令行客户端允许通过外部数据(外部临时表)来查询。更多相关信息,请参考 «外部数据查询处理».

查询参数

您可以创建带有参数的查询,并将值从客户端传递给服务器。这允许避免在客户端使用特定的动态值格式化查询。例如:

$ clickhouse-client --param_parName="[1, 2]"  -q "SELECT * FROM table WHERE a = {parName:Array(UInt16)}"
查询语法

像平常一样格式化一个查询,然后把你想要从app参数传递到查询的值用大括号格式化,格式如下:

{<name>:<data type>}
  • name — 占位符标识符。在控制台客户端,使用--param_<name> = value来指定
  • data type — 数据类型参数值。例如,一个数据结构(integer, ('string', integer))拥有Tuple(UInt8, Tuple(String, UInt8))数据类型(你也可以用另一个integer类型)。
示例
$ clickhouse-client --param_tuple_in_tuple="(10, ('dt', 10))" -q "SELECT * FROM table WHERE val = {tuple_in_tuple:Tuple(UInt8, Tuple(String, UInt8))}"

配置

您可以通过以下方式传入参数到clickhouse-client中(所有的参数都有默认值):

  • 通过命令行
    命令行参数会覆盖默认值和配置文件的配置。
  • 配置文件
    配置文件的配置会覆盖默认值

命令行参数

  • --host, -h -– 服务端的host名称, 默认是localhost。您可以选择使用host名称或者IPv4或IPv6地址。
  • --port – 连接的端口,默认值:9000。注意HTTP接口以及TCP原生接口使用的是不同端口。
  • --user, -u – 用户名。 默认值:default
  • --password – 密码。 默认值:空字符串。
  • --query, -q – 使用非交互模式查询。
  • --database, -d – 默认当前操作的数据库. 默认值:服务端默认的配置(默认是default)。
  • --multiline, -m – 如果指定,允许多行语句查询(Enter仅代表换行,不代表查询语句完结)。
  • --multiquery, -n – 如果指定, 允许处理用;号分隔的多个查询,只在非交互模式下生效。
  • --format, -f – 使用指定的默认格式输出结果。
  • --vertical, -E – 如果指定,默认情况下使用垂直格式输出结果。这与–format=Vertical相同。在这种格式中,每个值都在单独的行上打印,这种方式对显示宽表很有帮助。
  • --time, -t – 如果指定,非交互模式下会打印查询执行的时间到stderr中。
  • --stacktrace – 如果指定,如果出现异常,会打印堆栈跟踪信息。
  • --config-file – 配置文件的名称。
  • --secure – 如果指定,将通过安全连接连接到服务器。
  • --history_file — 存放命令历史的文件的路径。
  • --param_<name> — 查询参数配置查询参数.

配置文件

clickhouse-client使用以下第一个配置文件:

  • 通过--config-file参数指定。
  • ./clickhouse-client.xml
  • ~/.clickhouse-client/config.xml
  • /etc/clickhouse-client/config.xml

配置文件示例:

<config>
    <user>username</user>
    <password>password</password>
    <secure>False</secure>
</config>

原生接口(TCP)

原生接口协议用于命令行客户端,用于分布式查询处理期间的服务器间通信,以及其他C++ 程序。不幸的是,原生ClickHouse协议还没有正式的规范,但它可以从ClickHouse源代码从这里开始或通过拦截和分析TCP流量进行逆向工程。

HTTP客户端

HTTP接口允许您在任何编程语言的任何平台上使用ClickHouse。我们使用它在Java和Perl以及shell脚本中工作。在其他部门中,HTTP接口用于Perl、Python和Go。HTTP接口比原生接口受到更多的限制,但它具有更好的兼容性。

默认情况下,clickhouse-server会在8123端口上监控HTTP请求(这可以在配置中修改)。

如果你发送了一个未携带任何参数的GET /请求,它会返回一个字符串 «Ok.»(结尾有换行)。可以将它用在健康检查脚本中。

如果你发送了一个未携带任何参数的GET /请求,它返回响应码200和OK字符串定义,可在Http服务响应配置定义(在末尾添加换行)

$ curl 'http://localhost:8123/'
Ok.

Web UI 可以通过这个地址访问: http://localhost:8123/play. 在运行状况检查脚本中,使用GET /ping请求。这个处理方法总是返回 "Ok"。(以换行结尾)。可从18.12.13版获得。请参见' /replicas_status '检查复制集的延迟。

$ curl 'http://localhost:8123/ping'
Ok.
$ curl 'http://localhost:8123/replicas_status'
Ok.

通过URL中的 query 参数来发送请求,或者发送POST请求,或者将查询的开头部分放在URL的query参数中,其他部分放在POST中(我们会在后面解释为什么这样做是有必要的)。URL的大小会限制在16KB,所以发送大型查询时要时刻记住这点。

如果请求成功,将会收到200的响应状态码和响应主体中的结果。 如果发生了某个异常,将会收到500的响应状态码和响应主体中的异常描述信息。

当使用GET方法请求时,readonly会被设置。换句话说,若要作修改数据的查询,只能发送POST方法的请求。可以将查询通过POST主体发送,也可以通过URL参数发送。

示例:

$ curl 'http://localhost:8123/?query=SELECT%201'
1

$ wget -nv -O- 'http://localhost:8123/?query=SELECT 1'
1

$ echo -ne 'GET /?query=SELECT%201 HTTP/1.0\r\n\r\n' | nc localhost 8123
HTTP/1.0 200 OK
Date: Wed, 27 Nov 2019 10:30:18 GMT
Connection: Close
Content-Type: text/tab-separated-values; charset=UTF-8
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}

1

可以看到,curl 命令由于空格需要 URL 转义,所以不是很方便。尽管 wget 命令对url做了 URL 转义,但我们并不推荐使用他,因为在 HTTP 1.1 协议下使用 keep-alive 和 Transfer-Encoding: chunked 头部设置它并不能很好的工作。

$ echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
1

$ echo 'SELECT 1' | curl 'http://localhost:8123/?query=' --data-binary @-
1

$ echo '1' | curl 'http://localhost:8123/?query=SELECT' --data-binary @-
1

如您所见,curl有些不方便,因为空格必须进行URL转义。 尽管wget本身会对所有内容进行转义,但我们不推荐使用它,因为在使用keepalive和传输编码chunked时,它在HTTP 1.1上不能很好地工作。

$ echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
1

$ echo 'SELECT 1' | curl 'http://localhost:8123/?query=' --data-binary @-
1

$ echo '1' | curl 'http://localhost:8123/?query=SELECT' --data-binary @-
1

如果部分查询是在参数中发送的,部分是在POST中发送的,则在这两个数据部分之间插入换行。

错误示例:

$ echo 'ECT 1' | curl 'http://localhost:8123/?query=SEL' --data-binary @-
Code: 59, e.displayText() = DB::Exception: Syntax error: failed at position 0: SEL
ECT 1
, expected One of: SHOW TABLES, SHOW DATABASES, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE., e.what() = DB::Exception

默认情况下,返回的数据是TabSeparated格式的,更多信息,见Formats部分。

您可以使用查询的FORMAT子句来设置其他格式。

另外,还可以使用default_formatURL参数或X-ClickHouse-Format头来指定TabSeparated之外的默认格式。

$ echo 'SELECT 1 FORMAT Pretty' | curl 'http://localhost:8123/?' --data-binary @-
┏━━━┓
┃ 1 ┃
┡━━━┩
│ 1 │
└───┘

INSERT必须通过POST方法来插入数据。在这种情况下,您可以在URL参数中编写查询的开始部分,并使用POST传递要插入的数据。例如,要插入的数据可以是来自MySQL的一个以tab分隔的存储。通过这种方式,INSERT查询替换了从MySQL查询的LOAD DATA LOCAL INFILE。

示例: 创建一个表:

$ echo 'CREATE TABLE t (a UInt8) ENGINE = Memory' | curl 'http://localhost:8123/' --data-binary @-

使用类似INSERT的查询来插入数据:

$ echo 'INSERT INTO t VALUES (1),(2),(3)' | curl 'http://localhost:8123/' --data-binary @-

数据可以从查询中单独发送:

$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-

您可以指定任何数据格式。Values格式与将INSERT写入t值时使用的格式相同:

$ echo '(7),(8),(9)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20Values' --data-binary @-

若要插入tab分割的数据,需要指定对应的格式:

$ echo -ne '10\n11\n12\n' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20TabSeparated' --data-binary @-

从表中读取内容。由于查询处理是并行的,数据以随机顺序输出。

$ curl 'http://localhost:8123/?query=SELECT%20a%20FROM%20t'
7
8
9
10
11
12
1
2
3
4
5
6

删除表:

$ echo 'DROP TABLE t' | curl 'http://localhost:8123/' --data-binary @-

成功请求后并不会返回数据,返回一个空的响应体。

在传输数据时,可以使用ClickHouse内部压缩格式。压缩的数据具有非标准格式,您需要使用特殊的clickhouse-compressor程序来处理它(它是与clickhouse-client包一起安装的)。为了提高数据插入的效率,您可以通过使用http_native_compression_disable_checksumming_on_decompress设置禁用服务器端校验。

如果在URL中指定了compress=1,服务会返回压缩的数据。 如果在URL中指定了decompress=1,服务会解压通过POST方法发送的数据。

您也可以选择使用HTTP compression。发送一个压缩的POST请求,附加请求头Content-Encoding: compression_method。为了使ClickHouse响应,您必须附加Accept-Encoding: compression_method。ClickHouse支持gzip,br和deflate compression methods。要启用HTTP压缩,必须使用ClickHouse启用Http压缩配置。您可以在Http zlib压缩级别设置中为所有压缩方法配置数据压缩级别。

您可以使用它在传输大量数据时减少网络流量,或者创建立即压缩的转储。

通过压缩发送数据的例子:

#Sending data to the server:
$ curl -vsS "http://localhost:8123/?enable_http_compression=1" -d 'SELECT number FROM system.numbers LIMIT 10' -H 'Accept-Encoding: gzip'

#Sending data to the client:
$ echo "SELECT 1" | gzip -c | curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/'

!!! note "警告" 一些HTTP客户端可能会在默认情况下从服务器解压数据(使用gzip和deflate),即使您未正确地使用了压缩设置,您也可能会得到解压数据。

您可以使用databaseURL参数或X-ClickHouse-Database头来指定默认数据库。

$ echo 'SELECT number FROM numbers LIMIT 10' | curl 'http://localhost:8123/?database=system' --data-binary @-
0
1
2
3
4
5
6
7
8
9

默认情况下,在服务器设置中注册的数据库被用作默认数据库。默认情况下,它是名为default的数据库。或者,您可以始终在表名之前使用点来指定数据库。

用户名和密码可以通过以下三种方式指定:

通过HTTP Basic Authentication。示例:

$ echo 'SELECT 1' | curl 'http://user:password@localhost:8123/' -d @-
  1. 通过URL参数中的user和password。示例:
$ echo 'SELECT 1' | curl 'http://localhost:8123/?user=user&password=password' -d @-
  1. 使用X-ClickHouse-User或X-ClickHouse-Key头指定,示例:
$ echo 'SELECT 1' | curl -H 'X-ClickHouse-User: user' -H 'X-ClickHouse-Key: password' 'http://localhost:8123/' -d @-

如果未指定用户名,则使用default。如果未指定密码,则使用空密码。 您还可以使用URL参数来指定处理单个查询或整个设置配置文件的任何设置。例子:http://localhost:8123/?profile=web&max_rows_to_read=1000000000&query=SELECT+1

更多信息,详见设置部分。

$ echo 'SELECT number FROM system.numbers LIMIT 10' | curl 'http://localhost:8123/?' --data-binary @-
0
1
2
3
4
5
6
7
8
9

有关其他参数的信息,请参考SET一节。

类似地,您可以在HTTP协议中使用ClickHouse会话。为此,需要向请求添加session_idGET参数。您可以使用任何字符串作为会话ID。默认情况下,会话在60秒不活动后终止。要更改此超时配置,请修改服务器配置中的default_session_timeout设置,或向请求添加session_timeoutGET参数。要检查会话状态,使用session_check=1参数。一次只能在单个会话中执行一个查询。

您可以在X-ClickHouse-Progress响应头中收到查询进度的信息。为此,启用Http Header携带进度。示例:

X-ClickHouse-Progress: {"read_rows":"2752512","read_bytes":"240570816","total_rows_to_read":"8880128"}
X-ClickHouse-Progress: {"read_rows":"5439488","read_bytes":"482285394","total_rows_to_read":"8880128"}
X-ClickHouse-Progress: {"read_rows":"8783786","read_bytes":"819092887","total_rows_to_read":"8880128"}

显示字段信息:

  • read_rows — 读取的行数。
  • read_bytes — 读取的数据字节数。
  • total_rows_to_read — 读取的数据总行数。
  • written_rows — 写入数据行数。
  • written_bytes — 写入数据字节数。

如果HTTP连接丢失,运行的请求不会自动停止。解析和数据格式化是在服务器端执行的,使用Http连接可能无效。

可选的query_id参数可能当做query ID传入(或者任何字符串)。更多信息,详见replace_running_query部分。

可选的quota_key参数可能当做quota key传入(或者任何字符串)。更多信息,详见Quotas部分。

HTTP接口允许传入额外的数据(外部临时表)来查询。更多信息,详见外部数据查询处理部分。

响应缓冲

可以在服务器端启用响应缓冲。提供了buffer_size和wait_end_of_query两个URL参数来达此目的。

buffer_size决定了查询结果要在服务内存中缓冲多少个字节数据. 如果响应体比这个阈值大,缓冲区会写入到HTTP管道,剩下的数据也直接发到HTTP管道中。

为了确保整个响应体被缓冲,可以设置wait_end_of_query=1。这种情况下,存入内存的数据会被缓冲到服务端的一个临时文件中。

示例:

$ curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=3000000&wait_end_of_query=1' -d 'SELECT toUInt8(number) FROM system.numbers LIMIT 9000000 FORMAT RowBinary'

查询请求响应状态码和HTTP头被发送到客户端后,若发生查询处理出错,使用缓冲区可以避免这种情况的发生。在这种情况下,响应主体的结尾会写入一条错误消息,而在客户端,只能在解析阶段检测到该错误。

查询参数

您可以使用参数创建查询,并通过相应的HTTP请求参数为它们传递值。有关更多信息,请参见CLI查询参数。

示例

$ curl -sS "<address>?param_id=2¶m_phrase=test" -d "SELECT * FROM table WHERE int_column = {id:UInt8} and string_column = {phrase:String}"

特定的HTTP接口

ClickHouse通过HTTP接口支持特定的查询。例如,您可以如下所示向表写入数据:

$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-

ClickHouse还支持预定义的HTTP接口,可以帮助您更容易与第三方工具集成,如Prometheus Exporter.

示例:

  • 首先,将此部分添加到服务器配置文件中:
<http_handlers>
    <rule>
        <url>/predefined_query</url>
        <methods>POST,GET</methods>
        <handler>
            <type>predefined_query_handler</type>
            <query>SELECT * FROM system.metrics LIMIT 5 FORMAT Template SETTINGS format_template_resultset = 'prometheus_template_output_format_resultset', format_template_row = 'prometheus_template_output_format_row', format_template_rows_between_delimiter = '\n'</query>
        </handler>
    </rule>
    <rule>...</rule>
    <rule>...</rule>
</http_handlers>
  • 请求Prometheus格式的URL以获取数据:
$ curl -v 'http://localhost:8123/predefined_query'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /predefined_query HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 28 Apr 2020 08:52:56 GMT
< Connection: Keep-Alive
< Content-Type: text/plain; charset=UTF-8
< X-ClickHouse-Server-Display-Name: i-mloy5trc
< Transfer-Encoding: chunked
< X-ClickHouse-Query-Id: 96fe0052-01e6-43ce-b12a-6b7370de6e8a
< X-ClickHouse-Format: Template
< X-ClickHouse-Timezone: Asia/Shanghai
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
# HELP "Query" "Number of executing queries"
# TYPE "Query" counter
"Query" 1

# HELP "Merge" "Number of executing background merges"
# TYPE "Merge" counter
"Merge" 0

# HELP "PartMutation" "Number of mutations (ALTER DELETE/UPDATE)"
# TYPE "PartMutation" counter
"PartMutation" 0

# HELP "ReplicatedFetch" "Number of data parts being fetched from replica"
# TYPE "ReplicatedFetch" counter
"ReplicatedFetch" 0

# HELP "ReplicatedSend" "Number of data parts being sent to replicas"
# TYPE "ReplicatedSend" counter
"ReplicatedSend" 0

* Connection #0 to host localhost left intact

* Connection #0 to host localhost left intact

正如您从示例中看到的,如果在config.xml文件中配置了http_handlers,并且http_handlers可以包含许多规则。ClickHouse将把接收到的HTTP请求与rule中的预定义类型进行匹配,第一个匹配的将运行处理程序。如果匹配成功,ClickHouse将执行相应的预定义查询。

现在rule可以配置method, header, url, handler:

method 负责匹配HTTP请求的方法部分。 method完全符合HTTP协议中method的定义。这是一个可选的配置。如果它没有在配置文件中定义,那么它与HTTP请求的方法部分不匹配。

url 负责匹配HTTP请求的URL部分。它匹配RE2正则表达式。这是一个可选的配置。如果配置文件中没有定义它,则它与HTTP请求的URL部分不匹配。

headers 负责匹配HTTP请求的头部分。它与RE2的正则表达式兼容。这是一个可选的配置。如果它没有在配置文件中定义,那么它与HTTP请求的头部分不匹配。

handler 包含主要的处理部分。现在handler可以配置type, status, content_type, response_content, query, query_param_name。 type 目前支持三种类型:特定查询, 动态查询, static.

  • query — 使用predefined_query_handler类型,在调用处理程序时执行查询。
  • query_param_name — 与dynamic_query_handler类型一起使用,提取并执行HTTP请求参数中与query_param_name值对应的值。
  • status — 与static类型一起使用,响应状态代码。
  • content_type — 与static类型一起使用,响应信息content-type。
  • response_content — 与static类型一起使用,响应发送给客户端的内容,当使用前缀file://或config://时,从发送给客户端的文件或配置中查找内容。

接下来是不同type的配置方法。

特定查询

predefined_query_handler 支持设置Settingsquery_params参数。您可以将query配置为predefined_query_handler类型。

query 是一个预定义的predefined_query_handler查询,它由ClickHouse在匹配HTTP请求并返回查询结果时执行。这是一个必须的配置。

以下是定义的max_threads和max_final_threads设置, 然后查询系统表以检查这些设置是否设置成功。

示例:

<http_handlers>
    <rule>
        <url><![CDATA[/query_param_with_url/\w+/(?P<name_1>[^/]+)(/(?P<name_2>[^/]+))?]]></url>
        <method>GET</method>
        <headers>
            <XXX>TEST_HEADER_VALUE</XXX>
            <PARAMS_XXX><![CDATA[(?P<name_1>[^/]+)(/(?P<name_2>[^/]+))?]]></PARAMS_XXX>
        </headers>
        <handler>
            <type>predefined_query_handler</type>
            <query>SELECT value FROM system.settings WHERE name = {name_1:String}</query>
            <query>SELECT name, value FROM system.settings WHERE name = {name_2:String}</query>
        </handler>
    </rule>
</http_handlers>
$ curl -H 'XXX:TEST_HEADER_VALUE' -H 'PARAMS_XXX:max_threads' 'http://localhost:8123/query_param_with_url/1/max_threads/max_final_threads?max_threads=1&max_final_threads=2'
1
max_final_threads   2

!!! note "警告" 在一个predefined_query_handler中,只支持insert类型的一个查询

动态查询

dynamic_query_handler时,查询以HTTP请求参数的形式编写。区别在于,在predefined_query_handler中,查询是在配置文件中编写的。您可以在dynamic_query_handler中配置query_param_name

ClickHouse提取并执行与HTTP请求URL中的query_param_name值对应的值。query_param_name的默认值是/query。这是一个可选的配置。如果配置文件中没有定义,则不会传入参数。

为了试验这个功能,示例定义了max_threads和max_final_threadsqueries设置是否成功的值。

示例:

<http_handlers>
    <rule>
    <headers>
        <XXX>TEST_HEADER_VALUE_DYNAMIC</XXX>    </headers>
    <handler>
        <type>dynamic_query_handler</type>
        <query_param_name>query_param</query_param_name>
    </handler>
    </rule>
</http_handlers>
$ curl  -H 'XXX:TEST_HEADER_VALUE_DYNAMIC'  'http://localhost:8123/own?max_threads=1&max_final_threads=2¶m_name_1=max_threads¶m_name_2=max_final_threads&query_param=SELECT%20name,value%20FROM%20system.settings%20where%20name%20=%20%7Bname_1:String%7D%20OR%20name%20=%20%7Bname_2:String%7D'
max_threads 1
max_final_threads   2

static

static可以返回content_type, status和response_content。response_content可以返回指定的内容。

示例:

返回信息.

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/hi</url>
            <handler>
                <type>static</type>
                <status>402</status>
                <content_type>text/html; charset=UTF-8</content_type>
                <response_content>Say Hi!</response_content>
            </handler>
        </rule>
</http_handlers>
$ curl -vv  -H 'XXX:xxx' 'http://localhost:8123/hi'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /hi HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 402 Payment Required
< Date: Wed, 29 Apr 2020 03:51:26 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
* Connection #0 to host localhost left intact
Say Hi!%

从配置中查找发送到客户端的内容。

<get_config_static_handler><![CDATA[<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>]]></get_config_static_handler>

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/get_config_static_handler</url>
            <handler>
                <type>static</type>
                <response_content>config://get_config_static_handler</response_content>
            </handler>
        </rule>
</http_handlers>
$ curl -v  -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_config_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:01:24 GMT
< Connection: Keep-Alive
< Content-Type: text/plain; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
* Connection #0 to host localhost left intact
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%

从发送到客户端的文件中查找内容。

<http_handlers>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/get_absolute_path_static_handler</url>
            <handler>
                <type>static</type>
                <content_type>text/html; charset=UTF-8</content_type>
                <response_content>file:///absolute_path_file.html</response_content>
            </handler>
        </rule>
        <rule>
            <methods>GET</methods>
            <headers><XXX>xxx</XXX></headers>
            <url>/get_relative_path_static_handler</url>
            <handler>
                <type>static</type>
                <content_type>text/html; charset=UTF-8</content_type>
                <response_content>file://./relative_path_file.html</response_content>
            </handler>
        </rule>
</http_handlers>
$ user_files_path='/var/lib/clickhouse/user_files'
$ sudo echo "<html><body>Relative Path File</body></html>" > $user_files_path/relative_path_file.html
$ sudo echo "<html><body>Absolute Path File</body></html>" > $user_files_path/absolute_path_file.html
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_absolute_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:16 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=3
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
<
<html><body>Absolute Path File</body></html>
* Connection #0 to host localhost left intact
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
*   Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_relative_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:31 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8