前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Swoole v4.7 版本预览之支持 c-ares

Swoole v4.7 版本预览之支持 c-ares

作者头像
沈唁
发布2021-07-23 12:21:26
6840
发布2021-07-23 12:21:26
举报
文章被收录于专栏:沈唁志沈唁志

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

函数原型:

代码语言:javascript
复制
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

代码语言:javascript
复制
Swoole\Coroutine\System::dnsLookup(string $domain, float $timeout = 5, int $type = AF_INET): string|false

示例代码

  • IPv6
代码语言:javascript
复制
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 日志

代码语言:javascript
复制
use Swoole\Coroutine\System;
use function Swoole\Coroutine\run;

run(function () {
    $ip = System::gethostbyname("www.taobao.com", AF_INET, 0.5);
    echo $ip;
});
代码语言:javascript
复制
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
代码语言:javascript
复制
好文和朋友一起看~
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 沈唁志 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • gethostbyname
  • dnsLookup
    • 示例代码
    • strace 日志
    相关产品与服务
    云数据库 MySQL
    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档