PHP 探针实现原理分析

Posted 轻易科技技术中心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP 探针实现原理分析相关的知识,希望对你有一定的参考价值。

作用

  1. 调试 eg: xdebug, zend debug

  2. 性能分析 xhprof

  3. 链路监控 apm, molten, skywalking-php-sdk

实现方式

总的来讲有两种实现方式

  1. 添加代理,对每个函数的执行增加代理,在代理中针对性的增加记录。

  2. 在模块注册过程中修改CG(function_table) 或 CG(class_table)。

添加代理的方式


PHP 探针实现原理分析

PHP 探针实现原理分析

        以上代码中有两个关键函数 zend_execute_ex 及 zend_execute_internal,通过修改这两个函数来添加代理,保存旧值是为了在代理中恢复原始PHP代码的执行。 

       不同场景下对数据的收集详细程度不同,例如调试和性能分析时需要运行相关的所有数据,而在链路监控中只需要针对性的进行处理即可,在molten中即通过设置需要代理的名单来进行针对性的监控。



PHP 探针实现原理分析

        从上面可以看出增加探针之后性能影响因素包括 检测当前方法是否需要进行代理及日志的处理上,同时由于每个方法的执行都要经过代理进行判断及处理在性能上会有一部分损耗.

       以下为对猜想的验证:

验证代码

PHP 探针实现原理分析

PHP 探针实现原理分析

        上图中的参数t为执行的函数数量,代码中执行的函数不在探针的统计列表中。可以看到所执行函数次数从100增加到400后QPS降低了15%左右。

针对Lumen框架的测试可以看到之进行简单输出内容的一个接口性能影响甚至达到了20%+。

       综上可以看出通过代理的方式优点是可以很方便的针对用户定义的函数/类进行监控,但是性能损耗也会受到框架及业务逻辑复杂度的影响。

修改Hash表的方式

        在模块注册过程中修改Hash表相比于代理来说性能损耗很小,损耗大小主要取决于探针逻辑及增加的钩子的多少(探针逻辑越复杂,钩子执行的越多性能损耗也就越高)

以下代码为Molten中的实现方式。

       针对内置函数也可以使用修改handler的方式来处理,如下为opcache中覆盖内置文件相关函数的方法,相比上面的直接替换的方式更简单易懂,skywalking-php-sdk中使用的即是这种方式。

对比


代理 修改全局Hash表
内置函数 可以 可以
自定义函数 可以 不可以
性能 差,执行函数越多性能越差 好,影响较小


猜想

       通过查阅资料发现zend引擎中可以对编译函数进行改写,因此如果把用户自定义函数钩子添加到函数注册的节点,那么就可以不通过代理直接达到修改Hash表方式的性能。


以上是关于PHP 探针实现原理分析的主要内容,如果未能解决你的问题,请参考以下文章

020 wifi探针的广告扰民原理

PHP函数的实现原理及性能分析

编译原理:词法分析PHP代码实现

php session实现原理分析

从原理分析PHP性能

PHP中Session ID的实现原理分析