聊聊HttpClient的DnsResolver
序
本文主要研究一下HttpClient的DnsResolver
DnsResolver
org/apache/http/conn/DnsResolver.java
/*** Users may implement this interface to override the normal DNS lookup offered* by the OS.** @since 4.2*/
public interface DnsResolver {/*** Returns the IP address for the specified host name, or null if the given* host is not recognized or the associated IP address cannot be used to* build an InetAddress instance.** @see InetAddress** @param host* The host name to be resolved by this resolver.* @return The IP address associated to the given host name, or null if the* host name is not known by the implementation class.*/InetAddress[] resolve(String host) throws UnknownHostException;}
DnsResolver定义了resolve方法,可用于替换OS提供的DNS lookup
InMemoryDnsResolver
org/apache/http/impl/conn/InMemoryDnsResolver.java
/*** In-memory {@link DnsResolver} implementation.** @since 4.2*/
public class InMemoryDnsResolver implements DnsResolver {/** Logger associated to this class. */private final Log log = LogFactory.getLog(InMemoryDnsResolver.class);/*** In-memory collection that will hold the associations between a host name* and an array of InetAddress instances.*/private final Map<String, InetAddress[]> dnsMap;/*** Builds a DNS resolver that will resolve the host names against a* collection held in-memory.*/public InMemoryDnsResolver() {dnsMap = new ConcurrentHashMap<String, InetAddress[]>();}/*** Associates the given array of IP addresses to the given host in this DNS overrider.* The IP addresses are assumed to be already resolved.** @param host* The host name to be associated with the given IP.* @param ips* array of IP addresses to be resolved by this DNS overrider to the given* host name.*/public void add(final String host, final InetAddress... ips) {Args.notNull(host, "Host name");Args.notNull(ips, "Array of IP addresses");dnsMap.put(host, ips);}/*** {@inheritDoc}*/@Overridepublic InetAddress[] resolve(final String host) throws UnknownHostException {final InetAddress[] resolvedAddresses = dnsMap.get(host);if (log.isInfoEnabled()) {log.info("Resolving " + host + " to " + Arrays.deepToString(resolvedAddresses));}if(resolvedAddresses == null){throw new UnknownHostException(host + " cannot be resolved");}return resolvedAddresses;}}
InMemoryDnsResolver实现了DnsResolver接口,它用一个ConcurrentHashMap来存放dns信息,提供add方法往map添加host及对应的ip地址,然后其resolve就是从这个map来读取对应的ip地址信息
SystemDefaultDnsResolver
org/apache/http/impl/conn/SystemDefaultDnsResolver.java
/*** DNS resolver that uses the default OS implementation for resolving host names.** @since 4.2*/
public class SystemDefaultDnsResolver implements DnsResolver {public static final SystemDefaultDnsResolver INSTANCE = new SystemDefaultDnsResolver();@Overridepublic InetAddress[] resolve(final String host) throws UnknownHostException {return InetAddress.getAllByName(host);}}
SystemDefaultDnsResolver实现了DnsResolver,它用的就是jdk提供的InetAddress.getAllByName,默认是走的OS的DNS,可以通过
sun.net.spi.nameservice.provider.<n>去自定义
DefaultHttpClientConnectionOperator
org/apache/http/impl/conn/DefaultHttpClientConnectionOperator.java
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
public class DefaultHttpClientConnectionOperator implements HttpClientConnectionOperator {static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry";private final Log log = LogFactory.getLog(getClass());private final Lookup<ConnectionSocketFactory> socketFactoryRegistry;private final SchemePortResolver schemePortResolver;private final DnsResolver dnsResolver;public DefaultHttpClientConnectionOperator(final Lookup<ConnectionSocketFactory> socketFactoryRegistry,final SchemePortResolver schemePortResolver,final DnsResolver dnsResolver) {super();Args.notNull(socketFactoryRegistry, "Socket factory registry");this.socketFactoryRegistry = socketFactoryRegistry;this.schemePortResolver = schemePortResolver != null ? schemePortResolver :DefaultSchemePortResolver.INSTANCE;this.dnsResolver = dnsResolver != null ? dnsResolver :SystemDefaultDnsResolver.INSTANCE;}@Overridepublic void connect(final ManagedHttpClientConnection conn,final HttpHost host,final InetSocketAddress localAddress,final int connectTimeout,final SocketConfig socketConfig,final HttpContext context) throws IOException {final Lookup<ConnectionSocketFactory> registry = getSocketFactoryRegistry(context);final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName());if (sf == null) {throw new UnsupportedSchemeException(host.getSchemeName() +" protocol is not supported");}final InetAddress[] addresses = host.getAddress() != null ?new InetAddress[] { host.getAddress() } : this.dnsResolver.resolve(host.getHostName());final int port = this.schemePortResolver.resolve(host);for (int i = 0; i < addresses.length; i++) {final InetAddress address = addresses[i];final boolean last = i == addresses.length - 1;Socket sock = sf.createSocket(context);sock.setSoTimeout(socketConfig.getSoTimeout());sock.setReuseAddress(socketConfig.isSoReuseAddress());sock.setTcpNoDelay(socketConfig.isTcpNoDelay());sock.setKeepAlive(socketConfig.isSoKeepAlive());if (socketConfig.getRcvBufSize() > 0) {sock.setReceiveBufferSize(socketConfig.getRcvBufSize());}if (socketConfig.getSndBufSize() > 0) {sock.setSendBufferSize(socketConfig.getSndBufSize());}final int linger = socketConfig.getSoLinger();if (linger >= 0) {sock.setSoLinger(true, linger);}conn.bind(sock);final InetSocketAddress remoteAddress = new InetSocketAddress(address, port);if (this.log.isDebugEnabled()) {this.log.debug("Connecting to " + remoteAddress);}try {sock = sf.connectSocket(connectTimeout, sock, host, remoteAddress, localAddress, context);conn.bind(sock);if (this.log.isDebugEnabled()) {this.log.debug("Connection established " + conn);}return;} catch (final SocketTimeoutException ex) {if (last) {throw new ConnectTimeoutException(ex, host, addresses);}} catch (final ConnectException ex) {if (last) {final String msg = ex.getMessage();throw "Connection timed out".equals(msg)? new ConnectTimeoutException(ex, host, addresses): new HttpHostConnectException(ex, host, addresses);}} catch (final NoRouteToHostException ex) {if (last) {throw ex;}}if (this.log.isDebugEnabled()) {this.log.debug("Connect to " + remoteAddress + " timed out. " +"Connection will be retried using another IP address");}}}//......
}
DefaultHttpClientConnectionOperator的connect方法会通过dnsResolver.resolve解析host
小结
HttpClient提供了DnsResolver接口,可以用于自定义DNS解析,是除了使用sun.net.spi.nameservice.provider.<n>去自定义JDK全局dns解析外的另外一种方案。
相关文章:
聊聊HttpClient的DnsResolver
序 本文主要研究一下HttpClient的DnsResolver DnsResolver org/apache/http/conn/DnsResolver.java /*** Users may implement this interface to override the normal DNS lookup offered* by the OS.** since 4.2*/ public interface DnsResolver {/*** Returns the IP a…...
剑指智能驾驶,智己LS6胜算几何?
监制 | 何玺 排版 | 叶媛 10月12日,IM智己旗下的新车智己LS6宣布上市。 新车型搭载尖端科技多项,其中以“全画幅数字驾舱屏”、和城市高阶智能辅助驾驶为核心的智驾技术,更是引来众多用户关注。 01 新能源新卷王智己LS6 智己LS6一发布就…...
网络工程师知识点5
71、什么是FTP? FTP是文件传输协议。 FTP传输数据时支持两种传输模式:ASCII模式和二进制模式。 需要TCP的21号端口来建立控制连接 需要TCP的20号端口来建立数据连接 72、什么是telnet? Telnet提供了一个交互式操作界面,允许终端远…...
未来展望:大型语言模型与 SQL 数据库集成的前景与挑战
一、前言 随着 GPT-3、PaLM 和 Anthropic 的 Claude 等大型语言模型 (LLM) 的出现引发了自然语言在人工智能领域的一场革命。这些模型可以理解复杂的语言、推理概念并生成连贯的文本。这使得各种应用程序都能够使用对话界面。然而,绝大多数企业数据都存储在结构化 …...
SpringCloud-Hystrix
一、介绍 (1)避免单个服务出现故障导致整个应用崩溃。 (2)服务降级:服务超时、服务异常、服务宕机时,执行定义好的方法。(做别的) (3)服务熔断:达…...
Ansible脚本进阶---playbook
目录 一、playbooks的组成 二、案例 2.1 在webservers主机组中执行一系列任务,包括禁用SELinux、停止防火墙服务、安装httpd软件包、复制配置文件和启动httpd服务。 2.2 在名为dbservers的主机组中创建一个用户组(mysql)和一个用户&#x…...
pytorch 模型部署之Libtorch
Python端生成pt模型文件 net.load(model_path) net.eval() net.to("cuda")example_input torch.rand(1, 3, 240, 320).to("cuda") traced_model torch.jit.trace(net, example_input) traced_model.save("model.pt")output traced_model(exa…...
Unity——数据存储的几种方式
一、PlayerPrefs PlayerPrefs适合用于存储简单的键值对数据 存储的数据会在游戏关闭后依然保持,并且可以在不同场景之间共享,适合用于需要在游戏不同场景之间传递和保持的数据。 它利用key-value的方式将数据保存到本地,跟字典类似。然后通…...
『heqingchun-ubuntu系统下安装cuda与cudnn』
ubuntu系统下安装cuda与cudnn 一、安装依赖 1.更新 sudo apt updatesudo apt upgrade -y2.基础工具 sudo apt install -y build-essential python二、安装CUDA 1.文件下载 网址 https://developer.nvidia.com/cuda-toolkit-archive依次点击 (1)“CUDA Toolkit 11.6.2”…...
Unity AI Muse 基础教程
Unity AI Muse 基础教程 Unity AI 内测资格申请Unity 项目Package ManagerMuse Sprite 安装Muse Texture 安装 Muse Sprite 基础教程什么是 Muse Sprite打开 Muse Sprite 窗口Muse Sprite 窗口 参数Muse Sprite Generations 窗口 参数Muse Sprite Generations 窗口 画笔Muse Sp…...
pgsl基于docker的安装
1. 有可用的docker环境 ,如果还没有安装docker,则请先安装docker 2. 创建pg数据库的挂载目录 mkdir postgres 3. 下载pg包 docker pull postgres 这个命令下载的是最新的pg包,如果要指定版本的话,则可以通过在后面拼接 :versio…...
idea设置某个文件修改后所在父文件夹变蓝色
idea设置某个文件修改后所在父文件夹变蓝色的方法: 老版idea设置方法: File---->Settings---->Version Control---->勾选 Show directories with changed descendants 新版idea设置方法: File---->Settings---->Version Co…...
代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离
代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离 一、583. 两个字符串的删除操作 题目链接:https://leetcode.cn/problems/delete-operation-for-two-strings/ 思路:定义dp[i][j]为要是得区间[0,i-1]和区间[0,j-1]所需要删除…...
秋日有感之秋诉-于光
诗:于光 秋风扫叶枝不舍, 叶落随风根欢唱。 秋日穿云不入眼, 云亦婆娑诉余年。...
ubuntu 22.04版本修改服务器名、ip,dns信息的操作方法
总结 1、ubuntu修改服务器名重启后生效的方法是直接修改/etc/hostname文件 2、ubuntu 22.04操作系统配置ip和dns信息,一般只需要使用netplan命令行工具来配置就行,在/etc/netplan/在目录下创建一个yaml文件就可以实现ip和dns的配置,当然如果…...
【微信小程序】6天精准入门(第2天:小程序的视图层、逻辑层、事件系统及页面生命周期)
一、视图层 View 1、什么是视图层 框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。WXML(WeiXin Markup language) 用于描述页面的结构。WXS(WeiXin Script) 是小程序的一套脚本语言&am…...
速学Linux丨一文带你打开Linux学习之门
前言 如果你是刚开始学习Linux的小白同学,相信你已经体会到与学习一门编程语言相比,学习Linux系统的门槛相对较高,你会遇到一些困惑,比如: 为什么要学习Linux,学成之后我们可以在哪些领域大显身手…...
符尧:别卷大模型训练了,来卷数据吧!【干货十足】
大家好,我是HxShine。 今天分享一篇符尧大佬的一篇数据工程(Data Engineering)的文章,解释了speed of grokking指标是什么,分析了数据工程(data engineering)包括mix ratio(数据混合…...
2023年中国半导体检测仪器设备销售收入、产值及市场规模分析[图]
半导体测试设备是一种用于电子与通信技术领域的电子测量仪器。随着技术发展,半导体芯片晶体管密度越来越高,相关产品复杂度及集成度呈现指数级增长,这对于芯片设计及开发而言是前所未有的挑战,随着芯片开发周期的缩短,…...
诊断DLL——Visual Studio安装与dll使用
文章目录 Visual Studio安装一、DLL简介二、使用步骤1.新建VS DLL工程2.生成dll文件3.自定义函数然后新建一个function.h文件,声明这个函数。4.新建VS C++ console工程,动态引用DLL编写代码,调用dll三、extern "C" __declspec(dllexport)总结Visual Studio安装 官…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
内窥镜检查中基于提示的息肉分割|文献速递-深度学习医疗AI最新文献
Title 题目 Prompt-based polyp segmentation during endoscopy 内窥镜检查中基于提示的息肉分割 01 文献速递介绍 以下是对这段英文内容的中文翻译: ### 胃肠道癌症的发病率呈上升趋势,且有年轻化倾向(Bray等人,2018&#x…...
