php-fpm版本:7.4 nginx版本:1.19.0
我们在 gke、kubernetes 上运行;我们的节点有 10 个 CPU 和 24G 内存,我们向运行 Laravel 堆栈(nginx + php-fpm)的 pod 请求 2 个 CPU(限制为 3 个)。这两个服务共享一个 pod,但是是单独的容器(一个用于 nginx,一个用于 php)。它们共享一个 pod 的原因是,从单独的 pod 进行 php -> nginx 通信会堵塞我们的网络(我们过去在单独的服务/部署中运行 nginx/php)
此外,nginx 和 php 通过以卷形式共享的共享文件共享连接:e
- name: php-socket
emptyDir: {}
volumeMounts:
- name: php-socket
mountPath: /sock
这似乎比 pod 内的本地网络连接更好,我们相信这是最佳实践。
但这让我想到了一个问题:为什么这个特定的请求这么慢?我知道数据量很大,但事实并非如此大数据。我认为未压缩时大小为 3MB,但经过 gzip 压缩后大小为 <1MB:
但它需要很长时间,超过了我们原来的 30 秒超时。
我们知道,导出 3000 名用户一年的数据对于我们的数据库来说会很繁重,所以我们将此响应缓存在 Redis 中。查看 PHP 日志,我们访问缓存并在不到 1/4 秒的时间内开始返回响应。
php -> nginx -> 客户端之间的某个地方花费的时间太长了。
起初我以为是因为我们正在对大量数据进行 gzip 压缩;禁用 gzip 并没有帮助。我甚至认为这可能是 nginx 必须进行的文件缓冲,所以我将节点磁盘从 100GB 升级到 200GB,甚至从 HDD 升级到 SSD。这并没有帮助。我们甚至反复了解到,在配置方面,我们经常处于边缘情况,所以我尝试将 fastcgi_buffers、proxy_buffers 和 gzip_buffers 设置为极高的内存值:
keepalive_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_connect_timeout 120;
# Try higher buffer size for large assesment loading
fastcgi_buffering on;
fastcgi_buffers 50000 4k;
fastcgi_busy_buffers_size 4098k;
client_max_body_size 128M;
client_body_buffer_size 45M;
client_header_buffer_size 16k;
large_client_header_buffers 32 4k;
proxy_buffers 50000 4k;
proxy_buffer_size 4098k;
proxy_busy_buffers_size 4098k;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 50000 4k;
gzip_http_version 1.1;
gzip_min_length 64;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
但这似乎也没有什么帮助。
PHP 慢速日志:
[08-Jul-2021 18:09:48] [pool www] pid 120 - -
Jul 8, 2021 @ 11:09:48.478 script_filename = /var/www/public/index.php - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81baf0] runQueryCallback() /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:629 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b9b0] run() /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:338 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b910] select() /var/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2159 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b860] runSelect() /var/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2147 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b760] Illuminate\Database\Query\{closure}() /var/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2619 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b660] onceWithColumns() /var/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2148 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b540] get() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:546 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b3c0] getModels() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:530 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b240] get() /var/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php:143 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b1b0] first() /var/www/app/Models/User.php:232 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81b070] getAccountAttribute() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:454 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81afc0] mutateAttribute() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:350 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81ae90] getAttributeValue() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:323 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81ada0] getAttribute() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1550 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81acb0] offsetExists() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1595 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81ac40] __isset() unknown:0 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fff466902c0] ???() /var/www/app/Models/User.php:236 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81abb0] getAccountTypeAttribute() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:454 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81ab00] mutateAttribute() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:466 - -
Jul 8, 2021 @ 11:09:48.478 [0x00007fe3cc81aa40] mutateAttributeForArray() /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:111 - -
Jul 8, 2021 @ 11:09:48.478 [08-Jul-2021 18:09:48] NOTICE: finished trace of 120 - -
Jul 8, 2021 @ 11:09:48.477 [08-Jul-2021 18:09:48] WARNING: [pool www] child 120, script '/var/www/public/index.php' (request: "GET /index.php?clientTimezone=America%2FLos_Angeles") executing too slow (6.203325 sec), logging - -
Jul 8, 2021 @ 11:09:48.477 [08-Jul-2021 18:09:48] NOTICE: child 120 stopped for tracing - -
Jul 8, 2021 @ 11:09:48.477 [08-Jul-2021 18:09:48] NOTICE: about to trace 120
有人还有其他想法吗?
答案1
一旦被告知使用 php slow_log 函数,我就能发现我意外地访问了数据库,因为我使用的是缓存响应。在返回语句的最终 json 序列化之后,更多的数据被急切加载