Demo:系统设置与指标
可构建、可运行、可验证,并与仓库 examples 目录中的源码保持一致。
1. 示例内容
完整源码中的关键调用均有中文注释,页面同时给出运行命令、验证方法和可调整参数。
2. 构建与运行
cmake --build build --target sttnet_system_settings --parallel
./build/examples/sttnet_system_settings3. 运行结果
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;
}