最近,在维护 KProxy(一个代理服务,Web 版的 charles) 时,遇到一个故障问题:一个请求的响应早已结束,但是在一段时间后却触发了 request timeout。
近期在做 Node.js 基础监控中 Active Handles/Requests 信息的按需采集功能。在 Active Handles 中包含了 timer 的信息采集,这里的 timer 就是指的通过 setTimeout
/setInterval
设置的定时器,以及 Nodejs 内置 JavaScript 模块中创建的定时器等。而 Nodejs 在 timer 实现上与其他异步资源的代码结构不太一致,做了特定的优化。
近期在做 Node.js 基础监控中 Active Handles/Requests 信息的按需采集功能。在 Active Handles 中包含了 timer 的信息采集,这里的 timer 就是指的通过 setTimeout
/setInterval
设置的定时器,以及 Nodejs 内置 JavaScript 模块中创建的定时器等。而 Nodejs 在 timer 实现上与其他异步资源的代码结构不太一致,做了特定的优化。
本文记录了使用 Node gRPC(static codegen 方式)时,遇到的一个“奇怪”的坑。虽然问题本身并不常见,但顺着问题排查发现其中涉及到了一些有意思的点。去沿着问题追根究底、增长经验是一种不错的学习方式。所以我把这次排查的过程以及涉及到的点记录了下来。
两周前(202.02.17),vite2.0 发布了,作为使用了浏览器原生 ESM 为下一代前端工具,vite 2.0 相较于 1.0 更加成熟。在此之前笔者就开始关注这类「新型」的前端工具。这次趁着 vite 2.0 发布,也成功将一个基于 vue-cli(-service) + vue2 的已有项目进行了迁移。
之前在使用一些开源项目时,经常会看到在控制台输出项目大大的 LOGO。例如:
添加这种大号「艺术字」可以达到「品牌露出」的效果,当然,也是程序员特有「情趣」的体现。 😄
但它们的实现方式无外乎把编排好的 Logo 通过 console.log
输出。这种方式问题在于它几乎没有任何复用能力,而且一些需要转义的情况还会导致字符串的可维护性极差。因此,我花了一个周末的时候,实现了一个易用的、可复用的控制台「艺术字」lib。这样,下次有新的需求,只需要把正常的文本传给它,它就可以帮你自动编排与打印。
近期在做一个 DNS 服务器切换升级的演练中发现,我们在 NodeJS 中使用的 axios 以及默认的 dns.lookup
方法存在一些问题,会导致切换过程中的响应耗时从 ~80ms 上升至 ~3min,最终 nginx 层出现大量 502。
具体背景与分析参见《node中请求超时的一些坑》 ➡️
总结来说,NodeJS DNS 这块的“坑”可能有↓↓
dns.lookup
来进行 DNS 查询,其底层调用了系统函数 getaddrinfo
。getaddrinfo
会同步阻塞,所以使用线程池来模拟异步,默认数量为 4。因此如果 DNS 查询时间过长且并发请求多,则会导致整体事件循环(Event Loop)出现延迟(阻塞)。Request#setTimeout
方法,该方法的超时时间不包括 DNS 查询。因此如果你将超时设为 3s,但是 DNS 查询由于 DNS 服务器未响应挂起了 5s(甚至更久),这种情况下你的请求是不会被超时释放的。随着请求的越来越多问题会被累积,造成雪崩。getaddrinfo
使用 resolv.conf 中 nameserver 配置作为本地 DNS 服务器,可以配置多个作为主从。但其并没有完备的探活等自动切换机制。主下掉后,仍然会从第一个开始尝试,超时后切换下一个。即使使用 Round Robin,理论上仍会有 1/N 的请求第一个命中超时节点(N 为 nameserver 的数量)。针对这种问题,在不去修改 NodeJS 底层(主要是 C/C++ 层)源码的情况下,在 JS 层引入 DNS 的缓存是一个轻量级的方案,会一定程度上规避这个问题(但也并不能完美解决)。因此,计划引入 lookup-dns-cache 作为优化方案。但更换 DNS 查询与引入缓存的影响面较广,线上引入前需要慎重确认以下问题:
Update your browser to view this website correctly. Update my browser now