[![构建状态][:badge-ci:]][:link-ci:] ![支持的PHP版本: 5.4 .. 8.x][:badge-php-versions:] ![支持的平台: GNU/Linux, macOS & FreeBSD][:badge-supported-platforms:] ![支持的架构: x86-64 或 ARM64][:badge-supported-arch:] [![许可证][:badge-license:]][:link-license:]
<a href="https://www.buymeacoffee.com/noisebynw" target="_blank"><img src="https://yellow-cdn.veclightyear.com/2b54e442/ffaf898e-0398-4d38-83e6-228f0d014c36.png" alt="给我买杯咖啡" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
SPX,全称为_Simple Profiling eXtension_,是另一个PHP性能分析扩展。 它与其他类似扩展的区别在于:
目前平台支持相当有限。如果您的平台不受支持,请随时提出问题。 当前要求是:
sudo apt-get install zlib1g-dev
。sudo dnf install zlib-devel
。git clone https://github.com/NoiseByNorthwest/php-spx.git cd php-spx git checkout release/latest phpize ./configure make sudo make install
然后在您的php.ini中添加extension=spx.so
,或在包含目录中创建一个专用的spx.ini文件。
您可能还想覆盖默认SPX配置以便能够分析Web请求,例如使用这个配置来适用于本地开发环境。
在GNU/Linux上,SPX使用procfs(即通过读取/proc
目录下的文件)来获取当前进程或线程的一些统计信息。当您选择以下指标中的至少一个时,就会在底层执行此操作:mor
、io
、ior
或iow
。
但是,在大多数PHP-FPM设置中,您会遇到权限问题,阻止SPX打开/proc/self
目录下的文件。
这是因为PHP-FPM主进程以root 身份运行,而子进程以另一个非特权用户身份运行。
在这种情况下,必须在FPM池配置中添加process.dumpable = yes
行,以便子进程能够读取/proc/self
下的任何文件。
这仍然是实验性的。API可能会改变,功能可能会增加或删除,或者开发可能会被冻结。
您仍然可以在非生产环境中安全地使用它。
欢迎贡献,但请注意这个项目的实验性质,并请遵循这里描述的贡献规则:CONTRIBUTING.md
假设开发环境使用这里描述的配置,并且您的应用程序可以通过http://localhost
访问。
只需用浏览器打开以下URL:http://localhost/?SPX_KEY=dev&SPX_UI_URI=/
即可访问Web界面的控制面板。
注意:http://localhost/
必须通过标准Web服务器功能(如目录索引或URL重写)由PHP脚本提供服务。但是,PHP脚本不会被执行,SPX将拦截并禁用其执行,以替代提供其内容。
如果您只看到空白页面,请确保在PHP配置文件中设置zlib.output_compression = 0
然后您将看到以下表单:
然后开启"已启用"。此时,通过一组专用cookie,为当前域和您当前的浏览器会话启用了性能分析。
也可以使用Curl触发性能分析,如下例所示:
curl --cookie "SPX_ENABLED=1; SPX_KEY=dev" http://localhost/
注意:您也可以通过spx.http_profiling_enabled
设置在INI配置级别启 用性能分析,从而对所有HTTP请求生效。但是,请记住,在高流量环境中使用此设置可能会快速耗尽SPX数据目录所在存储设备的容量。
然后刷新您想要分析的Web请求,并刷新控制面板以查看控制面板表单下方列表中生成的报告。
然后点击列表中的报告,享受分析界面。
只需在命令行前加上SPX_ENABLED=1
即可触发性能分析。您将在执行结束时在STDERR上看到打印的扁平配置文件,即使您通过按Ctrl-C中止它,如下例所示:
$ SPX_ENABLED=1 composer update 加载composer仓库信息 更新依赖(包括require-dev) ^C *** SPX 报告 *** 全局统计: 调用的函数 : 27.5K 不同的函数 : 714 墙钟时间 : 7.39s ZE内存 : 62.6MB 扁平配置文件: 墙钟时间 | ZE内存 | 包含 | *排除 | 包含 | 排除 | 调用次数 | 函数 ----------+----------+----------+----------+----------+---------- 101.6ms | 101.6ms | 41.8MB | 41.8MB | 12 | Composer\Json\JsonFile::parseJson 53.6ms | 53.6ms | 544B | 544B | 4 | Composer\Cache::sha256 6.91s | 41.5ms | 41.5MB | -7.5MB | 4 | Composer\Repository\ComposerRepository::fetchFile 6.85s | 32.3ms | 47.5MB | 5.4MB | 5 | 1@Composer\Repository\ComposerRepository::loadProviderListings 7.8ms | 7.8ms | 0B | 0B | 4 | Composer\Cache::write 1.1ms | 1.1ms | -72B | -72B | 1 | Composer\Console\Application::Composer\Console\{closure} 828.5us | 828.5us | 976B | 976B | 12 | Composer\Util\RemoteFilesystem::findHeaderValue 497.6us | 491.0us | 710.2KB | 710.2KB | 1 | Composer\Cache::read 2.4ms | 332.6us | 20.9KB | -378.8KB | 34 | 3@Symfony\Component\Finder\Iterator\FilterIterator::rewind 298.9us | 298.9us | 2.2KB | 2.2KB | 47 | Symfony\Component\Finder\Iterator\FileTypeFilterIterator::accept
注意:只需添加SPX_FP_LIVE=1
即可在脚本执行期间启用扁平配置文件的实时刷新。
您只需指定SPX_REPORT=full
即可生成可通过Web界面访问的报告:
SPX_ENABLED=1 SPX_REPORT=full ./bin/console cache:clear
如果您的CLI脚本是长期运行和/或守护进程(例如通过supervisord),分析其整个生命周期可能没有意义。这在等待处理任务的服务情况下尤其如此。
为了处理这种情况,SPX允许禁用性能分析的自动启动,并暴露2个用户层函数,spx_profiler_start(): void
和spx_profiler_stop(): ?string
,分别控制被分析跨度的开始和结束。
以下是如何修改您的脚本:
<?php while ($task = get_next_ready_task()) { spx_profiler_start(); try { $task->process(); } finally { spx_profiler_stop(); } }
当然,这个脚本必须至少启用性能分析并禁用自动启动,如下面的命令所示:
SPX_ENABLED=1 SPX_REPORT=full SPX_AUTO_START=0 my_script.php
自动启动也可以通过spx.http_profiling_auto_start
INI参数或通过控制面板为Web请求禁用。
注意事项:
spx_profiler_start()
和spx_profiler_stop()
可以安全嵌套。spx_profiler_stop()
返回报告键,这样您就可以将其存储在某处,例如与被分析跨度相关的其他信息中。使用报告键,您可以构建分析界面URL,该URL以此模式结尾/?SPX_UI_URI=/report.html&key=<report key>
。当使用_full_报告作为输出进行性能分析时,为当前报告添加自定义元数据可能会很方便,这样您就可以轻松检索它或将其与其他类似报告区分开来。
这对于长期运行进程的用例尤其如此,否则无法将一个报告与同一进程的其他报告区分开来。
为此,SPX暴露了spx_profiler_full_report_set_custom_metadata_str(string $customMetadataStr): void
函数。
正如您可能注意到的,此函数接受一个字符串作为自定义元数据,以实现SPX端的灵活性和简单性。由您来将任何结构化数据编码为字符串,例如使用JSON格式。
元数据字符串限制为4KB,这对大多数用例来说足够大了。如果您传递一个超过此限制的字符串,它将被丢弃,并会发出一个通知日志。
此字符串将与当前报告的其他元数据一起存储,您可以在Web界面的报告列表中检索它。
只要 profiler 已经启动且尚未结束,spx_profiler_full_report_set_custom_metadata_str()
就可以在任何时候调用,这意味着:
spx_profiler_start()
之后和调用 spx_profiler_stop()
之前的任何时刻调用。以下是一个示例:
<?php while ($task = get_next_ready_task()) { spx_profiler_start(); spx_profiler_full_report_set_custom_metadata_str(json_encode( [ 'taskId' => $task->getId(), ] )); try { $task->process(); } finally { spx_profiler_stop(); } }
名称 | 默认值 | 可更改 | 描述 |
---|---|---|---|
spx.data_dir | /tmp/spx | PHP_INI_SYSTEM | 存储性能分析报告的目录。例如,在多服务器架构的情况下,您可以将其更改为指向共享文件系统。 |
spx.http_enabled | 0 | PHP_INI_SYSTEM | 是否启用网络界面和HTTP请求分析。 |
spx.http_key | PHP_INI_SYSTEM | 用于身份验证的密钥(更多详情请参见安全问题)。您可以使用以下命令生成16字节的随机密钥作为十六进制字符串: openssl rand -hex 16 。 | |
spx.http_ip_var | REMOTE_ADDR | PHP_INI_SYSTEM | 用于身份验证的客户端IP地址所在的 $_SERVER 键(更多详情请参见安全问题)。当您的应用程序位于反向代理后面时,需要覆盖默认值。 |
spx.http_trusted_proxies | 127.0.0.1 | PHP_INI_SYSTEM | 可信代理列表,以逗号分隔的IP地址列表。当 spx.http_ip_var 的值为 REMOTE_ADDR 时,此设置将被忽略。 |
spx.http_ip_whitelist | PHP_INI_SYSTEM | 用于身份验证的IP地址白名单,以逗号分隔的IP地址列表,使用 * 允许所有IP地址。 | |
spx.http_ui_assets_dir | /usr/local/share/misc/php-spx/assets/web-ui | PHP_INI_SYSTEM | 安装网络界面文件的目录。在大多数情况下,您无需更改它。 |
spx.http_profiling_enabled | NULL | PHP_INI_SYSTEM | SPX_ENABLED 参数的INI级别对应项,仅适用于HTTP请求。更多详情请参见此处。 |
spx.http_profiling_auto_start | NULL | PHP_INI_SYSTEM | SPX_AUTO_START 参数的INI级别对应项,仅适用于HTTP请求。更多详情请参见此处。 |
spx.http_profiling_builtins | NULL | PHP_INI_SYSTEM | SPX_BUILTINS 参数的INI级别对应项,仅适用于HTTP请求。更多详情请参见此处。 |
spx.http_profiling_sampling_period | NULL | PHP_INI_SYSTEM | SPX_SAMPLING_PERIOD 参数的INI级别对应项,仅适用于HTTP请求。更多详情请参见此处。 |
spx.http_profiling_depth | NULL | PHP_INI_SYSTEM | SPX_DEPTH 参数的INI级别对应项,仅适用于HTTP请求。更多详情请参见此处。 |
spx.http_profiling_metrics | NULL | PHP_INI_SYSTEM | SPX_METRICS 参数的INI级别对应项,仅适用于HTTP请求。更多详情请参见此处。 |
对于您的本地和私有开发环境,由于不需要身份验证,您可以使用以下配置:
spx.http_enabled=1
spx.http_key="dev"
spx.http_ip_whitelist="127.0.0.1"
然后通过 http(s)://<your application host>/?SPX_KEY=dev&SPX_UI_URI=/
访问网络界面。
以下是可收集的指标列表。默认情况下,仅收集 Wall time 和 Zend Engine memory usage。
键 (命令行) | 名称 | 描述 |
---|---|---|
wt | Wall time | 绝对经过时间。 |
ct | CPU time | 在CPU上运行所花费的时间。 |
it | Idle time | 离开CPU的时间,即等待CPU、I/O完成、获取锁...或显式休眠。 |
zm | Zend Engine memory usage | 等同于 memory_get_usage(false) 。 |
zmac | Zend Engine allocation count | 执行的内存分配次数(即分配的块数)。 |
zmab | Zend Engine allocated bytes<b>*</b> | 分配的字节数。 |
zmfc | Zend Engine free count | 执行的内存释放次数(即释放的块数)。 |
zmfb | Zend Engine freed bytes<b>*</b> | 释放的字节数。 |
zgr | Zend Engine GC run count | GC(循环收集器)被触发的次数(手动或自动)。 |
zgb | Zend Engine GC root buffer length | 根缓冲区长度,请参阅此处的解释。这有助于跟踪垃圾收集器的压力。 |
zgc | Zend Engine GC collected cycle count | 通过所有GC运行收集的循环总数。 |
zif | Zend Engine included file count | 包含的文件数。 |
zil | Zend Engine included line count | 包含的行数。 |
zuc | Zend Engine user class count | 用户定义类的数量。 |
zuf | Zend Engine user function count | 用户定义函数的数量(包括用户定义类/实例方法)。 |
zuo | Zend Engine user opcode count | 包含的用户定义操作码数量(所有用户定义文件/函数/方法操作码的总和)。 |
zo | Zend Engine object count | 用户代码当前持有的对象数量。 |
ze | Zend Engine error count | 引发的PHP错误数量。 |
mor | Process's own RSS<b>**</b> | 进程内存中保留在RAM中的部分。不考虑共享(与其他进程)的内存块。此指标可用于突出显示PHP扩展或更深层次(例如第三方C库)中的内存泄漏。 |
io | I/O (reads + writes)** | 执行I/O时读取或写入的字节数。 |
ior | I/O (reads)** | 执行I/O时读取的字节数。 |
iow | I/O (writes)** | 执行I/O时写入的字节数。 |
*: 如果您使用自定义分配器或通过将 USE_ZEND_ALLOC
环境变量设置为 0
强制使用libc分配器,则不会收集分配和释放的字节数。
**: macOS和FreeBSD不支持RSS和I/O指标。在GNU/Linux上,如果您使用PHP-FPM,应该阅读此内容。
与仅支持 full 报告类型(可由网络界面利用)的网络请求分析不同,命令行脚本分析支持多种类型的报告。 以下是列表:
键 | 名称 | 描述 |
---|---|---|
fp | Flat profile | SPX提供的平面分析。这是默认报告类型,直接打印在STDERR上。 |
full | Full report | 这是网络界面的报告类型。报告将存储在SPX数据目录中,因此可在网络界面端进行分析。 |
trace | Trace file | 自定义格式(人类可读文本)的跟踪文件。 |
名称 | 默认值 | 描述 |
---|---|---|
SPX_ENABLED | 0 | 是否启用SPX分析器(即触发分析)。禁用时不会对应用程序的性能产生影响。 |
SPX_AUTO_START | 1 | 是否启用SPX分析器的自动启动。禁用自动启动时,您必须在运行时通过 spx_profiler_start() 和 spx_profiler_stop() 函数自行启动和停止分析。更多详情请参见此处。 |
SPX_BUILTINS | 0 | 是否分析内部函数、脚本编译、GC运行和请求关闭。 |
SPX_DEPTH | 0 | 分析必须停止的堆栈深度(即聚合更深层调用的度量)。0(默认值)表示无限制。 |
SPX_SAMPLING_PERIOD | 0 | 是否根据指定的采样周期定期收集当前调用堆栈的数据(0 表示不采样)。结果通常会不太准确,但在某些情况下,它可能会更加准确,因为不会过度评估多次调用的小函数。如果您想准确找到时间瓶颈,建议尝试采样(使用不同的周期)。在分析长时间运行且CPU密集的脚本时,此选项将允许您控制报告大小,从而保持其足够小以便网络界面利用。更多详情请参见此处。 |
SPX_METRICS | wt,zm | 要收集的可用指标键的逗号分隔列表。所有报告类型都可以利用多指标分析。 |
SPX_REPORT | fp | 选择的报告键。 |
SPX_FP_FOCUS | wt | 平面分析排序的指标键。 |
SPX_FP_INC | 0 | 是否在平面分析中按包含值而不是排他值对函数进行排序。 |
SPX_FP_REL | 0 | 是否在平面分析中将指标值显示为相对值(即百分比)。 |
SPX_FP_LIMIT | 10 | 平面分析的大小(即显示的前N个函数)。 |
SPX_FP_LIVE | 0 | 是否启用平面分析实时刷新。由于它通过ANSI转义序列操作光标位置,因此使用STDOUT作为输出,替换脚本输出(STDOUT和STDERR)。 |
SPX_FP_COLOR | 1 | 是否启用平面分析的彩色模式。 |
SPX_TRACE_SAFE | 0 | 默认情况下,跟踪文件的写入方式会确保准确性,但在进程崩溃(例如段错误)的情况下,可能会丢失一些日志。如果您想确保持久性(例如,找到崩溃前的最后一个事件),只需将此参数设置为1即可。 |
SPX_TRACE_FILE | 自定义跟踪文件名。如果未指定,将在 /tmp 中生成并在脚本结束时显示在STDERR上。 |
正如您可能已经在相应的基本用法示例中注意到的那样,为命令行脚本设置SPX参数只需设置一个具有相同名称的环境变量。
由于网络界面使用了高级JavaScript功能,因此仅支持以下浏览器:
这是网络界面的主页,分为两部分:
[点击此 默认情况下,可视化中的函数相关块根据其成本进行着色,颜色比例尺显示在屏幕右上角。
您也可以通过点击屏幕顶部指标选择器后面显示的颜色方案模式链接来定义自定义颜色方案。 然后会出现一个下拉窗口,允许您在"默认"和"类别"模式之间切换,并为"类别"模式定义(添加/编辑/删除)您的类别(颜色、名称、模式列表)(请参见下面的截图)。
这个可视化是所有被调用函数的时间线概览。 您可以通过简单地水平拖动来更改所选时间范围,用透明的绿色矩形表示。
除了挂钟时间外,当前指标也绘制在前景层上(当前值随时间变化)。
支持的控制:
这个可视化是一个交互式时间线,能够控制并保持对所选时间范围的焦点。
支持的控制:
除了挂钟时间外,当前指标也绘制在前景层上(当前值随时间变化)。
这个可视化是所选时间范围和所选指标的平面配置文件,以可排序的表格显示。
"Inc."和"Exc."子列分别对应:
这个由Brendan Gregg设计的可视化,允许快速找到所选时间范围和所选指标的热代码路径。 这个可视化不支持对应于可释放资源(内存、使用中的对象等)的指标。
您可以通过点击时间线或火焰图小部件中的一个跨度,或平面配置文件小部件中的名称来高亮显示一个函数。
缺乏对这个问题的审查/反馈是SPX还不能被认为是生产就绪的主要原因。
SPX允许您分析Web请求以及命令行脚本,并通过其嵌入式Web UI列出和分析配置文件报告。 这就是为什么存在巨大的安全风险,因为攻击者可能:
因此,除非对您的应用程序的访问已经在较低层(即在您的应用程序被命中之前,而不是由应用程序/PHP框架本身)受到限制,否则触发分析或访问Web UI的客户端必须进行身份验证。
SPX提供两因素身份验证,包括这两个必需的锁:
因此,客户端只有在其IP地址在白名单中且提供的密钥有效的情况下,才能通过Web请求分析您的应用程序。
在跟踪模式(默认)下,当测量的函数执行时间:
SPX在时间相关指标方面可能存在准确性问题。
第一个问题通过使用平台提供的最高分辨率计时器来缓解。在Linux、FreeBSD和最新的macOS版本上,计时器分辨率为1ns;在macOS 10.12/Sierra之前的版本上,计时器分辨率仅为1us。
第二个问题通过考虑SPX的时间(挂钟/CPU)开销并从测量的函数执行时间中减去来缓解。这是通过在开始分析脚本之前评估SPX恒定每函数开销来完成的。
然而,无论平台如何,如果您想最大化准确性以找到时间瓶颈,您还应该:
用于Intelephense的SPX函数存根
composer require --dev 8ctopus/php-spx-stubs
我从阅读以下内容中获得了很多灵感和提示:
SPX是根据GNU通用公共许可证(GPL-3)许可的开源软件。 有关更多信息,请参阅[LICENSE][:link-license:]文件。
AI小说写作助手,一站式润色、改写、扩写
蛙蛙写作—国内先进的AI写作平台,涵盖 小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。
字节跳动发布的AI编程神器IDE
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制 定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号