DNS解析导致java api获取本机IP超时
背景
因为业务需求导致服务迁移,迁移过程中发现新机房同样接口的系统响应时间变的异常缓慢(普通有100-200ms的时延)。整个迁移过程中代码发布包完全拷贝,所以当时就定位为系统原因进行排查。
整个排查过程通过在代码中关键路径切入耗时监控,从而定位具体耗时部分的代码,缩小排查范围。
排查过程
定位的代码逻辑因为保密原因省略了很多跟问题无关的代码,仅列出核心的代码。
- try/catch过程中的核心代码没有任何耗时的逻辑。
- finally的处理过程中增加了getLocalIP()方法获取本地ip地址。
- 经过添加日志监控耗时怀疑getLocalIP()方法比较耗时。
public RecomResult recommend(RequestId reqId, RecomParam condition) { lock.readLock().lock(); long timeStart = System.currentTimeMillis(); try { // 省略核心代码 return result; } catch (Throwable t) { // 省略核心代码 } finally { mapTag.put("ip", engineContext.getLocalIP()); lock.readLock().unlock(); } }
getLocalIP()方法的实现逻辑就是调用java api获取本机ip地址
- 网上查询类似文章InetAddress.getLocalHost() 执行很慢开始怀疑DNS解析问题。
- 通过for循环执行dig命令确认dns解析时好时坏耗时在100-200ms不等。
- 验证猜测确认是DNS解析问题,并开始通过本地hosts或缓存本地ip地址减少解析。。
public String getLocalIP() { try { if (null == localIp) { localIp = InetAddress.getLocalHost().getHostAddress(); } } catch (UnknownHostException e1) { LOG.error("get ip failed, e is {}", e1); } return localIp; }
解决方案
解决方案本身分为代码本身优化和DNS解析优化。
- DNS层优化主要是服务器DNS解析增加本地缓存,牺牲DNS解析的时效性。
- 代码层面优化主要获取本地ip地址后缓存只需要进行一次host解析即可。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java总结 - clone总结
clone简介 即复制一个对象出来,他存在Object类中,是一个本地方法,并且修饰符是protected,所以他是可以让其子类实现自己的clone方法的protected native Object clone() throws CloneNotSupportedException; 与new的区别 new是从头创建一个对象的过程,为新对象分配内存,首先看new的对象中的属性类型需要多大空间,根据空间创建内存区域,分配完成后进行初始化值,然后返回对象供外部引用 clone也是为对象分配内存,首先看new的对象中的属性类型需要多大空间,根据空间创建内存区域,不同的是他的初始值是从被clone对象中读取的,之后返回对象供外部引用 什么情况下用clone 比如对象A已经是满足我们的要求了,那么我们希望有一个实例的属性值是跟A是一致的,那么我们就有
- 下一篇
python代码如何利用阿里云发送邮件
此代码是磁盘使用率超过90%就会发送邮件 #!/usr/bin/env python #coding:utf-8 import socket import re import os import smtplib import datetime import commands,time from email.mime.text import MIMEText from email.utils import formataddr # 硬盘使用率报警阀值 m=socket.gethostname() s="磁盘使用率超过:" b="测试服务器" d="%" hd_usage_rate_threshold = 90 def check_hd_use(): cmd_get_hd_use = '/bin/df' try: fp = os.popen(cmd_get_hd_use) except: ErrorInfo = r'get_hd_use_error' print ErrorInfo return ErrorInfo ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群