当前位置:首页 > PHP > 正文内容

php使用register_tick_function来定位执行慢的代码

高老师6年前 (2021-01-28)PHP1615

同事在优化页面加载慢的问题中将数据分离为2个接口来分别异步加载,但是实际的情况是接口1一直在查询,接口2也一直在查询,接口2一定要等接口1查询完成才能返回结果。一直以为fast-cgi进程数问题,反复设置无效,通过getmypid就能看到每次相应的进程id不同。正好我有空就想到通过register_tick_function来判断到底是卡在哪一行,一旦注册register_tick_function,php执行一行代码都会调用注册的处理函数,通过计算上一次代码执行时间和本次执行时间即可定位位置。

<?php

/**
 * Class Tracker
 */
class Tracker
{

    /**
     * 执行代码时间(单位毫秒)
     * @var int
     */
    protected $eval_code_time = 0;

    /**
     * 执行代码过慢时间(单位毫秒)
     * @var int
     */
    protected $slow_code_time = 200;

    /**
     * 获取当前毫秒时间戳
     * millisecondTime
     * @return float|int
     */
    protected function millisecondTime()
    {
        return microtime(true) * 1000;
    }

    /**
     * setSlowCodeTime
     * @param $time
     * @return Tracker
     * @throws Exception
     */
    public function setSlowCodeTime($time)
    {
        if ($time <= 0) {
            throw new \Exception('执行代码过慢时间必须大于0');
        }
        $this->slow_code_time = $time;
        return $this;
    }

    /**
     * startCollect
     * @throws Exception
     */
    public function startCollect()
    {
        declare (ticks = 1);
        if (!register_tick_function([$this, 'handle'], true)) {
            throw new \Exception('注册tracker处理函数失败');
        }
    }

    /**
     * handle
     */
    public function handle()
    {
        $millisecondTime = $this->millisecondTime();
        if (!$this->eval_code_time) {
            $this->eval_code_time = $millisecondTime;
        }
        if (($millisecondTime - $this->eval_code_time) > $this->slow_code_time) {
            $e = new Exception();
            var_dump($e->getTrace());die();
        } else {
            $this->eval_code_time = $millisecondTime;
        }
    }
}

//查询执行超过1秒的代码位置
$object = new Tracker();
$object->setSlowCodeTime(1)->startCollect();
sleep(1);

最终定位到的问题是同事本机开发环境session是保存在文件中的,存在session锁的问题,上面的简单粘贴下代码。

可能存在的问题,如果代码执行直接卡死进程关闭是无法定位到的,由于是windows,否则可以开启fpm慢日志即可快速定位。

扫描二维码推送至手机访问。

版权声明:本文由高久峰个人博客发布,如需转载请注明出处。

本文链接:https://blog.20230611.cn/post/194.html

分享给朋友:

“php使用register_tick_function来定位执行慢的代码” 的相关文章

PHP使用post发送Json数据

PHP使用post发送Json数据

前公司吃饭是需要在钉钉报餐的,对于不挑剔的我每天都在公司吃饭,有时忘记报餐导致吃不了饭还是很麻烦的。看了下报餐系统需要的是json数据包含我的工号即可。于是编写如下代码,放在360网址监控,1小时执行1次<?php /*自动报餐类*/ class  AutoBaocan{...

php异步执行,php后台运行,如何在windows下让php后台运行

php异步执行,php后台运行,如何在windows下让php后台运行

如果想在windows中执行php,并且让php脚本在后台运行,可以用下面的cmd命令start /b php  D:\wwwroot\default\demo1\run.php例如上面的命令意思后台运行run.php,如果想用php编写异步代码: ...

packagist包发布稳定版

packagist包发布稳定版

自己的composer已经发布到packagist,但是无法使用composer require easy-task/easy-task来安装,只能在配置文件使用如下方式安装:"require": {     "easy...

php端口复用,php socket端口复用

php端口复用,php socket端口复用

第一次听说端口复用是在mixphp最新版本中发现的,mixphp启动监听9501端口,现在作者说可以多开几个进程来执行mixphp,我心里想了下再启动不是会端口冲突嘛,但是却没有问题,于是下载mixphp的源码解读,原来是启动http服务器使用new Co\Http\Server('0.0....

php位运算符详解

php位运算符详解

文章篇幅较长,如果不喜欢看文章的,此处抛出韩顺丰老师的位运算视频,韩老师应该是全网讲php位运算符最详细的一个老师了。链接:https://pan.baidu.com/s/14xj7er8eVSUcJ-jYXyA0GA  提取码:731m 链接:https://pan.baidu.com...

php管道通信

php管道通信

(1).管道是干嘛的?管道是用于进程之间通信的,传播或交换信息(2).管道有几种?(2.1).匿名管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。通常是指父子进程关系。(2.2).高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中...