当前位置: 首页 > news >正文

.net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池

public class HttpClientPool : IDisposable
{private readonly ConcurrentQueue<HttpClient> _httpClientPool; // HttpClient 对象池private readonly SemaphoreSlim _semaphore; // 控制同时访问 HttpClient 对象池的线程数private readonly TimeSpan _timeout; // 获取 HttpClient 的超时时间private readonly int _maxRetries; // 最大重试次数private readonly TimeSpan _circuitBreakerTimeout; // 熔断器超时时间private readonly int _consecutiveFailuresThreshold; // 连续失败阈值private bool _circuitBreakerTripped; // 熔断器是否触发private DateTime _circuitBreakerTrippedTime; // 熔断器触发时间private int _consecutiveFailures; // 连续失败计数器public HttpClientPool(int maxPoolSize, // 最大 HttpClient 对象池大小TimeSpan timeout, // 获取 HttpClient 的超时时间int maxRetries, // 最大重试次数TimeSpan circuitBreakerTimeout, // 熔断器超时时间int consecutiveFailuresThreshold // 连续失败阈值){_httpClientPool = new ConcurrentQueue<HttpClient>();_semaphore = new SemaphoreSlim(maxPoolSize);_timeout = timeout;_maxRetries = maxRetries;_circuitBreakerTimeout = circuitBreakerTimeout;_consecutiveFailuresThreshold = consecutiveFailuresThreshold;_circuitBreakerTripped = false;}public async Task<HttpResponseMessage> SendRequestWithRetries(string url){var retryCount = 0;_consecutiveFailures = 0;while (retryCount <= _maxRetries){try{var httpClient = await GetHttpClientAsync();var response = await httpClient.GetAsync(url);if (response.IsSuccessStatusCode){_consecutiveFailures = 0; // 重置连续失败计数器return response;}else{_consecutiveFailures++;if (_consecutiveFailures >= _consecutiveFailuresThreshold){TripCircuitBreaker(); // 连续失败达到阈值,触发熔断器throw new InvalidOperationException("连续失败次数达到阈值,熔断器已触发。");}retryCount++;}}catch (Exception ex){_consecutiveFailures++;if (_consecutiveFailures >= _consecutiveFailuresThreshold){TripCircuitBreaker(); // 连续失败达到阈值,触发熔断器throw new InvalidOperationException("连续失败次数达到阈值,熔断器已触发。");}retryCount++;}}throw new Exception($"重试 {_maxRetries} 次后仍然无法发送请求。");}private async Task<HttpClient> GetHttpClientAsync(){if (_circuitBreakerTripped){var elapsedTime = DateTime.Now - _circuitBreakerTrippedTime;if (elapsedTime < _circuitBreakerTimeout){throw new InvalidOperationException("熔断器已触发,请稍后重试。");}else{// 重置熔断器_circuitBreakerTripped = false;}}if (await _semaphore.WaitAsync(_timeout)){if (_httpClientPool.TryDequeue(out var httpClient)){return httpClient;}}throw new TimeoutException("获取 HttpClient 超时。");}public void ReturnHttpClient(HttpClient httpClient, bool success){if (success){_httpClientPool.Enqueue(httpClient);_semaphore.Release();}else{// 触发熔断器TripCircuitBreaker();httpClient.Dispose();_semaphore.Release();}}private void TripCircuitBreaker(){_circuitBreakerTripped = true;_circuitBreakerTrippedTime = DateTime.Now;_consecutiveFailures = 0;}public void Dispose(){foreach (var httpClient in _httpClientPool){httpClient.Dispose();}_httpClientPool.Clear();_semaphore.Dispose();}
}

调用端
 

