swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.47k stars 3.16k forks source link

🪶 在 C++ 中,有提供了Socket sendfile的方法(zerocopy),可以不通过CPU去调度资源,避免重复拷贝两次DMZ(或者更多) #5330

Closed tianxiu2b2t closed 2 months ago

tianxiu2b2t commented 6 months ago

Please answer these questions before submitting your issue.

  1. What did you do? If possible, provide a simple script for reproducing the error. 发送文件时候会使内存升高,没有关闭的现状

  2. What did you expect to see? 假死,内存溢出

  3. What did you see instead? 修复正确关闭流文件或者是Socket

  4. What version of Swoole are you using (show your php --ri swoole)? 最新

  5. What is your machine environment used (show your uname -a & php -v & gcc -v) ? 最新

NathanFreeman commented 6 months ago

你用的是httpserver还是tcpserver

tianxiu2b2t commented 6 months ago

http基于TCP的,理论上支持

NathanFreeman commented 6 months ago

你是压测的过程中发现假死的吗,可以的话提供一下复现代码和压测命令

tianxiu2b2t commented 6 months ago

我只能提供文件数量和大小,压测命令我暂时没有,但可以提供数据

tianxiu2b2t commented 6 months ago

五分钟QPS:13570 文件数量:124k 大小:125G 最大文件大小:100MB左右 最小文件:64b或者是0b

NathanFreeman commented 6 months ago

你是用Swoole\Http\Response::end还是Swoole\Http\Response::sendfile方法发送文件

tianxiu2b2t commented 6 months ago

只有sendfile,没有end

NathanFreeman commented 6 months ago
<?php
$http = new Swoole\Http\Server('127.0.0.1', 9501, SWOOLE_PROCESS);

$http->on('start', function ($server) {
    echo "Swoole http server is started at http://127.0.0.1:9501\n";
});

$http->on('request', function ($request, $response) {
    $response->header('Content-Type', 'application/octet-stream');
    $response->header('Content-Disposition', 'attachment; filename=recvfile.txt');
    $response->sendfile('/home/sendfile.txt');
});

$http->start();

传输文件是100M的,wrk -c20000 -t4 -d120s http://127.0.0.1:9501/ 压测命令

你的服务器环境是怎么样的,代码是我这样的写法吗

NathanFreeman commented 6 months ago

php -m查看一下扩展列表,php --ri swoole查看一下swoole信息

tianxiu2b2t commented 6 months ago

服务器环境:4h8g,php占用6g php -m zstd拓展,swoole是最新版本的

tianxiu2b2t commented 6 months ago

另外,是Swoole\Coroutine\Http\Server

NathanFreeman commented 6 months ago

有内存泄漏,我看看是哪里的问题

tianxiu2b2t commented 6 months ago

我怀疑是客户端正确关闭后,没有自动释放,导致有引用计数不能为0的情况 可以看看是否客户端关闭没有通知response关闭?

tianxiu2b2t commented 6 months ago

因为连接数导致内存上涨和没有正确释放等问题

NathanFreeman commented 6 months ago

我测试了一下,这个应该不是内存泄漏,更有可能是因为php的内存管理机制会将小的内存块保留起来不还给操作系统。 使用Swoole\Timer::tick设置合适的时间间隔调用gc_mem_caches()强制php归还内存给操作系统试试看。