STTNet 0.7.0

Demo:系统设置与指标

可构建、可运行、可验证,并与仓库 examples 目录中的源码保持一致。

1. 示例内容

完整源码中的关键调用均有中文注释,页面同时给出运行命令、验证方法和可调整参数。

2. 构建与运行

cmake --build build --target sttnet_system_settings --parallel
./build/examples/sttnet_system_settings

3. 运行结果

curl http://127.0.0.1:8084/metrics
预期:返回指标 JSON,并写入日志文件。

4. 完整源码

#include <sttnet.h>

#include <iostream>

int main()
{
    using namespace stt::network;
    using stt::system::ServerSetting;

    // 信号在线程、Reactor 或 Worker 创建前完成屏蔽。
    if(!ServerSetting::blockTerminationSignals())
    {
        std::cerr << "failed to block termination signals\n";
        return 1;
    }

    // 创建容量为 16K 的异步日志队列。
    // openFile() 会在可能时创建缺失目录。
    stt::file::LogFile log(16384);
    if(!log.openFile("logs/sttnet.log"))
    {
        std::cerr << "failed to open logs/sttnet.log\n";
        return 2;
    }

    // init() 配置信号默认行为并把日志对象接入 STTNet。
    // 使用 "Chinese" 输出中文框架日志;其他值使用英文。
    ServerSetting::init(&log, "English");

    // 构造参数定义容量和内置防护默认值。
    HttpServer server(
        100000, // 框架最多跟踪的并发连接数。
        64,     // 每连接最大接收缓冲,单位 KiB。
        65536,  // Worker 完成队列容量,取 2 的幂。
        true    // 启用内置连接/请求安全限流。
    );

    ServerSocketOptions socketOptions;
    socketOptions.tcp_no_delay = true;          // 降低小响应延迟。
    socketOptions.keep_alive = true;            // 开启内核 TCP keepalive。
    socketOptions.keep_alive_idle_seconds = 60; // 空闲 60 秒后开始探测。
    socketOptions.keep_alive_interval_seconds = 10;
    socketOptions.keep_alive_probe_count = 3;
    socketOptions.listen_backlog = 4096;
    server.setSocketOptions(socketOptions);

    // 限制慢客户端占用的内存,并防止单连接独占 I/O。
    server.setMaxPendingWriteBytes(4 * 1024 * 1024);
    server.setWriteBudgetPerEvent(256 * 1024);

    // 限制请求头和 WorkerPool 压力。
    server.setMaxHttpHeaderBytes(64 * 1024);
    server.setMaxPendingWorkerTasks(32768);

    // close() 时最多用五秒完成网络排空。
    server.setGracefulShutdownTimeout(5000);

    server.setFunction("/metrics",
        [&server](HttpServerFDHandler &client, HttpRequestInformation &) {
            // 指标是无锁快照,可从任意线程读取。
            const ServerMetricsSnapshot metrics = server.getMetrics();

            Json::Value response;
            response["active_connections"] = Json::UInt64(metrics.active_connections);
            response["parsed_http_requests"] = Json::UInt64(metrics.parsed_http_requests);
            response["pending_write_bytes"] = Json::UInt64(metrics.pending_write_bytes);
            response["worker_task_rejections"] = Json::UInt64(metrics.worker_task_rejections);
            return client.sendJson(response) ? 1 : -2;
        });

    if(!server.startListen(8084, 8))
    {
        std::cerr << "failed to listen on port 8084\n";
        return 3;
    }

    std::cout << "Configured server listening on http://127.0.0.1:8084\n";
    ServerSetting::waitForTerminationSignal();

    // LogFile 的生命周期覆盖 Server 的完整关闭过程。
    return server.close() ? 0 : 4;
}