Perfetto - 43 - Service-based model
Perfetto - 43 - Service-based model
Service
服务 跟踪服务是一个长期运行的实体(在Linux/Android上是系统守护进程,在Chrome上是服务),具有以下职责:
- 维护活动生成器及其数据源的注册表。
- 拥有跟踪缓冲区。
- 处理多个跟踪会话的复用。
- 将跟踪配置从消费者路由到相应的生产者。
- 告诉生成器何时以及如何跟踪。
- 将数据从生成器的共享内存缓冲区移动到中央非共享跟踪缓冲区。
Producer
生产者是一个不受信任的实体,提供了对跟踪贡献的能力。在多进程模型中,生产者几乎总是对应于跟踪服务的客户端进程。它通过一个或多个数据源宣布其贡献跟踪的能力。每个生产者恰好具有:
- 一个与跟踪服务独占共享的共享内存缓冲区。
- 一个与跟踪服务的IPC通道。
生产者完全与消费者(在技术和概念上)解耦。生产者不知道以下内容:
- 有多少个消费者连接到服务。
- 有多少个跟踪会话处于活动状态。
- 有多少其他生产者已注册或处于活动状态。
- 其他生产者编写的跟踪数据。
Consumer
Consumer 消费者是一个受信任的实体(在Linux / Android上是一个cmdline客户端,在Chrome中是浏览器进程的接口),它非排他性地控制追踪服务并以破坏性方式读回追踪缓冲区。消费者具有以下能力:
向服务发送追踪配置,确定:
- 要创建多少个跟踪缓冲区。
- 跟踪缓冲区应该有多大。
- 每个缓冲区的策略(环形缓冲区或在满时停止)。
- 启用哪些数据源。
- 为每个已配置的数据源产生的数据配置目标缓冲区。
- 启用和禁用跟踪。
- 读取追踪缓冲区:
- 通过IPC通道流式传输数据。
- 将文件描述符传递给服务,并指示其定期将追踪缓冲区保存到文件中。
Data source
数据源 数据源是由生产者提供的提供某些跟踪数据的能力。数据源几乎总是定义了自己的模式(protobuf),包括:
最多一个 DataSourceConfig 子消息:
(示例)
一个或多个 TracePacket 子消息(示例)
不同的生产者可能公开相同的数据源。
具体例子: 附注:在不久的将来,我们可能会提供一个库进行进程内堆剖析。在这种情况下,更多的生产者将会链接更新后的Perfetto库,为其自己的进程公开堆剖析数据源。
IPC channel
IPC 通道 在多进程的情况下,每个生产者和每个消费者都使用 IPC 通道与服务进行交互。IPC 仅在非快速路径交互中使用,主要是握手,如启用/禁用跟踪(消费者),(取消)注册和启动/停止数据源(生产者)。通常不使用 IPC 来传输跟踪的 protobufs。Perfetto 提供了一个基于 UNIX socket 上的 protobufs 的 POSIX-friendly IPC 实现(请参见套接字协议)。
该 IPC 实现不是强制性的。Perfetto 允许嵌入者:
包装自己的 IPC 子系统(例如,Chromium 中的 Perfetto 使用 Mojo)。 根本不使用 IPC 机制,只是通过 PostTask(s) 来缩短 Producer <> Service <> Consumer 的交互。
Shared memory buffer
共享内存缓冲区
生产者通过一个名为ProtoZero的特殊库,将跟踪数据以protobuf编码的二进制块的形式直接写入其共享内存缓冲区。共享内存缓冲区:
- 具有固定且通常较小的大小(可配置,默认为128 KB)。
- 是一个ABI,必须保持向后兼容性。
- 由生产者的所有数据源共享。
- 与跟踪缓冲区的数量和大小无关。
- 与消费者数量无关。
- 分成变量大小的块。
每个块:
- 由一个生产者线程独占所有权(或通过互斥锁共享)。
- 包含一系列TracePacket的线性序列,或其片段。一个TracePacket可以跨越多个块,片段不会暴露给消费者(消费者总是看到整个数据包,就好像它们从未被分割)。
- 可以被一个TraceWriter拥有和写入。
- 是可靠和有序序列的一部分,由WriterID标识:序列中的数据包保证按顺序读回,没有间隙和重复。
有关此缓冲区二进制格式的更多详细信息,请参见shared_memory_abi.h中的注释。
Reference
- https://perfetto.dev/docs/concepts/buffers