ClickHouse源码阅读(0000 0011) —— ClickHouse Client启动和终止过程分析

在Mac OS系统上,命令行终端切换到/Users/***/ClionProjects/Beautiful1205/ClickHouse/cmake-build-debug/dbms/programs目录下,执行以下命令:

./clickhouse client --port=9000

则通过TCP连接与Server端建立连接,Client端打印如下日志:

ClickHouse源码阅读(0000 0001) —— main.cpp分析这篇文章已经分析了根据启动参数选择不同的应用进行启动,client的mainEntryClickHouseClient方法为:

int mainEntryClickHouseClient(int argc, char **argv) {
    try {
        DB::Client client;
        client.init(argc, argv);//注意客户端需要先执行这里的client.init()方法
        return client.run();
    }
    catch (const boost::program_options::error &e) {
        std::cerr << "Bad arguments: " << e.what() << std::endl;
        return 1;
    }
    catch (...) {
        std::cerr << DB::getCurrentExceptionMessage(true) << std::endl;
        return 1;
    }
}

可以看到,这里比server应用启动时多了一个init()方法,具体看下这个方法具体干了啥。

内容比较繁琐,基本就是根据你的输入参数初始化一些内容,比如输入中增加了-n,-m等参数,会做相应的初始化。比较核心的应该是这里:

            /// Parse main commandline options.
            po::parsed_options parsed = po::command_line_parser(
                    common_arguments.size(), common_arguments.data()).options(main_description).run();
            po::variables_map options;
            po::store(parsed, options);
            po::notify(options);

就是根据一些预定义的参数和输入的参数将输入参数解析,保存在options中,然后即可以options为基础进行相应的处理。这里先不多做分析了。

接着就是执行client.run()方法,ClickHouse源码阅读(0000 0010) —— 根据日志分析ClickHouse Server启动和终止过程这篇文章已经提到了poco Application 框架以及核心的run()方法,这里就直接跳转到client的实现,即

接着来到了Client.cpp文件ClickHouse Client启动的main()方法这里,一路来到mainImpl()方法。

关键步骤包括:

1)注册相关函数;

2)判断是否是交互模式,如果是交互式模式,输出client版本信息;

            // 如果满足以下条件之一, 则表示不是命令行交互模式, 设置is_interactive = false;
            // 将启用批处理模式:
            //1)输入的参数形如: ./clickhouse-client --query='****';
            //2)stdin不是终端命令行.

3)设置标准输出和错误输出的浮点数的精度;

4)判断输出格式;

5)设置一些参数。注意命令行中的settings会覆盖clickhouse-client.xml中的配置;

6)connect()方法向服务端Server发起连接, 连接请求被服务端对应端口的Handler捕获并处理。连接完成后,如果是交互式模式打印连接成功的提示。

client和server是通过Connection这个类来进行连接的。client和server之间通过互相发送数据包通信,server服务端发给client端的数据包定义如下:

        //server服务端发给client端的数据包定义
        /// Packet that could be received from server.
        struct Packet {
            UInt64 type;

            Block block;
            std::unique_ptr<Exception> exception;
            std::vector<String> multistring_message;
            Progress progress;
            BlockStreamProfileInfo profile_info;

            Packet() : type(Protocol::Server::Hello) {}
        };

7)初始化时区;

8)一些参数的设置;

9)针对交互式模式和非交互式模型,进行不同的处理逻辑。

对于交互式模式,1)从服务器加载建议数据, 方便在客户端命令行输出command line suggestions;2)加载历史命令记录(可以使用上下按键查看历史命令);3)loop()方法, 客户端与服务端一直保持连接。

针对非交互式模式,主要由nonInteractive()方法进行处理。

 

备注:loop()方法和nonInteractive()方法内部对SQL的处理都是调用了process()方法。在深入分析就涉及SQL的处理了,后面再写文章分析吧。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值