userver项目必须用cmake-init脚本初始化,http handler须继承loggablecomponentbase并注册到components::server,配置热重载需启用dynamicconfigclient,postgresql须用cluster异步接口,组件依赖顺序须严格声明。

userver 项目初始化必须用 cmake-init
直接 clone userver 官方 repo 或手动建 CMakeLists.txt 会卡在依赖和构建配置上,因为 userver 不是普通库,它自带 toolchain、预编译头、测试框架集成和组件注册机制。官方唯一支持的起点是 cmake-init 脚本。
- 运行
curl -L https://github.com/userver-framework/userver/releases/latest/download/cmake-init.sh | bash,生成标准项目骨架 - 生成的
CMakeLists.txt里已包含find_package(userver REQUIRED)和userver_add_component(),别手写add_library或硬连libuserver_core.a - 如果跳过这步,后续
userver::server组件无法自动链接 OpenSSL、gRPC、PostgreSQL 驱动等隐式依赖,启动时大概率报undefined symbol: SSL_CTX_new或类似链接错误
HTTP handler 注册必须走 components::Server
不能像 Boost.Beast 那样直接 bind 到 socket,userver 的路由系统完全基于组件生命周期管理。所有 HTTP 接口必须作为 components::ComponentBase 子类注册,并在 components::Server 的配置中声明路径映射。
- 写 handler 类时继承
userver::components::LoggableComponentBase,重载GetRoutes()返回userver::server::handlers::HttpHandlerBase::Routes - 配置文件(如
service.yaml)里要明确写server:→handlers:→- name: my-handler→path: /api/v1/xxx,漏掉name字段会导致 handler 根本不加载 - 别在
main()里调server.AddHandler()—— userver 2.x 已移除该 API,强行调用会编译失败,提示no member named 'AddHandler' in 'userver::server::handlers::HttpHandlerBase'
配置热重载依赖 components::DynamicConfigClient
userver 默认关闭配置热重载,即使你改了 dynamic_config.yaml 并 SIGHUP 进程,服务也不会响应变更。必须显式启用并注入 client 实例。
- 在 handler 构造函数里通过
component_context.Get()<:components::dynamicconfigclient>()</:components::dynamicconfigclient>获取 client - 配置项需加
dynamic_config_client:块,且source: file或source: http必须存在,否则DynamicConfigClient初始化失败,日志里只输出WARNING Dynamic config source is not configured,无其他报错 - 读取配置用
config["my_service.timeout_ms"].As<int>()</int>,不要缓存结果 —— 热重载后旧值仍有效,新值需重新As()才能拿到
数据库连接池要用 userver::storages::postgres::Cluster
别直接 new pqxx::connection 或用 libpq 封装,userver 的 PostgreSQL 支持是异步非阻塞的,底层复用 io_uring(Linux)或 epoll + 线程池(其他平台),自己封装会破坏调度模型。
- 配置里写
postgresql:→cluster:→shard0:→hosts:,每个 shard 必须至少一个 host,空列表会导致Cluster::GetCluster("shard0")返回空指针 - 执行 SQL 用
cluster->Execute(...),返回userver::storages::postgres::ResultSet,不是 rawPQresult*;若需事务,必须用cluster->Begin(...)而非PQexec(conn, "BEGIN") - 连接池大小由
max_connections_per_host控制,默认 16,高并发下不够用时会卡在WaitForConnection状态,表现为请求延迟突增但 CPU 不高
最易被忽略的是组件依赖顺序:比如你的 handler 依赖数据库组件,就必须在 CMakeLists.txt 的 userver_add_component() 中把数据库组件列在 handler 组件之前,否则启动时报 Component 'my-handler' depends on non-existent component 'postgresql' —— 这个错误不提示具体缺哪个,只说 “non-existent”,得自己对照 components::ComponentList 检查拼写和加载顺序。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











