自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(493)
  • 资源 (2)
  • 收藏
  • 关注

原创 推广 Node.js 小册子和技术星球

《深入剖析 Node.js 底层原理》掘金小册子Node.js 技术星球

2023-10-10 01:27:28 162 1

原创 聊聊 Libuv 最近引入的 io_uring

io_uring 是 Linux 下高性能的异步 IO 框架,网上很多相关资料,我之前也初步分析了一下它的实现,有兴趣的可以查看 https://zhuanlan.zhihu.com/p/387620810。Libuv 中最近加入了对 io_uring 的支持,那么为什么要把它引入 Libuv 呢?

2023-10-19 22:37:37 367

原创 Node.js 是如何处理请求的

在服务器软件中,如何处理请求是非常核心的问题。不管是底层架构的设计、IO 模型的选择,还是上层的处理都会影响一个服务器的性能,本文介绍 Node.js 在这方面的内容。

2023-09-29 22:24:58 2262

原创 有趣的 Async hooks 模块

在 Node.js 中,Async hooks 是一个非常有意思且强大的模块(虽然性能上存在一些问题),在 APM 中,我们可以借助这个模块做很多事情。本文介绍两个有趣的用法。

2023-07-14 22:05:57 384

原创 Node.js HTTP 模块的内存泄露问题

这个例子虽然看起来有点不常见,用法也很怪异,但是从侧面说明了虽然 JS 自带 GC,但是因为逻辑 / 引用关系复杂,还是很容易出现内存泄露问题,所以写代码时还是需要注意,具体的 issue 可以参考 https://github.com/nodejs/node/issues/48604。

2023-06-30 22:54:19 641 1

原创 如何计算 Node.js GC 负载

在 Node.js 中,我们关注的比较的是 CPU 负载,但是在有 GC 的语言中,GC 负载也是需要关注的一个指标,因为 GC 过高会影响我们应用的性能。本文介绍关于 GC 负载的一些内容。

2023-06-20 01:07:50 324

原创 穿针引线之 AsyncLocalStorage

AsyncLocalStorage 有很多用法和用处,我们在 Node.js APM 中也大量用到该技术,通过 AsyncLocalStorage,我们可以无侵入地实现对 Node.js 应用的内部进行观测,时间关系,本文简单地介绍了 AsyncLocalStorage 的使用和原理,有兴趣的同学可以自行探索。

2023-06-03 18:36:32 449

原创 如何实现一个 APM watchdog

这就是 APM watchdog 的实现原理,核心思想是利用子线程和 env->RequestInterrupt 机制,保证我们对目的线程进行相对实时的监控(取决于设置的轮询时间),并在发现问题采集相关信息来协助我们排查问题,利用这个思路,我们可以实现不同类型的 watchdog 来解决不同的问题,比如 CPU watchdog 可以在 JS 死循环时采集 CPU Profile 信息帮助我们找到有问题的代码,本文就分享到这里,最后贴上目前的实现。接着看看实现,首先看 JS 层的实现。

2023-03-25 01:33:20 295 1

原创 Node.js C++ 层的任务管理

2022-12-02 23:13:05 697

原创 如何写一个 JS 运行时

2022-10-06 01:29:18 448

原创 如何实现 JS 运行时的 Inspector 能力

2022-10-03 03:21:11 710

原创 聊聊 JS 断点的实现

2022-09-29 21:27:53 535

原创 利用多线程和 C++ 实现一个简单的 HTTP 服务器

2022-09-07 23:43:25 1108

原创 V8 GC 的实现

V8 GC

2022-08-18 00:51:19 459

原创 如何追踪 JS 对象是否被 GC

如何追踪 JS 对象是否被 GC

2022-08-08 02:00:47 426 2

原创 Node.js 子线程 crash 问题的排查

Node.js 子线程

2022-06-22 23:21:51 365

原创 如何把 Node.js 嵌入自己的项目中

如何把 Node.js 嵌入自己的项目中

2022-06-04 00:05:44 682

原创 如何优雅地 hack 用户的代码

前言:做基础技术的时候,会经常碰到一个问题就是如何让自己提供的代码对用户少侵入,无感。比如我提供了一个 SDK 收集 Node.js 进程的 HTTP 请求耗时,最简单的方式就是给用户提供一个 request 方法,然后让用户统一调用,这样我就可以在 request 里拿到这些数据。但是这种方式很多时候并不方便,这时候我们就需要去 hack Node.js 的 HTTP 模块或者给 Node.js 提 PR。在操作系统层面,有提供很多技术解决这种问题,比如 ebpf、uprobe、kprobe。但是应用层无

