Ruby 请教 ruby-rb gem 连接 redis 超时问题

uestc_bird · 发布于 2017年04月12日 · 最后由 uestc_bird 回复于 2017年04月14日 · 353 次阅读
96

平台: mac OSX: 10.12.4 (16E195) rails: 3.2.22 redis-rb: 2.2.2

连接方式1: Redis.new({:url => "redis://:cache.test.cn:6379/7"}) 这种情况下,每次都能连接成功,但是只能连接到db0,后面的/7是无效的(gem的bug)

连接方式2:Redis.new({:host=>"cache.test.cn", :port=>6379}) 这种情况下,连接经常会出现超时的情况,cache.test.cn这个host已经写在/etc/hosts中,nslookup,ping都正常,速度很快 源码中使用TCPSocket.new来连接,其中试验的TCPSocket.gethostbyname(),这个函数非常缓慢,经常需要5秒以上才能返回结果

请问谁知道这种情况的原因,怎样解决? 附: 用mac的同学能否试验一下这个函数,步骤:

  1. 打开ruby解释器的交互窗口(irb);
  2. 输入 require 'socket';
  3. 输入:Socket.getaddrinfo("www.baidu.com",nil);
  4. 输入:Socket.getaddrinfo("xxxxxxxxx",nil), 其中xxxxxxx是在etc/hosts文件中的一条本地域名; 比较一下3、4两步骤的速度,第4步是不是明显要比第3步慢? 如果有实验结果,麻烦回复一下,顺便带上macos版本,ruby版本,以及ruby的安装方式(源码编译?rvm?rben?等)
共收到 6 条回复
370

TCPSocket.gethostbyname 5秒可能是 DNS 问题。

370

你是不是装了什么代理工具,被自动修改或劫持了 DNS 部分?你试试直接 IP 是不是很快,如果是,那么可以确定是 DNS 问题。

96
370kgen 回复

直接写IP确实很快,确实是dns的问题,但是明知道这个问题但是无从下手啊,需要被解析的域名我都写在/etc/hosts里面了,而且查看了域名解析的过程,都没问题啊

96

TCPSocket.gethostbyname用的是不是OSX本身的底层函数库的gethostbyname?感觉应该是的 还有,我确实安装了代理,云梯

370

云梯因为是 VPN,所以关闭的时候,对 DNS 和系统网络是完全零影响的。你测试下,在打开和关闭云梯的情况下,超时问题有没有区别?

理论上 macOS 是优先读 hosts,然后才发 DNS 请求的。但 TCPSocket.gethostbyname 是不是调 macOS 的 gethostbyname 要看C源码了,有可能是它自己实现的。之前在调试某些浏览器的时候,遇到某些浏览器 DNS 不走 macOS 的 fallback 流程。

96
370kgen 回复

是的,这个思路很对,我昨天就是按照这样做的,我自己用C语言写了gethostbyname的测试用例,这个用例调用的是mac中的libc库函数,发现解析速度很快,看了下libc库中的gethostbyname的说明,确实是优先从hosts文件中解析域名。我在看一下ruby的源码吧,看看它是怎样实现域名解析的,我估计也是ruby自己实现的

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册