【发布时间】:2018-08-20 19:21:18
【问题描述】:
我刚刚解决了我们基础架构中的一个延迟问题,该问题被触发,因为这里的代码 sn-p 在每次运行代码时都会触发对 getaddrinfo 的调用:
sock = UDPSocket.open
sock.send("#{key}|#{value}", 0,
GRAPHITE_SERVER,
STATSD_PORT)
sock.close
因为我们使用statsd and graphite 进行大量事件和统计数据监控,所以我们在每次 API 调用时有效地触发了无数次调用getaddrinfo,并且每分钟可能会触发数万次。
我修改了这段代码以使用我们的石墨服务器的内部 IP 地址,而不是 DNS 名称,并且能够解决延迟问题(可能是因为内部 AWS VPC DNS 服务器没有配备处理如此高的容量请求)。
现在我的问题已经解决,我很想知道为什么 Ruby 中的 UDP 实现不使用缓存的 IP 地址值(大概基于域名条目的 TTL)。 Here is the relevant line 和完整的函数,你可以在最后看到对rsock_addrinfo 的调用:
static VALUE
udp_send(int argc, VALUE *argv, VALUE sock)
{
VALUE flags, host, port;
struct udp_send_arg arg;
VALUE ret;
if (argc == 2 || argc == 3) {
return rsock_bsock_send(argc, argv, sock);
}
rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port);
StringValue(arg.sarg.mesg);
GetOpenFile(sock, arg.fptr);
arg.sarg.fd = arg.fptr->fd;
arg.sarg.flags = NUM2INT(flags);
arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0);
ret = rb_ensure(udp_send_internal, (VALUE)&arg,
rsock_freeaddrinfo, (VALUE)arg.res);
if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port);
return ret;
}
我认为这个决定是故意的,并且很想了解更多原因。
【问题讨论】:
-
4 年前有类似问题的其他人:bugs.ruby-lang.org/issues/9925
标签: ruby dns udp getaddrinfo