如何避免 .NET 中 HttpClient 的 DNS 失效问题?

HttpClient 可以用来发送 HTTP 请求。HttpClient 可以设置为单例并在整个生命周期中重复使用。这是因为,HttpClient 有一个“连接池”来重用连接并减少 TCP 连接的数量。因此,如果您向同一主机发送多个请求,它们将重用相同的连接。这样,应用程序就不会在重负载下耗尽可用的套接字数量(如果使用 HttpClient 的方式有误,将会影响软件的稳定性)。此外,这种方式可以避免对同一主机的每个请求进行握手(TCP 握手、TLS 握手)从而提高应用程序的性能。

保持连接打开对提升性能有益处,但必须避免保持陈旧的连接。如果主机更改了 IP 地址怎么办?例如,如果 DNS TTL 过期,主机可能会更改其 IP 地址。在这种情况下,应该关闭已经打开的连接并打开一个新的。HttpClient 不会自动执行此操作,因为它感知不到 DNS TTL。尽管如此,可以通过设置超时时间来自动关闭链接。这样,下一个请求将需要重新打开连接,并使用 DNS 查找新的 IP 地址。

您可以使用 SocketsHttpHandler 来配置 HttpClient 及其连接池的行为。有 2 个属性需要配置:PooledConnectionIdleTimeout和PooledConnectionLifetime 。这些属性允许在一定时间后强制关闭连接。这样,下一个请求将打开一个新连接,以反映 DNS 或其他网络更改。

默认情况下,空闲连接会在 1 分钟后关闭。但是,活动连接永远不会关闭。因此必须明确设置PooledConnectionLifetime 为所需的值。

using System.Net;using var socketHandler = new SocketsHttpHandler()
{// 池中连接的最大空闲时间。当达到最大空闲时间时,连接将会被释放。// 在 .NET 6 中,该属性的默认值是 1 分钟PooledConnectionIdleTimeout = TimeSpan.FromMinutes(1),//此属性定义池中连接的最大连接寿命,无论连接是空闲还是活动性。//在 .NET 6 中,该属性的默认值是从不过期//设置超时时间以反映 DNS 或其他网络更改PooledConnectionLifetime = TimeSpan.FromMinutes(1),
};using var httpClient = new HttpClient(socketHandler);var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
while (await timer.WaitForNextTickAsync())
{_ = await httpClient.GetStringAsync("https://www.coderbusy.com");
}

避免 DNS 问题的另一种方法是使用 IHttpClientFactory

如何调试

如果您想知道 HttpClient 何时查询 DNS,可以使用 EventListener 。这是因为 System.Net.* 命名空间下的对象会发出 ETW 追踪信息。

using System.Diagnostics.Tracing;_ = new NetEventListener();using var socketHandler = new SocketsHttpHandler()
{PooledConnectionIdleTimeout = TimeSpan.FromMinutes(1),PooledConnectionLifetime = TimeSpan.FromSeconds(10),
};using var httpClient = new HttpClient(socketHandler);var timer = new PeriodicTimer(TimeSpan.FromSeconds(2));
while (await timer.WaitForNextTickAsync())
{_ = await httpClient.GetStringAsync("https://www.coderbusy.com");
}class NetEventListener : EventListener
{protected override void OnEventSourceCreated(EventSource eventSource){if (eventSource.Name.StartsWith("System.Net"))EnableEvents(eventSource, EventLevel.Informational);}protected override void OnEventWritten(EventWrittenEventArgs eventData){if (eventData.EventName == "ResolutionStart"){Console.WriteLine(eventData.EventName + " - " + eventData.Payload[0]);}else if (eventData.EventName == "RequestStart"){Console.WriteLine(eventData.EventName + " - " + eventData.Payload[1]);}}
}

当您运行此应用程序时,您应该会看到应用程序何时执行 http 请求和 DNS 请求:

RequestStart - www.coderbusy.com
ResolutionStart - www.coderbusy.com
RequestStart - www.coderbusy.com
RequestStart - www.coderbusy.com
RequestStart - www.coderbusy.com
RequestStart - www.coderbusy.com
RequestStart - www.coderbusy.com
RequestStart - www.coderbusy.com
ResolutionStart - www.coderbusy.com

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

POJ 1159 Palindrome(字符串变回文:LCS)

POJ 1159 Palindrome(字符串变回文:LCS) http://poj.org/problem?id1159 题意: 给你一个字符串, 问你做少须要在该字符串中插入几个字符能是的它变成一个回文串. 分析: 首先把原字符串和它的逆串进行匹配, 找出最长公共子序列. 那么最长公共子序列的字符串肯定是一个回文串. 所…

java excutorthread_Java中ThreadPoolExecutor的参数理解

一、使用Executors创建线程池之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去new ThreadPoolExecutor1. newFixedThreadPool()创建线程数固定大小的线程池。 由于使用…

yii1.0性能调优之改善并发数

开启YII的APC缓存 在config/main.php components 组件下添加: apccache>array(class>system.caching.CApcCache), 下载php_apc.dll,文件放到php/ext 下,搜索时可能会比较麻烦.... 在php.ini 中添加php_apc扩展: extension…

windows下apache报错The requested operation has failed解决方法

2019独角兽企业重金招聘Python工程师标准>>> Apache报错The requested operation has failed,基本上是因为端口被占用。解决方法如下: 第一步,运行cmd,cd 定位到Apache安装目录的bin目录下,输入httpd.exe -…

