.NET Core HttpClient请求异常分析

推送逻辑是在类库中使用HttpClient,所以没有使用HttpClientFactory,因此定义静态变量来使用HttpClient,而非每一个请求就实例化一个HttpClient,

接下来我们来详细分析项目示例代码并对其进行改进

static class Program
{
    static HttpClient httpClient = CreateHttpClient();
    static Program()
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

        ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, error) => true,
    }

    static async Task Main(string[] args)
    {
        await httpClient.PostAsync("", new StringContent(""));
    }

    static HttpClient CreateHttpClient()
    {
        var client = new HttpClient(new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true
        })
        {
            Timeout = TimeSpan.FromSeconds(30)
        };

        client.DefaultRequestHeaders.Accept.Clear();

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("ContentType", "application/json");
        return client;
    }
}

若对接方仅使用HTTPS协议,无需验证证书,最好是忽略证书验证,否则有可能会引起建立验证证书连接异常,即添加

ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true

我们观察上述代码,有两个地方都对证书验证进行了设置,一个是在静态构造函数中ServicePointManager(简称SP),另外则在实例化HttpClient构造函数中即HttpClientHandler(简称HCH),那么这二者是否有使用上的限制呢?

在.NET Framework中,内置的HttpClient建立在HttpWebRequest之上,因此可以使用SP来配置

在.NET Core中,通过SP配置证书信息仅影响HttpWebRequest,而对HttpClient无效,需通过HCH配置来达到相同目的

所以去除在静态构造函数中对忽略证书的配置,改为在HttpClientHandler中

var client = new HttpClient(new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
    SslProtocols = SslProtocols.Tls12
})

 

配置keep-alive我们俗称为保活机制,所以在默认请求头中添加如下一行

 //增加保活机制,表明连接为长连接
 client.DefaultRequestHeaders.Connection.Add("keep-alive");

上述只是在报文头中添加持久化连接标识,但不意味着就一定生效,因为默认是禁用持久化连接,所以为了保险起见,添加如下代码

  //启用保活机制(保持活动超时设置为 2 小时,并将保持活动间隔设置为 1 秒。)
  ServicePointManager.SetTcpKeepAlive(true, 7200000, 1000);
public static void SetTcpKeepAlive(bool enabled, int keepAliveTime, int keepAliveInterval)
{
    if (enabled)
    {
        if (keepAliveTime <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(keepAliveTime));
        }
        if (keepAliveInterval <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(keepAliveInterval));
        }
    }
}

最关键的一点则是默认持久化连接数为2,非持久化连接为4

public class ServicePointManager { public const int DefaultNonPersistentConnectionLimit = 4; public const int DefaultPersistentConnectionLimit = 2; private ServicePointManager() { } }

那么问题是否就已很明了,项目中使用非持久化连接,即连接为4,未深究源码具体细节,大胆猜想一下,若连接大于4,是否会出现将此前连接主动关闭,重建新的连接请求呢?最终我们将原始代码修改为如下形式

static class Program
{
    static HttpClient httpClient = CreateHttpClient();

    static Program()
    {
        //默认连接数限制为2,增加连接数限制
        ServicePointManager.DefaultConnectionLimit = 512;

        //启用保活机制(保持活动超时设置为 2 小时,并将保持活动间隔设置为 1 秒。)
        ServicePointManager.SetTcpKeepAlive(true, 7200000, 1000);
    }

    static async Task Main(string[] args)
    {
        await httpClient.PostAsync("", new StringContent(""));

        Console.WriteLine("Hello World!");
    }

    static HttpClient CreateHttpClient()
    {
        var client = new HttpClient(new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
            SslProtocols = SslProtocols.Tls12
        })
        {
            Timeout = TimeSpan.FromSeconds(30)
        };

