需引入重试逻辑与异步执行能力:一、用steady_timer实现指数退避重试;二、用packaged_task封装并返回future;三、用awaitable协程简化流程;四、用retrypolicy类解耦重试策略;五、用自定义completion_token注入重试逻辑。

如果您在C++中需要发起HTTP请求并确保网络波动或临时失败时仍能成功获取响应,则需引入重试逻辑与异步执行能力。以下是基于Boost.Asio实现带有重试机制的HTTP异步请求,并通过std::future获取结果的具体方法:
一、使用boost::asio::steady_timer配合async_wait实现指数退避重试
该方法利用steady_timer在每次请求失败后按指数增长的时间间隔触发下一次重试,避免密集轮询,同时保持异步非阻塞特性。每个重试尝试均封装为独立的async_connect → async_write → async_read操作链,失败时递归调度下一次重试。
1、定义重试参数:设置最大重试次数为3次,初始延迟为100毫秒,退避因子为2。
2、构造io_context对象与tcp::resolver实例,用于DNS解析与连接管理。
3、在首次请求失败回调中,检查当前重试计数;若未达上限,则创建steady_timer对象,设置超时时间为当前延迟值,并调用async_wait绑定重试发起函数。
4、重试发起函数中更新延迟值(乘以退避因子),并重新执行完整的HTTP GET请求流程。
5、所有异步操作均通过post或dispatch提交至io_context,确保线程安全与执行上下文一致。
二、封装异步操作为std::packaged_task并返回std::future
该方法将整个HTTP请求及重试逻辑封装进std::packaged_task
1、声明std::promise<:string>对象,用于存储最终响应体或错误信息。
2、构造std::packaged_task
3、将packaged_task通过io_context.post投递执行,立即返回对应std::future<:string>。
4、future支持调用.wait()阻塞等待,或.wait_for()设定超时,亦可直接.get()提取结果或传播异常。
三、使用boost::asio::awaitable配合co_await实现协程式重试流程
该方法借助Boost.Asio 1.70+提供的awaitable协程支持,将重试循环、超时控制与HTTP交互步骤自然地组织为顺序代码结构,避免回调嵌套,提升可读性与调试便利性。
1、定义返回类型为boost::asio::awaitable<:string>的协程函数,接收host、port、target等参数。
2、在协程体内使用boost::asio::use_awaitable作为完成令牌,调用async_connect、async_write、async_read等异步函数,每一步均以co_await挂起并自动恢复。
3、在外层while循环中控制重试次数,每次失败后调用co_await boost::asio::steady_timer(...).async_wait(boost::asio::use_awaitable),实现可控暂停。
4、将awaitable对象通过boost::asio::co_spawn提交至io_context,同时绑定处理完成回调,其中调用promise.set_value或set_exception。
5、外部通过promise.get_future()获取结果,无需感知协程调度细节。
四、集成boost::beast::http::async_read与自定义重试策略类
该方法将重试逻辑抽象为独立的RetryPolicy类,与beast的HTTP组件解耦,支持灵活配置重试条件(如仅对5xx响应重试)、最大持续时间、抖动因子等,提高复用性与测试性。
1、定义RetryPolicy接口,包含should_retry(const beast::error_code&, const http::response<:dynamic_body>&)和next_delay()成员函数。
2、在HTTP请求完成后,由policy判断是否应重试;若返回true,则计算下一次延迟并启动timer异步等待。
3、每次重试前克隆request对象,防止body被多次序列化或移动失效。
4、使用beast::flat_buffer管理读取缓冲区,确保多次read操作复用同一内存块。
5、所有beast异步操作统一使用同一个executor,避免跨executor访问导致未定义行为。
五、基于completion_token定制重试完成处理器
该方法通过自定义CompletionToken机制,在每次异步操作完成时注入重试决策逻辑,无需修改原始asynchronous operation签名,符合Boost.Asio的设计哲学。
1、定义retrying_completion_token模板类,继承自boost::asio::completion_token_for,重载operator()以包裹原始handler。
2、在operator()内部捕获error_code,根据预设规则决定是否重新发起请求;若是,则构造新请求并再次调用async_initiate流程。
3、将retrying_completion_token实例传入async_connect等函数,替代默认use_default_token。
4、原始handler仅在最终成功或耗尽重试次数后被调用,其参数包含完整响应或最后一次失败的error_code。
5、token内部维护重试计数器与延迟状态,确保每次重试上下文隔离且可追踪。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











