3
头图

What is c-ares?

c-ares is an asynchronous DNS resolution library. It is suitable for applications that need to execute DNS queries without blocking or need to execute multiple DNS queries in parallel.

It is not enabled by default. If you need to enable it, you need to add the --enable-cares parameter when compiling Swoole

gethostbyname

In the previous version, Coroutine\System::gethostbyname is based on the synchronization thread pool simulation implementation, the bottom layer automatically performs coroutine scheduling,

Relying on the operating system and AIO thread pool, resulting in weak concurrency, and after enabling c-ares, it will become purely asynchronous IO.

After enabling c-ares, all network clients will use c-ares when resolving domain names, including Redis, MySQL, HttpClient, and PHP hook stream, sockets, etc.

dnsLookup

Function prototype:

Swoole\Coroutine\System::dnsLookup(string $domain, float $timeout = 5): string|false

Different from Coroutine\System::gethostbyname Coroutine\System::dnsLookup is a DNS coroutine client based on the Co\Socket UDP client.

The bottom layer is asynchronous IO, instead of using the gethostbyname function provided by libc. After opening c-ares, it will be replaced with c-ares implementation.

This function is available when Swoole version >= v4.4.3 , the bottom layer will read /etc/resolve.conf obtain the DNS server address. In the previous version, only AF_INET(IPv4) domain name resolution was supported. This version also adds support for IPv6

For Coroutine\System::dnsLookup a third parameter is added to select IPv4 ( AF_INET ) or IPv6 ( AF_INET6 ). The default is IPv4

Swoole\Coroutine\System::dnsLookup(string $domain, float $timeout = 5, int $type = AF_INET): string|false

Sample code

  • IPv6
use Swoole\Coroutine\System;
use function Swoole\Coroutine\run;

run(function () {
    var_dump(System::dnsLookup('www.taobao.com', 3, AF_INET6));
});

strace log

After enabling c-ares, it will become pure asynchronous IO. The following is the strace log

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


沈唁
1.9k 声望1.2k 粉丝