stm32 usmart使用

我直接用正点原子给的,步骤如下 先添加三个.c进工程,添加两个头文件的编译路径 #include "usart.h"#include "usmart.h" main函数里添加如下 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2 uart_init(960…

Scylla——开源免费的优秀代理 IP 池:自动验证、JSON API、基于 React 的 Web UI、Docker 支持...

GitHub:github.com/imWildCat/s… 中文文档:scylla.wildcat.io/zh/latest/ 自己是一个爬虫爱好者,有时候爬虫写的太过强大了被目标网站封了(笑)。所以就萌生了用代理 IP 的想法。很可惜很多开源代理 IP 池都是没有持续…

vs2015提示中文

解决方案:1.找到这个目录C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework 进入 \v4.0\zh-Hans的目录,全部复制,覆盖掉\v4.5\zh-Hans就行了

Istio 1.15 发布,支持 arm64 架构处理器

Istio 是基于容器的云原生技术栈的三大核心技术之一,另外两个是 Kubernetes 和 Knative。其中 Kubernetes 和 Knative 早已支持了 arm64 架构,甚至连 Istio 的数据平面 Envoy 早在 1.16 版本 [1] 就已支持 arm64 架构(2020 年 10 月&#xff…

TP框架表单验证 【包含ajax方法】

之前的表单验证都是用js写的,这里也可以使用tp框架的验证。但是两者比较而言还是js验证比较好,因为tp框架验证会运行后台代码,这样运行速度和效率就会下降。  自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创…

Spring 入门学习二之IOC

今天来学习Spring ioc .一、spring jar 包导入 在 spring 官网下载开发包 spring-framework-4.2.4.RELEASE,然后导入需要的 jar 包到项目 /lib/ 目录下。  二、代码开发 新建一个 src/cn/sxt/bean/Hello.java文件 package cn.sxt.bean;/*** Created by kaiyiwang o…

java 物理内存_聊聊Java中的内存

JVM的内存先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8)那么一个Java进程最大占用的物理内存为:Max Memory eden survivor old String Constant Pool Code cache compressed class space Metaspace Thread st…

.Net CoreRabbitMQ基本使用

队列模式https://www.rabbitmq.com/getstarted.html对以上几种模式进行简要分类,可以分成如下三类(RPC暂不考虑)简单队列模式,单发单收,一对一模式Worker模式,单发多收(一个消息一个接收者,多个消息多个接收者)&#x…

【微信小程序】:实现轮播图3秒滚动

wxml模板&#xff1a;&#xff08;数据一维数组&#xff09; <scroll-view scroll-y"true"><swiper autoplay"auto" interval"3000" duration"500"><block wx:for"{{home_pics}}" wx:for-index"index…

Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)

Linux基础&#xff1a;https://www.cnblogs.com/dunitian/p/4822808.html#linux 之前看到朋友还动不动 apt-get update upgrade&#xff0c;就很纳闷&#xff0c;后来发现原来他只是知道这个更新命令却不知其意&#xff0c;所以每次安装个包就把所有apt-get的常用清除更新命令打…

java获取tomcat目录结构_Tomcat目录结构详解

Tomcat目录结构图如下&#xff1a;bin目录存放一些可执行的二进制文件&#xff0c;.sh结尾的为linux下执行命令&#xff0c;.bat结尾的为windows下执行命令。catalina.sh&#xff1a;真正启动tomcat文件&#xff0c;可以在里面设置jvm参数。startup.sh&#xff1a;启动tomcat(需…

智慧农业物联网云平台方案

2019独角兽企业重金招聘Python工程师标准>>> 多比智慧农业物联网云平台解决方案结合了最先进的物联网、云计算、传感器、自动控制等, 在浏览器或手机客户端实时显示大棚、大田、温室等温度、湿度、PH值、光强度、CO2&#xff0c;或作为自动控制的参变量参与到自动控…

Linux下汇编语言学习笔记65 ---

这是17年暑假学习Linux汇编语言的笔记记录&#xff0c;参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译《汇编语言基于Linux环境》的书&#xff0c;喜欢看原版书的同学可以看《Assembly Language Step-By-Setp:Programming with Linux 3rd Edition》&#xff0c;非常感谢该…

python:继承日志模块生成自定义日志

1 继承日志模块生成自定义日志 from __future__ import absolute_importimport os import sys import time import datetime import logging import logging.handlers import tempfileDATE_FORMAT %Y-%m-%d %H:%M:%Sdef create_logfile():if SYAPI_LOG_TEST in os.environ:val…

使用JDBC获取Oracle连接时报错

The Network Adapter could not establish the connection 网络适配器不能创建连接 作为初学者的来说&#xff0c;这个问题让我找了好多次&#xff0c;每次重新开启电脑时就可以正常获取连接&#xff0c;过了一会儿&#xff0c;自己不知道做了什么就会又报错&#xff0c;…

.Net CoreRabbitMQ消息转发可靠机制(上)

前言生产者发送消息到了队列&#xff0c;队列推送数据给了消费者&#xff0c;这里存在一些问题需要思考下生产者如何确保消息一定投递到了队列中RabbitMQ 丢失了消息(下文暂不涉及这块)队列如何确保消费者收到了消息呢生产者可靠发送执行流程当生产者将消息发送出去后&#xff…