2022-05-24 01:19:52 399

原创 V8 global.gc() 的实现

前言:在 Node.js 中我们有时候会使用 global.gc() 主动触发 gc 来测试一些代码,因为我们知道 V8 gc 的执行时机是不定的。但是可能很少同学知道 global.gc() 的实现,本文介绍一些在 V8 中关于这部分的实现。了解 global.gc() 实现之前,首先看一下 V8 的 Extension 机制。Extension 机制用于拓展 V8 的能力。在 V8 初始化的过程中,V8::Initialize 会初始化 Extension 机制,具体在 Bootstrapper::

2022-05-23 23:15:35 733

原创 V8 CPU Profiler 的实现

前言:CPU Profiler 是应用性能诊断和优化的利器,本文介绍 V8 中关于这部分的实现,细节比较多也比较复杂,大致分析一下原理,代码来自 V8 10.2。开始分析前,先来看一下对象的关系图(从左往右看),这个对后面的分析比较重要,因为他们的关系错综复杂。下面开始分析。入口对象为 CpuProfiler。CpuProfiler 负责管理多个 CpuProfile,而我们进行一次 CPU Profile 时对应的就是一个 CpuProfile 对象。首先看一下 CpuProfiler 的构造函数。

2022-05-06 22:51:07 732

原创 V8 Heap Profiler 的实现

前言:V8 Heap Profiler 用于收集哪些代码分析了多少内存的信息。本文介绍 V8 中关于这部分的实现,代码来自 V8 10.2。入口函数是 StartSamplingHeapProfiler。 bool StartSamplingHeapProfiler(uint64_t sample_interval, int stack_depth, v8::HeapProfiler::SamplingFlags);主要的参数是 sample_interval。bool HeapProfile

2022-05-06 22:49:33 417

原创 利用 V8 的 trace API 追踪代码

V8 和 Node.js 提供了 trace_event 机制,但是因为稳定性原因,Node.js 目前没有支持用户自定义 trace event 能力,所以写了一个 addon 支持该能力(npm i v8_trace_event)。更多信息可以参考。https://github.com/nodejs/node/pull/42462https://nodejs.org/dist/latest-v18.x/docs/api/tracing.htmlhttps://zhuanlan.zhihu.com

2022-05-04 05:24:25 776

原创 V8 堆外内存 ArrayBuffer 垃圾回收的实现

前言:V8 除了我们经常讲到的新生代和老生代的常规堆内存外,还有另一种堆内存,就是堆外内存。堆外内存本质上也是堆内存,只不过不是由 V8 进行分配,而是由 V8 的调用方分配,比如 Node.js,但是是由 V8 负责 GC 的。本文介绍堆外内存的一种类型 ArrayBuffer 的 GC 实现。1 创建 ArrayBufferArrayBuffer 的创建有很多种方式,比如在 JS 层创建 Uint8Array 或者 ArrayBuffer(对应实现 builtins-arraybuffer.cc),

2022-04-29 04:30:00 820

原创 V8 新生代垃圾回收的实现

前言:因为最近在做一些 gc track 的事情,所以打算了解一下 V8 GC 的实现。介绍 V8 GC 的文章网上已经有很多,就不打算再重复介绍。本文主要介绍一下新生代 GC 的实现,代码参考 V8 10.2,因为 GC 的实现非常复杂,只能介绍一些大致的实现,读者需要对 V8 GC 有一定的了解,比如新生代是分为 from 和 to 两个 space,然后在 GC 时是如何处理的。说到 GC 首先需要介绍内存,具体来说,是堆内存,V8 把内存分为新生代和老生代,其中老生代又分为很多种类型,不过本文只关

2022-04-29 02:36:49 321

原创 通过代码缓存加速 Node.js 的启动

