gggeek/polyfill-pinba

纯PHP实现的暴露于本地Pinba扩展的API

1.1.1 2022-12-13 10:42 UTC

This package is auto-updated.

Last update: 2024-09-13 14:47:24 UTC


README

“PHP扩展Pinba”的纯PHP重新实现。

关于原始版本,请参阅http://pinba.org

要求

PHP 5.3或更高版本。

需要一个Pinba服务器来发送数据。已知的服务器包括http://pinba.org/https://github.com/badoo/pinba2。这两个都可以作为Docker容器镜像试用。

安装

composer require gggeek/polyfill-pinba

然后在php.ini中设置配置设置pinba.enabledpinba.server,具体请参阅https://github.com/tony2001/pinba_engine/wiki/PHP-extension#INI_Directives

就这么多。

注意默认情况下,指标收集和发送到服务器是禁用的。除非您在PHP代码中添加了显式的pinba api调用,否则您必须通过ini设置启用它。

用法

请参阅https://github.com/tony2001/pinba_engine/wiki/PHP-extension中描述的API

一个简单的用法示例可以在doc/sample.php中找到。

要查看收集到的指标,请查看https://github.com/intaro/pinboardhttps://github.com/pinba-server/pinba-serverhttps://github.com/ClickHouse-Ninja/Proton

原始API的扩展

Pinba::ini_set

如果您的设置中没有启用pinba php扩展(这很可能是情况,否则您就不会使用这个包),则无法从PHP代码中修改ini选项pinba.enabledpinba.server的值。虽然可以在php.ini中设置它们的值,但如果您想在运行时修改它们的值,您将不得不使用方法\PinbaPhp\Polyfill\pinba::ini_set($option, $value)。您还应该使用相应的方法\PinbaPhp\Polyfill\pinba::ini_get($option)来检查它。

ini选项pinba.inhibited

如果您想保留代码中用pinba_timer_addpinba_timer_stop和类似调用进行仪器检测,但不再收集pinba数据,并且希望尽可能减少此包带来的开销,请在php.ini中设置pinba.inhibited=1

在此场景中不建议使用pinba.enabled=0pinba.auto_flush=0,因为尽管它们都禁用了数据发送,但它们并不能防止定时器的实际创建。

兼容性

我们努力实现与Pinba扩展1.1.2相同的API。

至于服务器端,该库已针对Pinba服务器和Pinba2进行兼容性测试。

不支持的功能(尚未支持)

  • 定时器数据缺少ru_utimeru_stime成员。这也适用于添加到PinbaClient实例的定时器

已知问题(无法/不会修复的问题)

  • 时间报告精度不足:页面执行报告的时间会比使用PHP扩展所能测量的时间短得多。因此,我们建议不要将此包报告的时间视为绝对值,而是用它来检查宏观问题,例如一个页面运行10秒,或者比另一个页面多10倍。在演示文件 doc/sample.php 中,我们展示了如何尽可能精确地进行时间测量
  • 对系统性能的影响:此实现(运行在您网站的每个页面上!)所使用的CPU时间和RAM也大于PHP扩展使用的资源。是否使用此包给服务器增加额外负载取决于您自己,尤其是对于高负载的生产服务器
  • 当将错误数据传递给pinba php函数时,所引发的警告严重性为E_USER_WARNING,而不是E_WARNING
  • pinba_get_info报告的数据和报告给Pinba服务器的数据中,doc_size始终具有0值。可以通过使用PinbaClient实例并调用setDocumentSize来解决此问题 - 有关示例,请参阅doc/measure_body_size.php
  • 在报告给Pinba服务器的数据中,memory_footprint始终具有固定的0值或根本不报告。同样,使用PinbaClient实例可以解决这个问题 - 但据我所知,没有PHP函数可以报告由PHP扩展完成的等效mallinfo C调用的使用情况
  • ini设置pinba.resolve_interval不受支持,并且可能永远不会支持
  • 报告给Pina引擎的schema字段的默认值是空字符串,而不是未设置。这导致数据库表存储的值为''而不是NULL。同时,发送NULL值会使服务器端引擎重用上一个pinba数据包中的最后一个非空值,这似乎是一种错误的行为
  • pinba_reset调用确实会删除所有现有的计时器,这与PHP扩展中相同函数的行为不同。同样,上游的行为感觉上是错误的

