六一快乐
节日快乐
迎来了6.1儿童节,祝大朋友和小朋友节日快乐~!陪娃去市里上了两节课,一天过去了,想想不能断更,要加油更新出一篇。
事件背景
我们APP用户有时候会反馈不能用,运营同学会根据运维同学的要求让用户进行一些操作,比如ping了、打开某个服务接口地址、查看一下出口IP地址,方便运维这边进行排查。用户是PC的情况下,进行下面这样的操作:


用户是移动端的话动手能力强的装一个Best NetTools,进行的操作如下:

遇到的问题
移动端Best NetTools工具经常有错误,移动网络默认走IPv6协议,但是这种软件获取开启IPv4和IPv6接入的域名时候经常异常,异常如下图:

现在服务的接口和静态资源CDN的接入都支持IPv6,有时候是服务接口访问异常,有时候是CDN静态资源访问异常,目前网易获取IP的工具只支持获取IPv4的地址,无法获取IPv6的,有道这边想获取两个IP的话需要访问两个地址才可以,徒增了用户操作的复杂度。
获取用户的IP好处理,DNS这边没有想到获取的方式是怎么的,需要研究一下。
浏览器方案
如果能在浏览器里面发起一些ping请求的话,不管是移动端还是PC端都会非常方便。查询github上面的一些js项目,发现确实有一个适合ping.js ,是一个很多年前的项目了,访问域名下面的favicon.ico来判断连通性和请求的时延。
直接上代码,顺便再获取一下用户的v4和v6地址
<script src="https://*****.js" type="text/javascript"></script>
<h3>网络联通性测试</h3>
<ul>
<li>dict.youdao.com <span id="ping-dict"></span></li>
<li>shared.youdao.com <span id="ping-shared"></span></li>
<li>shared.ydstatic.com <span id="ping-shared-ydstatic"></span></li>
</ul>
<h3>获取IPv4信息</h3>
<ul id="ip-info"></ul>
<h3>获取IPv6信息</h3>
<ul id="ip-info-v6"></ul>
<script>
function ping(url, elementId) {
var settings = {
timeout: 2000,
logError: true
};
new Ping(settings).ping(url, function (err, data) {
if (err) {
console.error('Error loading resource');
data = data + ' ' + err;
}
document.getElementById(elementId).innerHTML = data;
});
}
addEventListener('contextmenu', function (e) { e.preventDefault(); });
addEventListener('selectstart', function (e) { e.preventDefault(); });
addEventListener('dragstart', function (e) { e.preventDefault(); });
addEventListener('mouseup', function () { document.selection.empty(); });
ping('https://dict.youdao.com', 'ping-dict');
ping('https://shared.youdao.com/images', 'ping-shared');
ping('https://shared.ydstatic.com/images', 'ping-shared-ydstatic');
function getIPAddress() {
var url = 'https://****';
fetch(url)
.then(response => response.json())
.then(data => {
const ipInfo = `
<li>Country: ${data.data.country}</li>
<li>City: ${data.data.city}</li>
<li>IP Address: ${data.data.ip}</li>
<li>Operator: ${data.data.operator}</li>
<li>Province: ${data.data.province}</li>
`;
document.getElementById('ip-info').innerHTML = ipInfo;
})
.catch(error => {
console.error('Error fetching IP information. Please try again.');
});
}
getIPAddress();
function getIPv6Address() {
var url = 'https://****';
fetch(url)
.then(response => response.json())
.then(data => {
const ipInfo = `
<li>Country: ${data.data.country}</li>
<li>City: ${data.data.city}</li>
<li>IP Address: ${data.data.ip}</li>
<li>Operator: ${data.data.operator}</li>
<li>Province: ${data.data.province}</li>
`;
document.getElementById('ip-info-v6').innerHTML = ipInfo;
})
.catch(error => {
console.error('Error fetching IP information. Please try again.');
});
}
getIPv6Address();
</script>
结果如下图

DNS实现原理
获取自己本地用的DNS这边有一个小技巧,
o-o.myaddr.l.google.com
是一个特殊的域名,该域名的 DNS 记录不是固定的。负责解析该域名的谷歌域名服务器将请求者的公网 IP 地址放入 TXT 记录中,请求者可以向谷歌域名服务器查询该记录,因而获取自己的 IP 地址。(注意,这里请求的是TXT 记录,而不是常见的 A 记录或者 AAAA 记录)
我本地设置了dns是223.5.5.5的阿里公共DNS,请求Google权威DNS的出口就是113.13.102.6

前面”您的DNS地址信息: 221.179.155.21 北京市北京市移动“实现的原理其实是网页端随机请求一个不存在的域名,根域名所在的权威服务器日志中会记录来源的请求信息,例如IP地址。比如请求youdao的123456788djfkldasjflksd.youdao.com

可以看到出口的DNS地址是220.181.96.103,自己写一个后端服务来实现查询+返回结果的简单逻辑就可以了。
写在最后
在结合工作实际情况写一些小工具的同时熟悉一些开源工具的原理和使用技巧,努力提高自己的代码能力,日积月累。