前言:之前的文章介绍了通过快照的方式加速 Node.js 的启动,除了快照,V8 还提供了另一种技术加速代码的执行,那就是代码缓存。通过 V8 第一次执行 JS 的时候,V8 需要即时进行解析和编译 JS代码,这个是需要一定时间的,代码缓存可以把这个过程的一些信息保存下来,下次执行的时候,通过这个缓存的信息就可以加速 JS 代码的执行。本文介绍在 Node.js 里如何利用代码缓存技术加速 Node.js 的启动。首先看一下 Node.js 的编译配置。'actions': [ { 'act

2022-04-02 01:54:44 1507

原创 通过快照加速 Node.js 的启动

前言:随着 Node.js 的越来越强大,代码量也变得越来越多,不可避免地拖慢了 Node.js 的启动速度,针对这个问题,Node.js 社区通过 V8 的 snapshot 技术对 Node.js 的启动做了优化,在 github 有很多关于此的 issue 讨论,大家有兴趣也可以去看一下。通过快照加速启动是一个非常复杂的过程,这需要对 V8 有深入的理解。本文介绍一下如何在 Node.js 中使用快照加速 Node.js 的启动。以 v16.13.1 为例,社区一直在优化这里面的速度,不同的版本的速度

2022-04-01 04:10:12 551

原创 聊聊最近给 Node.js 提交的几个PR

前言:最近因为工作中碰到的一些问题,希望给 Node.js 提交一些代码来解决我碰到的问题,一共提交了 4 个 PR,目前一个已经在 17.8.0 中发布,一个刚合到主干,一个等 reviewer 回复,一个等 31 号 tsc 开会讨论。总的来说,提交的代码并不复杂,但是的确解决了我的问题,同时我觉得也是开发者需要的一些功能。下面介绍一下这几个 PR 做的事情。1 通过 perf_hooks 收集 HTTP 模块的耗时了解 HTTP Server 处理一个请求的耗时和发送一个 HTTP Request

2022-03-30 02:26:05 230

原创 Node.js 的 trace events 架构

前言: trace 系统用于收集内核的数据,本文介绍在 Node.js 中 trace 系统的架构和实现,因为 Node.js 的 trace 系统是基于 V8 的,所以也会介绍 V8 部分。Node.js 中 trace 数据通过两种方式产生,第一种方式是在 JS 层通过 V8 提供的 trace C++ API,第二种方式是通过 Node.js C++ 层。下面首先看一下第一种。// binding.trace(phase, category, name, id, data) SimpleIns

2022-03-26 16:18:06 1410

原创 Node.js 的 perf_hooks

前言:perf_hooks 是 Node.js 中用于收集性能数据的模块,Node.js 本身基于 perf_hooks 提供了性能数据,同时也提供了机制给用户上报性能数据。文本介绍一下 perk_hooks。PerformanceEntryPerformanceEntry 是 perf_hooks 里的一个核心数据结构,PerformanceEntry 代表一次性能数据。下面来看一下它的定义。template <typename Traits>struct PerformanceE

2022-03-20 01:48:46 1954

原创 通过 Inspector 收集 Node.js 的 trace event 数据

前言:Node.js 提供了 trace event 的机制,在 Node.js 内核代码里,静态地埋了一些点,比如同步文件 IO 耗时,DNS 解析耗时等。每次执行这些代码时,Node.js 就会执行这些点的钩子,从而收集相应的数据。不过这个能力默认是关闭的,毕竟对性能会产生影响。我们可以通过 trace_events 模块打开这个功能。trace_events 模块会源源不断地把数据写到一个到多个文件中。除了通过 trace_events 模块之外,Node.js 也实现了通过 Inspector 协议

2022-03-13 02:10:08 180

原创 Node.js 事件循环全景图

2022-02-06 10:03:06 632

原创 端口复用之 SO_REUSEADDR

前言:端口复用是网络编程里的经典问题,同时这里面的知识点又非常繁琐,本文通过代码简单介绍一下 SO_REUSEADDR,但不会涉及到 SO_REUSEPORT。长期以来,我们都有一个认知,就是不能监听同一个端口。比如以下代码。server1.listen(8080);server2.listen(8080);我们就会看到 Address already in use 的错误。但是真的不能绑定到同一个端口吗?不一定。#include <stdio.h>#include <std

2022-02-04 05:40:34 572

原创 深入理解 Node.js 的 trace_event

前言: trace event 简单来说就是在代码里静态插入埋点,当开启 trace event 的时候,每次经过这些埋点,就会记录执行的相关数据,通过这些数据,我们可以对系统进行分析。Node.js 内核支持 trace event 的功能,并实现了对某些模块的 trace 能力。本文介绍 trace event 在 Node.js 中的实现。在 Node.js 收集 trace_event 数据的方式有两种,第一种是在启动 Node.js 时通过命令行参数。node --trace-event-ca

2022-01-29 19:15:12 1532

原创 Node.js 内核的幕后英雄 --- 子线程

前言:Node.js 为人所知的是单线程应用,也为人所知的是底层其实利用了多线程。单线程会使得代码实现上变得容易好理解,但是带来好处的同时,也往往会存在一些限制,这些限制导致在 Node.js 内核中,不得不引入其他子线程,最终形成多线程。本文介绍 Node.js 中的这些幕后英雄。1 Libuv 线程池Node.js 中,Libuv 线程池是最为人所知的子线程。Node.js 的整体架构是单线程 + 事件驱动,其本质是一个生产者消费者的模型。Node.js 不断通过事件驱动模块订阅 fd 的事件,

2022-01-29 03:01:29 1992

原创 Node.js ObjectWrap 的弱引用问题

前言:最近在写 Node.js Addon 的过程中,遇到了一个问题,然后发现是 ObjectWrap 弱引用导致的,本文介绍一下具体的问题和排查过程,以及 ObjectWrap 的使用问题。ObjectWrap 用于写 Addon 的时候导出 C++ 对象给 JS 层使用,大致用法如下。首先定义一个 C++ 类。class Demo: public node::ObjectWrap { public: static void create(const FunctionCallbackInfo

2022-01-02 05:29:43 850

原创 Node.js 的微任务处理(基于Node.js V17)

前言:Node.js 的事件循环已经老生常谈,但是在 Node.js 的执行流程中,事件循环并不是全部,在事件循环之外,微任务的处理也是核心节点,比如 nextTick 和 Promise 任务的处理。本文介绍 Node.js 中微任务处理的相关内容。网上文章和很多面试题中有很多关于 Promise、nextTick、setTimeout 和 setImmediate 执行顺序的内容。通过本文,让你从原理上理解他们,碰到相关的问题就引刃而解,不再拘泥于背诵和记录。1 事件循环本文不打算详细地讲解事件循环

2021-12-25 14:29:07 930

原创 使用 ebpf 监控 Node.js 事件循环的耗时

前言:强大的 ebpf 使用越来越广,能做的事情也越来越多,尤其是无侵入的优雅方式更加是技术选型的好选择。本文介绍如何使用 ebpf 来监控 Node.js 的耗时,从而了解 Node.js 事件循环的执行情况。不过这只是粗粒度的监控,想要精细地了解 Node.js 的运行情况,需要做的事情还很多。在 Node.js 里,我们可以通过 V8 Inspector 的 cpuprofile 来了解 JS 的执行耗时,但是 cpuprofile 无法看到 C、C++ 代码的执行耗时,通常我们可以使用 perf

2021-12-18 00:25:53 1040

原创 Linux ptrace 的实现

前言:ptrace 是 Linux 内核提供的非常强大的系统调用,通过 ptrace 可以实现进程的单步调试和收集系统调用情况。比如 strace 和 gdb 都是基于 ptrace 实现的,strace 可以显示进程调用了哪些系统调用,gdb 可以实现对进程的调试。本文介绍这些工具的底层 ptrace 是如何实现的。这里选用了 1.2.13 的早期版本,原理是类似的,新版内核代码过多,没必要陷入过多细节中。1 单步调试ptrace 系统调用的实现中包含了很多功能,首先来看一下单步调试的实现。通过 pt

2021-12-04 21:49:46 809

原创 探索 ebpf 在 Node.js 中的应用

前言:ebpf 是现代 Linux 内核提供的非常复杂和强大的技术,它使得 Linux 内核变得可编程,不再是完全的黑盒子。随着 ebpf 的发展和成熟,其应用也越来越广泛,本文介绍如何使用 ebpf 来追踪 Node.js 底层的代码。介绍ebpf 的设计思想虽然很简单,但是实现和使用上非常复杂。ebpf 本质上内核实现了一个虚拟机,用户可以把自己编写的 c 代码加载进内核中执行,从而参与内核的逻辑处理。这听起来很简单,但是整个技术其实非常复杂,从实现来说,内核需要对加载的代码进行非常多而复杂的校验,

2021-11-30 23:55:13 293

原创 something about Node.js

1 如何监听 Node.js 的所有函数这是一次危险的探索,但是或许某些场景下可以用到。主要想做的事情是劫持所有的 Node.js 函数,在函数执行前后,插入钩子做些事情。但是由于场景很多而且负责,劫持的风险非常高,如果你使用以下代码有问题,可以提个 issue。以下代码可以通过预加载方式加载或者在你的代码执行前加载。module-wrap.jsconst { Module } = require('module');function before(...args) { console.l

2021-11-21 08:21:10 364

libv8_monolith.a.zip

libv8_monolith.a.zip

2021-07-09

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除