性能

这些结果表明,执行1000次函数调用循环的时间和内存开销,并使用单独的计时器对每次执行进行仪表化。

如您所见,引入的执行延迟非常小,小于1毫秒。内存开销与添加的计时器数量和每个计时器附加的标签数量成正比。

No timing:       0.00001 secs,       0 bytes used
Pinba-extension: 0.00072 secs,  280.640 bytes used
PHP-Pinba:       0.00062 secs,  412.920 bytes used

注意:奇怪的是,PHP扩展似乎平均比纯PHP实现要慢一些。简要查看扩展的C代码后,我怀疑这是因为它执行了太多的gettimeofday调用...

如果您想保持使用大量pinba_timer_start调用的代码进行仪表化,并尽可能减少使用扩展的开销(当然不再进行测量),您可以在php.ini中设置pinba.inhibited=1

设置了它之后,这是“计时”1000次函数调用执行时的开销

No timing:      0.00001 secs,       0 bytes used
PHPPinba timed: 0.00009 secs,       0 bytes used

(在Ubuntu Focal容器中执行测试,容器运行在Ubuntu Jammy VM中,分配了4个vCPU)

注意

包含来自Iván -DrSlump- Montes的Protobuf for PHP库的代码:https://github.com/drslump/Protobuf-PHP

存在其他实现相同想法的已知包,例如:https://github.com/vearutop/pinba-pure-php

常见问题解答

  • 问题:我可以在使用 pinba php 扩展的同时运行 polyfill 吗?答案:是的,尽管我不明白你为什么要这样做。这样做时,除非你注意选择性地禁用 php 扩展或此捆绑包(例如,通过在代码中调用 Pinba::ini_set),否则你将向 Pinba 服务器报告双倍的数据。

运行测试

运行库的测试套件建议的方式是通过提供的 Docker 容器和相应的 Docker Compose 配置。有一个方便的 shell 脚本可以简化 Docker 和 Docker Compose 的使用。

操作的全过程是

./tests/ci/vm.sh build
./tests/ci/vm.sh start
./tests/ci/vm.sh runtests
./tests/ci/vm.sh stop

# and, once you have finished all testing related work:
./tests/ci/vm.sh cleanup

默认情况下,测试使用基于 Ubuntu 20 Focal 的容器中的 php 7.4 运行。数据被发送到运行原始 Pinba 服务器容器的容器 - 它也可以配置为发送到运行 Pinba2 服务器容器的容器。

你可以在构建容器之前设置环境变量 PHP_VERSIONUBUNTU_VERSION 来更改使用的 PHP 和 Ubuntu 版本。

你可以在启动容器之前设置环境变量 PINBA_DB_SERVER=pinba2PINBA_SERVER=pinba2PINBA_PORT=3002,将测试套件的目标容器切换到运行 Pinba2 的容器。

测试技巧

  • 要调试 php 和 Pinba 服务器之间的通信,你可以在 php 容器中使用 tcpdump。

      sudo tcpdump udp -w packets.cap
    

    一旦捕获文件被保存,可以使用 Wireshark 等工具进行分析。为了提高 Wireshark 解码 protobuf 格式消息的能力,请根据 https://wiki.wireshark.org/Protobuf.md 中的说明设置其配置。描述 Pinba 所用消息的 .proto 文件可以在 https://github.com/badoo/pinba2/blob/master/proto/pinba.proto 找到。

    作为 Wireshark 不需要的替代方案,你也可以将 pinba_get_data() 调用的字符串结果保存到文件中,然后使用默认包含在测试容器中的 protoc 工具对其进行解码。

    php myTestFile > test.rawmsg
    protoc --decode=Pinba.Request tests/pinba.proto < test.rawmsg
    

许可证

使用此软件受 许可证 文件中的条款约束。

License Latest Stable Version Total Downloads

Build Status Code Coverage