Swoole v4.7 版本预览之支持 c-ares
source link: https://segmentfault.com/a/1190000040267883
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
c-ares 是什么?
c-ares 是一个异步 DNS 解析库。 它适用于需要在不阻塞的情况下执行 DNS 查询或需要并行执行多个 DNS 查询的应用程序。
默认不开启,如需开启,需要在编译 Swoole 时增加 --enable-cares
参数
gethostbyname
在之前的版本中 Coroutine\System::gethostbyname
是基于同步的线程池模拟实现,底层自动进行协程调度,
依赖操作系统和 AIO 线程池,导致并发能力较弱,而启用 c-ares 之后会变成纯异步 IO 的。
启用 c-ares 之后,所有的网络客户端在解析域名时都会使用 c-ares ,包括 Redis、MySQL、HttpClient ,以及 PHP 的 Hook stream、sockets 之类
dnsLookup
函数原型:
Swoole\Coroutine\System::dnsLookup(string $domain, float $timeout = 5): string|false
与 Coroutine\System::gethostbyname
不同,Coroutine\System::dnsLookup
是基于 Co\Socket UDP 客户端自行实现的 DNS 协程客户端,
底层是异步 IO,而不是使用 libc 提供的 gethostbyname
函数。在开启 c-ares 之后也会被替换成 c-ares 实现。
此函数在 Swoole 版本 >= v4.4.3
时可用,底层会读取 /etc/resolve.conf
获取 DNS 服务器地址,之前版本中仅支持 AF_INET(IPv4)
域名解析,此版本中对于 IPv6 也增加了支持
对于 Coroutine\System::dnsLookup
增加了第三个参数,用于选择 IPv4 (AF_INET
) 还是 IPv6 (AF_INET6
),默认为 IPv4
Swoole\Coroutine\System::dnsLookup(string $domain, float $timeout = 5, int $type = AF_INET): string|false
use Swoole\Coroutine\System;
use function Swoole\Coroutine\run;
run(function () {
var_dump(System::dnsLookup('www.taobao.com', 3, AF_INET6));
});
strace 日志
启用 c-ares 之后会变成纯异步 IO,以下为 strace 日志
use Swoole\Coroutine\System;
use function Swoole\Coroutine\run;
run(function () {
$ip = System::gethostbyname("www.taobao.com", AF_INET, 0.5);
echo $ip;
});
epoll_create(512) = 3
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=658303392}) = 0
mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4173b8c000
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=658417744}) = 0
open("/etc/resolv.conf", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=89, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f41832b9000
read(4, "; generated by /usr/sbin/dhclien"..., 4096) = 89
read(4, "", 4096) = 0
close(4) = 0
munmap(0x7f41832b9000, 4096) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f41832b9000
read(4, "t\205\3006 \273`\271\375\377\273\376\261a\246VP\304Y-\4[\20619@\370\23N\1\223>"..., 4096) = 4096
close(4) = 0
munmap(0x7f41832b9000, 4096) = 0
open("/etc/hosts", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=242, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f41832b9000
read(4, "127.0.0.1 VM-32-17-centos VM-32-"..., 4096) = 242
read(4, "", 4096) = 0
close(4) = 0
munmap(0x7f41832b9000, 4096) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=659074426}) = 0
socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
fcntl(4, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("183.60.82.98")}, 16) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 4, {EPOLLIN, {u32=37374768, u64=37374768}}) = 0
sendto(4, "f\330\1\0\0\1\0\0\0\0\0\0\3www\5baidu\3com\0\0\1\0\1", 31, MSG_NOSIGNAL, NULL, 0) = 31
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=659365294}) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=659391969}) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=659414437}) = 0
epoll_wait(3, [{EPOLLIN, {u32=37374768, u64=37374768}}], 4096, 500) = 1
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=660754983}) = 0
recvfrom(4, "f\330\201\200\0\1\0\3\0\0\0\0\3www\5baidu\3com\0\0\1\0\1\300"..., 4097, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("183.60.82.98")}, [16]) = 90
epoll_ctl(3, EPOLL_CTL_DEL, 4, NULL) = 0
close(4) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2244208, tv_nsec=660917518}) = 0
write(1, "110.242.68.4", 12110.242.68.4) = 12
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK