基于boost::beast的低延迟HTTP请求性能优化方案问询
低延迟HTTP请求优化咨询
背景
正在构建低延迟项目,快速发送HTTP请求是核心环节。当前基于Boost.Beast实现的HTTP客户端平均延迟在10-20微秒,目标是优化至个位数微秒级别,运行环境为AWS搭载Intel Xeon 3GHz处理器的虚拟机。
当前实现代码
#include <thread> #include <iostream> #include <coroutine> #include <optional> #include <variant> #include <vector> #include <utility> #include <string> #include <chrono> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> #include <boost/json.hpp> #include <boost/beast.hpp> #include <boost/asio/io_context.hpp> #include <boost/asio/ssl/context.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/spawn.hpp> #include <boost/coroutine/all.hpp> #include <boost/beast/ssl/ssl_stream.hpp> #include <boost/beast/core/tcp_stream.hpp> #include <boost/beast/core/flat_static_buffer.hpp> #include <boost/beast/http.hpp> #include <boost/beast/http/string_body.hpp> #include <boost/beast/http/verb.hpp> #include <boost/asio/awaitable.hpp> #include <boost/asio/detached.hpp> class http_client { private: using response = boost::beast::http::response<boost::beast::http::string_body>; std::string http_hostname; std::string ip_address; boost::asio::ssl::context ssl_context; boost::asio::ip::tcp::resolver hostname_resolver; std::optional<boost::beast::ssl_stream<boost::beast::tcp_stream>> tcp_stream; boost::beast::flat_static_buffer<4 * 1024 * 1024> receive_flat_buffer; public: http_client(const std::string& http_name, boost::asio::io_context& io_context) : http_hostname(http_name), ssl_context(boost::asio::ssl::context::tlsv12_client), hostname_resolver(io_context), tcp_stream(boost::beast::ssl_stream<boost::beast::tcp_stream>(io_context, ssl_context)), receive_flat_buffer() { ssl_context.set_verify_mode(boost::asio::ssl::verify_peer); ssl_context.set_options( boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3 | boost::asio::ssl::context::single_dh_use); if (!SSL_set_tlsext_host_name(tcp_stream->native_handle(), http_hostname.c_str())) { boost::beast::error_code error_code{static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()}; throw boost::beast::system_error{error_code}; } auto const resolved_endpoint = hostname_resolver.resolve(http_hostname, "443"); ip_address = resolved_endpoint->endpoint().address().to_string(); boost::beast::get_lowest_layer(tcp_stream.value()).connect(resolved_endpoint); boost::beast::get_lowest_layer(tcp_stream.value()).socket().set_option(boost::asio::socket_base::keep_alive(true)); boost::beast::get_lowest_layer(tcp_stream.value()).socket().set_option(boost::asio::ip::tcp::no_delay(true)); std::cout << "Connected to REST endpoint at IP address <\"" << ip_address << "\"> which was resolved from <\"" << resolved_endpoint->host_name() << std::endl; tcp_stream->handshake(boost::asio::ssl::stream_base::client); } void send_request(boost::asio::io_context& io_context, const std::string& target, const std::function<void(response)>& callback) { boost::asio::spawn( io_context, [target = std::move(target), callback = std::move(callback), this](boost::asio::yield_context yield_context) mutable { boost::beast::http::request<boost::beast::http::string_body> http_request{ boost::beast::http::verb::get, target, 11}; http_request.set(boost::beast::http::field::host, http_hostname); http_request.set(boost::beast::http::field::content_type, "application/json"); http_request.set(boost::beast::http::field::connection, "Keep-Alive"); http_request.set(boost::beast::http::field::keep_alive, "timeout=86400"); http_request.keep_alive(true); http_request.prepare_payload(); size_t bytes_transferred = boost::beast::http::async_write(tcp_stream.value(), http_request, yield_context); response http_response; boost::beast::http::async_read(tcp_stream.value(), receive_flat_buffer, http_response, yield_context); callback(http_response); } ); } }; int main() { boost::asio::io_context io_context{}; std::string host_name{"fapi.binance.com"}; http_client client(host_name, io_context); for (int i = 0; i < 100; i++) { auto const stime = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); client.send_request(io_context, "/fapi/v1/time", [&](boost::beast::http::response<boost::beast::http::string_body> const& http_response) {}); auto const etime = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); std::cout << "time diff = " << etime - stime << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } io_context.run(); return 0; }
编译选项
g++ -std=c++20 -O2 -flto -g beast_http_client.cpp -I/home/dev/vcpkg/installed/x64-linux/include -L/home/dev/vcpkg/installed/x64-linux/lib -lboost_system -lboost_coroutine -lboost_thread -lboost_json -lssl -lcrypto -lboost_context
性能优化建议
1. 替换Boost.Beast为极简HTTP实现
Boost.Beast是通用HTTP库,包含大量适配逻辑和错误处理,对低延迟场景冗余。可以直接基于Boost.Asio的SSL/TCP流手动构造HTTP请求:
- 预构造固定格式的GET请求头字符串(比如针对
/fapi/v1/time的请求,所有字段都是固定的),避免每次请求动态构建 - 直接调用
async_write发送预构造好的字节流,跳过Beast的request对象封装 - 响应解析只做必要的处理(比如读取状态码和响应体长度),不需要完整的HTTP响应对象解析
2. 消除动态内存分配
- 将请求缓冲区、响应缓冲区设为类成员静态变量,复用内存,避免每次请求分配/释放
- 预构造HTTP请求头为字符数组,避免
std::string的动态内存操作 - 移除
std::function回调,改用编译期绑定的函数对象或直接内联处理逻辑,减少虚函数调用和内存分配
3. 优化协程与调度
- 避免每次
send_request都spawn新协程:因为是单连接Keep-Alive,串行发送请求更高效,可以用一个持久协程处理所有请求,通过队列传递任务 - 改用C++20原生协程(
std::awaitable)替代Boost.Coroutine,减少Boost库的额外开销 - 确保
io_context的线程数与CPU核心匹配(当前单线程,Xeon虚拟机可设为1或2线程,避免上下文切换)
4. 网络参数调优
- 缓存DNS解析结果:当前构造函数已做,但要确保不会重复解析
- 调整TCP缓冲区大小:设置
SO_RCVBUF和SO_SNDBUF为64KB或128KB(根据MTU和网络环境),减少系统调用次数 - 启用
TCP_FASTOPEN:如果服务器支持,在socket上设置该选项,减少TCP握手延迟 - 确认SSL会话复用:启用SSL会话缓存,避免每次重新握手(当前代码用的是长连接,SSL握手只做一次,这部分已经优化,但可确认
ssl_context是否开启会话复用)
5. 编译选项强化
- 移除
-g调试符号,减少运行时内存开销和二进制大小 - 添加
-march=native,让编译器针对Intel Xeon架构生成最优指令 - 改用
-O3优化级别,开启更多编译器优化(注意测试兼容性,避免优化带来的逻辑问题) - 添加
-fno-rtti和-fno-exceptions(如果代码可以适配),消除RTTI和异常处理的运行时开销 - 保留
-flto链接时优化,进一步提升二进制执行效率
6. 精确延迟测量
- 当前代码测量的是
send_request函数的调用时间,不是真实的请求往返延迟。应将计时起点放在请求发送前,终点放在响应接收完成后的回调中,准确统计从发送到收到响应的时间 - 使用
std::chrono::high_resolution_clock(比system_clock更精确)或rdtsc指令进行计时,避免系统时钟的误差
内容的提问来源于stack exchange,提问作者Rohith Uppala
相关产品推荐
相关产品推荐