        client.DefaultRequestHeaders.Accept.Clear();
        //增加保活机制,表明连接为长连接
        client.DefaultRequestHeaders.Connection.Add("keep-alive");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("ContentType", "application/json");
        return client;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/275630.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言之字符串处理

目录 字符串长度 显示字符串 数字字符的出现次数 大小写字符转换 字符串数组的参数传递 非字符串的字符数组 目前我们所学习到的是围绕字符串的处理&#xff0c;仅仅是生成字符串、读取并显示字符串&#xff0c;下面我学习更加灵活处理字符串的方式。 字符串长度 我们来看…

基于Java+SpringBoot+vue+elementui的校园文具商城系统详细设计和实现

基于JavaSpringBootvueelementui的校园文具商城系统详细设计和实现 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目录 基于JavaSpringBootvueelementui的校园文具商城系统详细设计和实现前言介绍&#xff1a;系统设计&#xff1a;系统开发流程用户登录流程系统操作流程 功能…

jenkins+mvn使用自定义jdk

jenkins2.357开始已经全面放弃jdk1.8从而使用openjdk11,但是项目一般都是用的比较老的java环境打包构建 一. 配置java环境(此方式测试有问题) 1.1 新增不同jdk配置和路径 1.2 新增后项目选择对应java8 1.3 构建命令 1.4 打包构建失败 原因在build阶段多了 mvn命令导致去掉就…

掌握激活函数(一):深度学习的成功之源

文章目录 引言基本概念常用激活函数举例Sigmoid激活函数公式Sigmoid函数的数学特性示例基于NumPy和PyTorch实现Sigmoid函数将Sigmoid函数应用于二分类任务 Sigmoid激活函数的局限性举例 ReLU激活函数公式ReLU函数的数学特性ReLU函数的特点示例基于NumPy和PyTorch实现ReLU函数搭…

C语言——数据在内存中的存储【整型数据在内存中的储存,大小端字节序储存,浮点型数据在内存中的储存】

&#x1f4dd;前言&#xff1a; 在前面的三篇文章中我们已经完成了对字符函数和字符串函数的学习&#xff0c;现在就让我们探索新领域&#xff0c;更加深入的理解**数据在内存中的存储方式**&#xff1a; 1&#xff0c;整数在内存中的存储 2&#xff0c;⼤⼩端字节序存储 3&…

GitOps实践指南:GitOps能为我们带来什么?

Git&#xff0c;作为开发过程中的核心工具&#xff0c;提供了强大的版本控制功能。即便在写代码的时候稍微手抖一下&#xff0c;我们也能通过 Git 的差异对比&#xff08;diff&#xff09;轻松追踪到庞大工程中的问题&#xff0c;确保代码的准确与可靠。这种无与伦比的自省能力…

FreeRTOS中断、临界区和任务调度器

一、中断 中断是 CPU 的一种常见特性&#xff0c;中断一般由硬件产生&#xff0c;当中断发生后&#xff0c;会中断 CPU 当前正 在执行的程序而跳转到中断对应的服务程序种去执行&#xff0c;ARM Cortex-M 内核的 MCU 具有一个 用于中断管理的嵌套向量中断控制器NVIC。ARM Cort…

【数据库】为什么要分库分表

为什么要分库分表 1.为什么要分库分表&#xff1f;2.垂直拆分3.水平拆分4.总结4.1 逻辑库和物理库4.2 逻辑表和物理表 1.为什么要分库分表&#xff1f; 随着近些年信息化大跃进&#xff0c;各行各业无纸化办公产生了大量的数据&#xff0c;而越来越多的数据存入了数据库中。当…

Vue 问题解决

一、问题&#xff1a;TypeError: (0 , _message.default) is not a function 当没有default时,在其他页面import引入的时&#xff0c;必须加{}。 二、问题&#xff1a;Vue前端页面的表格数据总是一行一行的显示 使用Async/Await来解决前端数据一行一行显示的问题。可以将获取部…

python 实现粒子群算法(带绘制)

本文章用python实现了粒子群算法&#xff0c; 标准PSO的算法流程如下&#xff1a; 初始化一群微粒&#xff08;群体规模为m&#xff09;&#xff0c;包括随机的位置和速度&#xff1b;评价每个微粒的适应度&#xff1b;对每个微粒&#xff0c;将它的适应值和它经历过的最好位…

众和策略股市行情分析:股票开户后什么时候能交易?

股票开户后什么时候能生意&#xff1f; 股票开户后不才一生意日便能正常展开生意操作&#xff0c;包含申报股票生意及非生意事务。假设投资者是周五或接近节假期时结束的开户&#xff0c;就要不才周一或假期结束后才华进行生意。 当然&#xff0c;假设投资者注册的是一些特别…

BDD - Python Behave 配置文件 behave.ini

BDD - Python Behave 配置文件 behave.ini 引言behave.ini配置参数的类型配置项 behave.ini 应用feature 文件step 文件创建 behave.ini执行 Behave 引言 前面文章 《BDD - Python Behave Runner Script》就是为了每次执行 Behave 时不用手动敲一长串选项&#xff0c;其实还有…

《深入理解C++11:C++11新特性解析与应用》笔记四

第四章 新手易学&#xff0c;老兵易用 4.1 右尖括号>的改进 在 C98 中&#xff0c;有一条需要程序员规避的规则:如果在实例化模板的时候出现了连续的两个右尖括号 >&#xff0c;那么它们之间需要一个空格来进行分隔&#xff0c;以避免发生编译时的错误。C98 会将>&g…

【量化】蜘蛛网策略复现

文章目录 蜘蛛网策略研报概述持仓数据整理三大商品交易所的数据统一筛选共有会员清洗数据计算研报要求数据全部代码 策略结果分析无参数策略有参数策略正做反做 MSD技术指标化 蜘蛛网策略 策略来自《东方证券-股指期货趋势交易之蜘蛛网策略——从成交持仓表中捕捉知情投资者行为…

腾讯云轻量应用服务器详细介绍

腾讯云轻量应用服务器开箱即用、运维简单的轻量级云服务器&#xff0c;CPU内存带宽配置高并且价格特别优惠&#xff0c;轻量2核2G3M带宽62元一年、2核2G4M优惠价118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;756元3年、4核8G12M带宽646元15个月等&#xf…

Linux操作系统:LVM与磁盘配额

目录 一、LVM逻辑卷管理基础 1、LVM逻辑卷管理的概念 2、LVM逻辑卷管理的核心组件 3、LVM逻辑卷管理的优势 4、LVM逻辑卷管理的命令 4.1 扫描命令的用法 4.1.1 pvscan 4.1.2 vgscan 4.1.3 lvscan 4.2 查看命令的用法 4.2.1 pvdisplay 4.2.2 vgdisplay 4.2.3 lvdis…

12.27_黑马数据结构与算法笔记Java(补2)

目录 279 0-1 背包问题 动态规划 实现 280 0-1 背包问题 动态规划 降维 281 完全背包问题 动态规划 分析 282 完全背包问题 动态规划 实现 283 零钱兑换问题 动态规划 分析 284 零钱兑换问题 动态规划 实现 285 零钱兑换问题 动态规划 降维 286 零钱兑换II 动态规划 分析…

【idea】运行工程时候卡了许久Java Method Breakpoints

老以为是数据库连接不上&#xff0c;此问题概率性小&#xff0c;操作上面不小心打了断点… 应该是打断点的时候&#xff0c;打到了方法上面&#xff0c;去掉哟 Java Method Breakpoints

C++day2作业

把课上strcut的练习&#xff0c;尝试着改成class #include <iostream>using namespace std; class Stu { private:int age;string sex;int hign; public:int soce;void get_information();void set_information(); }; void Stu::set_information() {static Stu s1;cout …

C++ DAY2作业

1.课堂struct练习&#xff0c;用class&#xff1b; #include <iostream>using namespace std;class Stu { private:int age;char sex;int high; public:double score;void set_values(int a,char b,int c,double d);int get_age();char get_sex();int get_high(); }; vo…
最新文章