Code前端首页关于Code前端联系我们

PHP并发性能调试实践,性能提升104%

terry 2年前 (2023-09-25) 阅读数 48 #后端开发

无论是PHP、Java还是其他语言,都采用调试思路。如果有使用PHP的经验,肯定会更好,docker-compose

  • 阿里云4C和8G
  • 问题背景

    php启用了opcache,laravel也跑了优化命令来优化,composer也跑了转储自动加载命令。

    首先要声明的是,系统环境肯定存在小问题(不是没有问题)(因此性能提升巨大),但这些问题可能一辈子都检测不到,如果有,你就不要不要使用适当的工具。

    本文重点介绍如何发现这些问题以及如何发现它们的想法。

    首先,我们在系统中找到合适的 API 或函数来放大问题。

    该API最初是为了对nginx负载均衡进行健康检查而设计的。进行负载测试时,使用ab -n 100000 -c 1000,发现qps只能达到每秒140。

    我们知道Laravel性能是出了名的差,但事实并非如此。从API的写法来看,应该不会那么低。于是我们决定一探究竟。

     public function getActivateStatus()
        {
            try {
                $result = \DB::select('select 1');
                $key = 1;
                if ($result[0]->$key !== 1) {
                    throw new \Exception("mysql 检查失败");
                }
            } catch (\Exception $exception) {
                \Log::critical("数据库连接失败: {$exception->getMessage()}", $exception->getTrace());
                return \response(null, 500);
            }
            try {
                Cache::getRedis()->connection()->exists("1");
            } catch (\Exception $exception) {
                \Log::critical("缓存连接失败: {$exception->getMessage()}", $exception->getTrace());
                return \response(null, 500);
            }
            return \response(null, 204);
        }
    复制代码

    问题表现及排查思路

    top

    top命令发现系统CPU占用100%,其中80%为用户态,20%为内核态。这似乎没什么大不了的。有一个地方看起来很奇怪,运行top命令的结果PHP并发性能调优实战 ,性能提升104%

    部分php-fpm进程处于睡眠状态,但CPU利用率仍然接近30%。当进程处于睡眠状态时,仍然占用大量CPU。不要怀疑是不是工艺问题。 ,让我们看一下Ttop命令的手册页。

    %CPU -- CPU usage
    
    The task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.
    复制代码

    大致意思就是这个占用是上次屏幕刷新时进程的CPU占用。因为在top命令收集信息的时候,Linux可能已经强制进程调度了(比如通过top收集进程信息),所以此时(屏幕刷新的那一刻),部分php-fpm进程处于睡眠状态,这是可以理解的,所以php-fpm应该没有问题。

    pidstat

    首先选择php-fpm进程并使用pidstat查看了进程的详细运行状态PHP并发性能调优实战 ,性能提升104%

    过程中没有发现任何异常,运行top命令的结果也基本一致,有点偏高,没有看到太多异常。由于我们使用的docker、redis和mysql都运行在同一台机器上,所以CS在7000左右还是一个合理的范围,但是这个IN(中断)有点高了。太高了,达到了 14,000 左右。一定是有什么东西触发了中断。 PHP并发性能调优实战 ,性能提升104%

    我们知道中断包括硬中断和软中断。硬中断是网卡、鼠标等硬件发出的中断信号,CPU会立即停止工作。处理中断信号。软中断由操作系统发出,通常用于强制进程调度。 vmstat 和 pidstat 都只是新的性能检测工具。我们看不到谁发出了特定的中断。我们通过从这个只读的 /proc/interrupts 文件中读取系统中断信息来准确找出导致中断尖峰的原因。使用 watch -d 命令确定最常更改的中断。

    watch -d cat /proc/interrupts
    复制代码
    PHP并发性能调优实战 ,性能提升104%

    我们发现中断重调度变化最快,它是中断重调度(RES)。这种类型的中断意味着唤醒空闲的CPU来调度新的任务运行。这是调度程序用来将任务分配到多处理器 (SMP) 系统中的不同 CPU 的机制。通常也称为处理器间中断 (IPI)。通过结合 vmstat 命令,我们可以确定 qps 低的原因之一是太多进程竞争 CPU。我们还不确定它是什么,因此需要进一步调查。

    strace

    strace可以显示系统调用。我们知道,当使用系统调用时,系统就会陷入内核模式。这个过程会产生软中断。通过查看 php-fpm 系统调用,我们可以验证我们的假设。 PHP并发性能调优实战 ,性能提升104%

    果然发现大量统计系统调用。我们猜测这是由 opcache 检查文件是否过期引起的。我们修改了opcache配置,使opcache检查文件时间戳的频率降低,以减少这个问题。系统调用

        opcache.validate_timestamps="60"
        opcache.revalidate_freq="0"
    复制代码

    ,再次执行ab命令进行压测PHP并发性能调优实战 ,性能提升104%

    果然qps直接上升到205,提升非常明显,接近46%。改进

    perf

    仍然不满意。希望这次表演能够在更多的地方找到突破。通过系统分析报告

    perf record -g
    perf report -g
    复制代码

    PHP并发性能调优实战 ,性能提升104%

    我们看到似乎有太多与tcp建立相关的系统调用(我不知道这是不是具体的,请大神指正,但是当我看到 send, ip 时, tcp 等等,我怀疑这可能是 tcp/ip 相关的问题)。我们怀疑两种情况

    1. Mysql和redis重复建立大量TCP连接,消耗资源
    2. 大量请求造成的TCP连接

    先说第一种。经过检查发现数据库连接使用了php-fpm连接池,而redis连接没有。 Redis 使用 predis。这是纯PHP实现,性能不佳。高,改成phpredis:

    打开laravel的config/database.php文件,编辑redis驱动为phpredis,并确保本机安装了redis php扩展。另外,由于 Laravel 本身封装了 Redis 门面,并且 redis 正在发生,因此扩展带来的对象的 Name 也称为 Redis。因此,有必要将Laravel Redis Facade修改为不同的名称,例如RedisL5。

    再次跑了负载测试PHP并发性能调优实战 ,性能提升104%

    ,取得了令人满意的286qps,虽然和其他高性能框架或者原生PHP比,还是有很大的提升空间(比如Swoole),但是在最终实现了104%的提升,还是非常有意义的。利用CPU资源,我们发现系统的瓶颈来自于PHP。

    然后使用pidstat和vmstat我们发现压力测试的时候出现了很多系统中断并且watch -d cat /proc/interrupts发现主要中断来自于中断重新调度(RES )

    通过strace检查具体syscall,发现大量syscall来自stat。据推测,opcache 可能会频繁检查时间戳以确定文件更改。通过修改配置项,性能提升46%

    最后使用perf查看函数调用栈,分析发现大量的TCP连接redis可能造成了不必要的资源消耗。通过安装 redis 扩展并使用 phpredis 驱动 Laravel 的 redis 缓存,提高性能并获得另外近 50% 的性能提升。

    我们终于实现了 104% 性能提升的目标

    作者:wqj97
    来源:掘金

    版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    热门