Implementation:ClickHouse ClickHouse TCPServer Start
| Knowledge Sources | |
|---|---|
| Domains | Deployment |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Concrete tool for starting multi-threaded TCP and HTTP servers in ClickHouse using the Poco `TCPServer` and `HTTPServer` classes, which provide an accept loop, connection dispatching via factory pattern, and thread pool management.
Description
The `TCPServer` class (declared in `base/poco/Net/include/Poco/Net/TCPServer.h`) implements a multithreaded TCP server. It uses a `ServerSocket` to listen for incoming connections, a `TCPServerConnectionFactory` to create protocol-specific connection handlers, and a `Poco::ThreadPool` to manage worker threads.
The server can be constructed in three ways:
- With a factory and a port number (creates its own `ServerSocket`)
- With a factory and an existing `ServerSocket` (uses the default thread pool)
- With a factory, an explicit `ThreadPool`, and an existing `ServerSocket`
Calling `start` creates a new background thread that runs the accept loop. Incoming connections are queued and dispatched to worker threads, which invoke the factory to create a `TCPServerConnection` object for each connection. The connection handler's `start` method is called; when it returns, the connection object is destroyed.
The `HTTPServer` class (declared in `base/poco/Net/include/Poco/Net/HTTPServer.h`) extends `TCPServer` to provide full HTTP/1.0 and HTTP/1.1 support, including persistent connections and chunked transfer encoding. It adds the `stopAll` method for controlled shutdown of active connections.
The systemd service unit at `packages/clickhouse-server.service` governs how the server process is managed in production. It uses `Type=notify` for readiness signaling, runs as the `clickhouse` user, and configures automatic restart, file descriptor limits, and Linux capabilities.
Usage
This API is used internally by the ClickHouse server during startup to create listeners for each configured protocol endpoint. External developers interact with it indirectly through ClickHouse's server configuration (specifying listen addresses and ports in `config.xml`), the systemd service unit, or direct binary invocation.
Code Reference
Source Location
- Repository: ClickHouse
- File:
base/poco/Net/include/Poco/Net/TCPServer.h(lines 72-239) - File:
base/poco/Net/include/Poco/Net/HTTPServer.h(lines 33-104) - File:
packages/clickhouse-server.service(systemd unit)
Signature
TCPServer:
class TCPServer : public Poco::Runnable {
public:
// Construct with factory and port (creates its own ServerSocket)
TCPServer(
TCPServerConnectionFactory::Ptr pFactory,
Poco::UInt16 portNumber = 0,
TCPServerParams::Ptr pParams = 0); // L114
// Construct with factory and existing ServerSocket (default thread pool)
TCPServer(
TCPServerConnectionFactory::Ptr pFactory,
const ServerSocket & socket,
TCPServerParams::Ptr pParams = 0); // L128
// Construct with factory, explicit ThreadPool, and existing ServerSocket
TCPServer(
TCPServerConnectionFactory::Ptr pFactory,
Poco::ThreadPool & threadPool,
const ServerSocket & socket,
TCPServerParams::Ptr pParams = 0); // L140-144
virtual ~TCPServer(); // L156
void start(); // L163 -- starts accept loop in background thread
void stop(); // L171 -- stops accepting, discards queued connections
int currentThreads() const; // L179
int maxThreads() const; // L182
int totalConnections() const; // L185
int currentConnections() const; // L188
int maxConcurrentConnections() const; // L191
int queuedConnections() const; // L194
int refusedConnections() const; // L197
const ServerSocket & socket() const; // L200
Poco::UInt16 port() const; // L203
void setConnectionFilter(const TCPServerConnectionFilter::Ptr & pFilter); // L206
TCPServerConnectionFilter::Ptr getConnectionFilter() const; // L215
};
HTTPServer (extends TCPServer):
class HTTPServer : public TCPServer {
public:
HTTPServer(
HTTPRequestHandlerFactory::Ptr pFactory,
Poco::UInt16 portNumber = 80,
HTTPServerParams::Ptr pParams = new HTTPServerParams); // L56-57
HTTPServer(
HTTPRequestHandlerFactory::Ptr pFactory,
const ServerSocket & socket,
HTTPServerParams::Ptr pParams); // L65
HTTPServer(
HTTPRequestHandlerFactory::Ptr pFactory,
Poco::ThreadPool & threadPool,
const ServerSocket & socket,
HTTPServerParams::Ptr pParams); // L75-79
~HTTPServer(); // L89
void stopAll(bool abortCurrent = false); // L92
};
TCPServerConnectionFilter:
class TCPServerConnectionFilter : public Poco::RefCountedObject {
public:
typedef Poco::AutoPtr<TCPServerConnectionFilter> Ptr;
virtual bool accept(const StreamSocket & socket) = 0; // L56
};
systemd service unit (packages/clickhouse-server.service):
[Unit]
Description=ClickHouse Server (analytic DBMS for big data)
Requires=network-online.target
After=time-sync.target network-online.target
[Service]
Type=notify
User=clickhouse
Group=clickhouse
Restart=always
RestartSec=30
TimeoutStopSec=infinity
TimeoutStartSec=0
ExecStart=/usr/bin/clickhouse-server --config=/etc/clickhouse-server/config.xml --pid-file=%t/%p/%p.pid
LimitCORE=infinity
LimitNOFILE=500000
CapabilityBoundingSet=CAP_NET_ADMIN CAP_IPC_LOCK CAP_SYS_NICE CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_IPC_LOCK CAP_SYS_NICE CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| pFactory | `TCPServerConnectionFactory::Ptr` | Yes | Factory that creates protocol-specific connection handler objects for each accepted connection. The server takes ownership. |
| socket | `ServerSocket` | Yes (for socket constructors) | A bound and listening server socket. Must be in listening state before `start` is called. |
| threadPool | `Poco::ThreadPool &` | No | Thread pool for worker threads. If not provided, the default thread pool is used. |
| pParams | `TCPServerParams::Ptr` | No | Configuration parameters including max queued connections, max threads, and thread idle time. If null, defaults are created by the `TCPServerDispatcher`. |
| pFilter | `TCPServerConnectionFilter::Ptr` | No | Optional connection filter for IP-based accept/reject decisions. Must be set before `start`. |
Outputs
| Name | Type | Description |
|---|---|---|
| Running accept loop | Background thread | After `start`, a dedicated thread accepts incoming connections and enqueues them for dispatch. |
| Connection statistics | `int` values | `currentThreads`, `totalConnections`, `currentConnections`, `maxConcurrentConnections`, `queuedConnections`, `refusedConnections` provide runtime metrics. |
| Listening port | `Poco::UInt16` | The actual port number the server is listening on, queryable via `port`. |
| Managed service | systemd unit | When deployed via packages, the server runs as a managed systemd service on ports 9000 (TCP) and 8123 (HTTP) by default. |
Usage Examples
Creating and starting a TCPServer programmatically:
#include <Poco/Net/TCPServer.h>
#include <Poco/Net/ServerSocket.h>
using namespace Poco::Net;
// Bind and listen on port 9000
ServerSocket socket(9000);
// Create server with a custom connection factory
TCPServer server(new MyConnectionFactory(), socket);
// Start the accept loop (returns immediately)
server.start();
// ... server runs in background ...
// Stop the server
server.stop();
Starting ClickHouse server via systemd:
# Start the service
sudo systemctl start clickhouse-server
# Check status
sudo systemctl status clickhouse-server
# View logs
sudo journalctl -u clickhouse-server -f
# Stop the service (waits for in-flight queries)
sudo systemctl stop clickhouse-server
Starting ClickHouse server directly:
# Start server with default config
clickhouse-server --config=/etc/clickhouse-server/config.xml
# Start server with custom config and foreground mode
clickhouse server --config-file=config.xml