public class Program
{public static async Task Main(){// 创建 HttpClientPoolvar httpClientPool = new HttpClientPool(maxPoolSize: 10,timeout: TimeSpan.FromSeconds(5),maxRetries: 3,circuitBreakerTimeout: TimeSpan.FromMinutes(10),consecutiveFailuresThreshold: 5);try{var response = await httpClientPool.SendRequestWithRetries("https://api.example.com");var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);}catch (Exception ex){Console.WriteLine($"请求失败:{ex.Message}");}}
}

相关文章:

.net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池

public class HttpClientPool : IDisposable {private readonly ConcurrentQueue<HttpClient> _httpClientPool; // HttpClient 对象池private readonly SemaphoreSlim _semaphore; // 控制同时访问 HttpClient 对象池的线程数private readonly TimeSpan _timeout; // 获…...

大促期间如何监测竞品数据

无论在什么时候&#xff0c;竞品的数据都是品牌非常关注的&#xff0c;大促当然也不例外&#xff0c;所以准确监测到竞品数据应该如何分析也很关键&#xff0c;通过分析竞品&#xff0c;品牌可以获取非常多有价值的内容&#xff0c;如竞品王牌产品的分析、行业分析报告等。 力维…...

Linux yum 没有可用软件包 fping。 错误:无须任何处理 的解决办法

yum install fping -y 报错解决&#xff1a; [rootcpcs-node-d4n591 ~]# yum install fping -y 已加载插件&#xff1a;fastestmirror Determining fastest mirrors* base: mirrors.aliyun.com* extras: mirrors.aliyun.com* updates: mirrors.aliyun.com base …...

人工智能与脑机接口:开启人机融合的新时代

人工智能与脑机接口&#xff1a;开启人机融合的新时代 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;我们正与一个全新的时代相遇——人工智能与脑机接口相融合的时代。这个时代将带来前所未有的变革&#xff0c;让人类与机器的交互方式发生根本性的改变。…...

【多线程面试题二十二】、 说说你对读写锁的了解

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说说你对读写锁的了解 …...

Panda3d 相机控制

Panda3d 相机控制 文章目录 Panda3d 相机控制Panda3d中的透视镜头和垂直镜头透视镜头垂直镜头 Panda3d 中用代码控制相机的移动用键盘控制相机的移动用鼠标控制相机的移动 Panda3d 把相机也当做是一个 PandaNode&#xff0c;因此可以向操作其他节点对其进行操作。 真正的相机是…...

Linux(CentOS)安装MySQL教程

主要参考链接 教程 1. 准备工作 1.1 安装CentOS虚拟机 教程点击 1.2 将CentOS虚拟机设置为静态IP&#xff0c;否则你每次重启虚拟机后连接数据库都要重新查IP 教程点击 1.3 如果有安装过MySQL&#xff0c;请先卸载MySQL 教程点击 1.4 虚拟机执行命令su切换到root账号(输…...

使用 OpenSSL 工具撰写 Bash 脚本进行密码明文的加密与解密

使用 OpenSSL 工具进行密码明文的加密与解密 Written By: Xinyao Tian 简介 本文档描述了使用 OpenSSL 工具在 Bash 脚本中对密码进行加密和解密的简单方式。 BASE64 的加密与解密脚本 使用 Base64 算法进行密码的加密 脚本名称为 encryptPasswd.sh, 脚本内容如下: #!/b…...

uniapp之actionsheet 自定义组件

uniapp本身自带的actionsheet太丑&#xff0c;不够美观。闲着也是闲着&#xff0c;自己实现了一个类似的选择器。 支持功能&#xff1a; 1、左对齐 2、右对齐 3、居中 4、可加图标 下面贴出使用教程&#xff1a; <template><view><action-sheet alignment&…...

在nodejs中使用Mongoose和MongoDB实现curd操作

在nodejs中使用Mongoose和MongoDB实现curd操作 在Node.js中&#xff0c;数据库被用来存储和检索Web应用程序的数据。它们是构建动态和可伸缩应用程序的重要组成部分。Node.js提供了各种模块和包,可以与数据库一起工作,如MySQL、PostgreSQL、MongoDB等。它们允许开发人员使用各…...

10.28 校招 实习 内推 面经

绿*泡*泡&#xff1a; neituijunsir 交流裙 &#xff0c;内推/实习/校招汇总表格 1、校招&#xff5c;理想汽车2024校园招聘算法类岗位特辑&#xff08;内推&#xff09; 校招&#xff5c;理想汽车2024校园招聘算法类岗位特辑&#xff08;内推&#xff09; 2、校招 | 国网信…...

Azure 机器学习 - 使用无代码 AutoML 训练分类模型

了解如何在 Azure 机器学习工作室中使用 Azure 机器学习自动化 ML&#xff0c;通过无代码 AutoML 来训练分类模型。 此分类模型预测某个金融机构的客户是否会认购定期存款产品。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管…...

【调试技术】用户态查看PEB和TEB

概述&#xff1a;用户态查看进程 PEB 和 TEB(通过windbg附加或启动调试的exe) 0x01 用户态查看 TEB 和 PEB 在双机调试的时候&#xff0c;可以直接使用 !PEB PID 和 !TEB TID 获取进程和线程的相关信息&#xff0c;在用户态这两个命令就会失效。原因就是用户态不支持大写的 !T…...

如何搭建一个Spring MVC和Vue3的应用程序

要搭建一个基于Spring MVC框架和Vue3框架的前端应用程序&#xff0c;可以按照以下步骤进行&#xff1a; 创建Java项目并添加Spring MVC依赖 使用Maven或Gradle等构建工具创建一个Java项目&#xff0c;并在项目的pom.xml或build.gradle文件中添加Spring MVC依赖。例如&#xf…...

CSS3设计动画样式

CSS3动画包括过渡动画和关键帧动画&#xff0c;它们主要通过改变CSS属性值来模拟实现。我将详细介绍Transform、Transitions和Animations 3大功能模块&#xff0c;其中Transform实现对网页对象的变形操作&#xff0c;Transitions实现CSS属性过渡变化&#xff0c;Animations实现…...

AtCoder abc 144

D - Water Bottle x先除以a&#xff0c;得到面积。体积和面积是等同考虑的。 分两种情况&#xff0c;一种是水比一半面积少&#xff0c;一种是水比一半面积多。 # -*- coding: utf-8 -*- # time : 2023/6/2 13:30 # author : yhdutongwoo.cn # desc : # file : …...

【开题报告】基于SpringBoot的医美在线预约系统的设计与实现

1.研究背景 医美行业是指结合医学和美容技术&#xff0c;为人们提供外貌改善和整容手术等服务的领域。随着社会经济的发展和人们审美观念的变化&#xff0c;医美行业得到了快速的发展&#xff0c;并受到越来越多人的关注和需求。 传统的医美预约方式主要依赖于电话预约或现场…...

AutoGen agent使用;调用本地LLM

参考&#xff1a; https://microsoft.github.io/autogen 安装&#xff1a; pip install pyautogen 代码 本地LLM部署可以用fastchat、vllm等框架部署openai接口&#xff1a; from autogen import AssistantAgent, UserProxyAgent, oai ## 调用本地模型对外的openai接口 conf…...

Docker安装matomo

Docker安装matomo 文章目录 Docker安装matomo1.安装Docker2.matomo安装 1.安装Docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun2.matomo安装 #拉取matomo镜像 docker pull matomo#启动matomo容器 docker run -d --name matomo -p 8093:80 -v /do…...

副对角线以上和以下都为0的行列式求解

...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...