2018-12-19-奇葩的问题呀整的头都大了

现网中存在两台服务器(存放后台系统web的,一台192.168.1.3-webA,一台是192.168.1.4-webB),但是它们在连接数据库(192.168.1.2)的时候出现连接等待时长不一样,webA等待时间在1S内,而另一台webB却有10S

手动编写的数据库连接时间测试demo:

$a=time();

$link=mysqli_connect("192.168.1.2","root","12345678");

if(!$link) echo "FAILD!连接错误,用户名密码不对";

$b=time()-$a;

echo $b;

验证时长:

时间较长的webB:

长时间的服务器

时间较短的webA:

短时间的服务器

查找资料得到结果,默认安装的MYSQL开启了DNS的反向解析。域名解析也可以导致网络程序慢,MySQL在处理新的线程连接请求时,会尝试进行DNS解析,如果在host cache和Hosts里找不到,处理起来就会很慢,一般来说数据库服务器为安全起见是不能连接到外网的,所以dns解析也没办法完成,这就可以解释为什么这么慢了,可以在mysql的配置文件中, 禁用该反向解析功能。

当远程访问mysql时,mysql会解析域名,会导致访问速度很慢,加上下面这个配置可解决此问题MY.INI(WINDOWS系统下)或MY.CNF(UNIX或LINUX系统下)文件的[mysqld]下加入skip-name-resolve这一句。

配置如下:

[mysqld]

skip-name-resolve    # 禁止mysql做域名解析

但是,这样会引起一个问题:连接mysql时,不能使用 localhost连接了,而是要使用IP地址的;以后在使用grant对用户进行授权时只能使用IP格式,而不能使用主机名称了

但是在此两台服务器中的数据库连接,就是使用ip地址的.应该不会存在域名解析这个问题,如果存在的话webA也会出现连接数据库慢的现象。

官方解释如下:

MySQL如何使用DNS

当一个新线程连接到mysqld时,mysqld将生成一个新线程来处理请求。这个线程将首先检查主机名是否在主机名缓存中。如果没有,线程将调用gethostbyaddr_r()和gethostbyname_r()来解析主机名。

如果操作系统不支持上述线程安全调用,则线程将锁定互斥对象,并调用gethostbyaddr()和gethostbyname()。注意,在这种情况下,只有第一个线程准备好了,其他线程才能解析主机名缓存中没有的其他主机名

可以通过使用 skip-name-resolve启动mysqld来禁用DNS主机查找。但是,在这种情况下,只能在MySQL特权表中使用IP地址而不是域名

如果有非常慢的DNS和许多主机,可以通过禁用 skip-name-resolve的DNS查找或通过增加HOST_CACHE_SIZE定义(默认值:128)并重新编译mysqld获得更高性能。

可以使用skip-host-cache禁用主机名缓存。可以使用FLUSH HOSTS或mysqladmin flush-host清除主机名缓存。

如果不想通过TCP/IP进行连接,可以通过使用–跳过网络启动mysqld来实现这一点。


最终的临时解决方法:

通过修改系统hosts文件也可以实现,举例来说,我想解决192.168.1.4远程连接MySQL服务器缓慢的问题,只需要在MySQL库所在服务器的hosts文件中新增一条记录如下:

192.168.1.4  webB

保存退出,再次远程连接该MySQL库,同样很快。之所以说绝,是因为这样设置,你添加记录的192.168.1.4远程连接速度变快了,其他主机连接速度跟之前一样慢。

该方法同样可以解决ssh远程连接某主机响应很慢的问题,原理一样。

你可能感兴趣的:(2018-12-19-奇葩的问题呀整的头都大了)