GithubHelp home page GithubHelp logo

在 Swoole\Coroutine\Http\Server 中的 http server 使用 sendfile 在高并发时会导致 PHP 假死并且内存泄露 about swoole-src HOT 57 OPEN

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024
在 Swoole\Coroutine\Http\Server 中的 http server 使用 sendfile 在高并发时会导致 PHP 假死并且内存泄露

from swoole-src.

Comments (57)

NathanFreeman avatar NathanFreeman commented on July 18, 2024

ulimit -n查看一下文件符数量

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

ulimit -n查看一下文件符数量

是 65536 之前排查的时候特意改了,但是还是没有用处

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

我没法复现这个问题,麻烦提供一份可复现的代码

<?php

$http = new Swoole\Http\Server('127.0.0.1', 9501);

$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) use ($http) {
        $response->header('Content-Type', 'application/octet-stream');
        $response->header('Content-Disposition', 'attachment; filename=recvfile.txt');
        $response->sendfile('/home/output.txt');
});

$http->start();

也可以strace -p 查看当前进程

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024
$response->header('Content-Disposition', 'attachment; filename=recvfile.txt');

因为现在是生产环境,只能快速重启解决,我尝试在 staging 复现一下吧

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

strace -p看看进程在做什么

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

你分发的文件有多大

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

你分发的文件有多大

大概在50MB以内

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

strace -p看看进程在做什么

是在正常运行的时候吗?那我直接从生产环境里面截取一部分好了

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

strace -p看看进程在做什么

这是假死前的 strace 记录,看看有没有帮助

read(61, 0x7f6467cdf0d3, 16709)         = -1 EAGAIN (Resource temporarily unavailable)
munmap(0x7f6467cdf000, 57344)           = 0
access("./cache/5d/5dd32ce63e2ff412c0c1009255e944fae80b03b0", F_OK) = 0
stat("./cache/5d/5dd32ce63e2ff412c0c1009255e944fae80b03b0", {st_mode=S_IFREG|0777, st_size=18069569, ...}) = 0
stat("./cache/5d/5dd32ce63e2ff412c0c1009255e944fae80b03b0", {st_mode=S_IFREG|0777, st_size=18069569, ...}) = 0
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6467cdf000
write(61, "\27\3\3\0\377\251N\270\361Q7^\364\277\v\372s\0\f\240\331s\232\2638\341T\26\331k\305;"..., 260) = 260
munmap(0x7f6467cdf000, 57344)           = 0
open("./cache/5d/5dd32ce63e2ff412c0c1009255e944fae80b03b0", O_RDONLY|O_LARGEFILE) = 86
pread64(86, "\355&+zd\4s\25$2\2\232W\251Y\335_\357\353^\265\337h\235Rd\217\366R\2656\301"..., 65536, 14570840) = 65536
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6467cdf000
write(61, "\27\3\3@\30\251N\270\361Q7^\365\320\16\270S\231(\210xU\356\377\r\"\275\3025?\220\235"..., 16413) = 16413
munmap(0x7f6467cdf000, 57344)           = 0
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6467cdf000
write(61, "\27\3\3@\30\251N\270\361Q7^\366\316\335L\323\337\272\227F\212#\305\353B?\377_\233\273B"..., 16413) = 16413
munmap(0x7f6467cdf000, 57344)           = 0
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6467cdf000
write(61, "\27\3\3@\30\251N\270\361Q7^\367\367i\376?\374\334\277\ns*9\375\210\247\303p\f0\256"..., 16413) = 16413
munmap(0x7f6467cdf000, 57344)           = 0
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6467cdf000
write(61, "\27\3\3@\30\251N\270\361Q7^\370\360\345\222W\227\327ov\376\307\254&\241\306\377\371\21\260\353"..., 16413) = 16413
munmap(0x7f6467cdf000, 57344)           = 0
pread64(86, "\215\377\25AO\261\317\371\360\344!\377\340Y\252\321\256\205\303\235\3777\233\0276\37\240\202\373j8\203"..., 65536, 14636376) = 65536
mmap(NULL, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6467cdf000
write(61, "\27\3\3@\30\251N\270\361Q7^\371S\315\325\335Q\32\356\2\340\317x\346\30\5-\231\20\241O"..., 16413) = 4348
write(61, "\275:\215\305\26\275\36690\376\367~-\330\234\215T\356\303\224\364l\27<\247L\270\276\320\221\210:"..., 12065) = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(7, EPOLL_CTL_ADD, 61, {events=EPOLLOUT, data={u32=1751122224, u64=140069224579376}}) = 0
epoll_pwait(7, [{events=EPOLLIN, data={u32=1748838112, u64=140069222295264}}], 4096, 582, NULL, 8) = 1
epoll_ctl(7, EPOLL_CTL_DEL, 46, NULL)   = 0
read(46, "\27\3\3\1\27\0\0\0\0\0\0\0\5\355\270\6\1\20S\303<G\273\207}\302\321.\333\354\332&"..., 16709) = 284
read(46, 0x7f6467ce3a53, 16709)         = -1 EAGAIN (Resource temporarily unavailable)
access("./cache/06/067fbe48fa274cd3c3e4066bfdee2841f095defb", F_OK) = 0
stat("./cache/06/067fbe48fa274cd3c3e4066bfdee2841f095defb", {st_mode=S_IFREG|0777, st_size=55826, ...}) = 0
stat("./cache/06/067fbe48fa274cd3c3e4066bfdee2841f095defb", {st_mode=S_IFREG|0777, st_size=55826, ...}) = 0
write(46, "\27\3\3\0\375\213\334\244\337M\245M\210\337\305\272\353\350C;\367J\364\n\375\262T\206\331\337\250l"..., 258) = 258
open("./cache/06/067fbe48fa274cd3c3e4066bfdee2841f095defb", O_RDONLY|O_LARGEFILE) = 87
pread64(87, "OggS\0\2\0\0\0\0\0\0\0\0\331&\377\0\0\0\0\0\20\220\303E\1\36\1vor"..., 55826, 0) = 55826
write(46, "\27\3\3@\30\213\334\244\337M\245M\211\323[\235\20\320\26MF\1\370*8\276\25\345\316\314\276}"..., 16413) = 16413
write(46, "\27\3\3@\30\213\334\244\337M\245M\212\226\263\240\320\223-\337\356\263r\362\325/\344\265xy\202\240"..., 16413) = 16413
write(46, "\27\3\3@\30\213\334\244\337M\245M\213.\304:m\225\216\307\337\31\353\236\332\264\265A6\211c\223"..., 16413) = 16413
write(46, "\27\3\3\32*\213\334\244\337M\245M\214\371\22\265\274\314\352\220#\0\345\222\375\226f\257\263\361\36\270"..., 6703) = 6703
close(87)                               = 0
write(1, "[2024.5.15-03:03:25][INFO] Serve"..., 219) = 219
read(46, 0x7f6467ce3ab3, 16709)         = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(7, EPOLL_CTL_ADD, 46, {events=EPOLLIN, data={u32=1748838112, u64=140069222295264}}) = 0
epoll_pwait(7, [{events=EPOLLOUT, data={u32=1751126832, u64=140069224583984}}], 4096, 485, NULL, 8) = 1
epoll_ctl(7, EPOLL_CTL_DEL, 80, NULL)   = 0
pread64(47, "F\263l3):Zp(\267\34\370(\234\6\2OggS\0\0@\207\213\0\0\0\0\0\256\346"..., 65536, 2097152) = 65536
write(80, "\332p\227\346\377\277\241}\360\307\10}Z\274\344{E\255wQ\271\235,\364[\5\16s^!x("..., 10996) = 10996
pread64(47, "\263\322\317\335\270\335\353t%\200\347X\207{\3629\237\177\256\373\\\263c\7:-?\225|\274?W"..., 65536, 2162688) = 65536
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\23.\231Wlm\24\242\243)[\21\4\341\262\257\347\206\325\31"..., 16413) = 16413
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\24Ryw\26Y\376\311\3041\225\263*\231\221\321\340\303\34-"..., 16413) = 16413
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\25\267\0263\374A\343\350I{n\31\225\230(\23\272\311O\366"..., 16413) = 16413
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\26\t%b\241\237\344\303\272b\270\236,X\27{T-\260C"..., 16413) = 16413
pread64(47, "\27v\375\260\336\34.\354gv\340;\374\233\374\335\275\34\234g\226=F{\234\206#E\357\367\362\367"..., 65536, 2228224) = 65536
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\27\246(\304\246\206\355\221\372\206\224\330\27\205W\2\201<\34E"..., 16413) = 16413
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\30L\272V\357C\27\255\35\247B\245\261W`\276\37\314\21O"..., 16413) = 16413
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\31\225\n\237\344h45\320\320\251\234\372\327\317r\352\265\35\340"..., 16413) = 16413
write(80, "\27\3\3@\30\216\263\260\367\227\343\300\32=:\30\343\253\202\271\227\233\22\27q8\10\256'\265K#"..., 16413) = 3137
write(80, "h\24\267\336Z\305}\341VZ\247\302\341Gv\2235\253h\35g\17\363\215L\257\342RL\203v\345"..., 13276) = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(7, EPOLL_CTL_ADD, 80, {events=EPOLLOUT, data={u32=1751126832, u64=140069224583984}}) = 0
epoll_pwait(7, [{events=EPOLLIN, data={u32=1751581216, u64=140069225038368}}], 4096, 470, NULL, 8) = 1
epoll_ctl(7, EPOLL_CTL_DEL, 9, NULL)    = 0
read(9, "\27\3\3\0\23Yl\26Z0\327\365\230e\251\243<\340g{_`\20o", 16709) = 24
shutdown(9, SHUT_RDWR)                  = 0
munmap(0x7f6468f62000, 4096)            = 0

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

另外还有一点就是假死的时候PHP内存占用大约为1G,在使用ab 2000并发 sendfile20mb文件 压测确实会达到如此内存,不知道是否是内存的问题

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

试试根据文档开启心跳检测
https://wiki.swoole.com/zh-cn/#/server/setting?id=heartbeat_check_interval

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

另外还有一点就是假死的时候PHP内存占用大约为1G,在使用ab 2000并发 sendfile20mb文件 压测确实会达到如此内存,不知道是否是内存的问题

可能是客户端没关闭连接,这些连接占用了内存了吧

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

试试根据文档开启心跳检测 https://wiki.swoole.com/zh-cn/#/server/setting?id=heartbeat_check_interval

我尝试一下

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

试试根据文档开启心跳检测
https://wiki.swoole.com/zh-cn/#/server/setting?id=heartbeat_check_interval

还是一样会假死

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

你这边看看能不能提供一个可复现的代码,我这边看看

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

你这边看看能不能提供一个可复现的代码,我这边看看

我尝试复现一下,主要是只有生产环境才会,我自己可能没办法复现

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

php -m查看一下扩展列表

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

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

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

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

好的,我晚点再压测一下

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

@Mxmilu666 怎么样,可以吗

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

@Mxmilu666 怎么样,可以吗

依然还会,我在实际测试一下

from swoole-src.

Mxmilu666 avatar Mxmilu666 commented on July 18, 2024

@Mxmilu666 怎么样,可以吗

Swoole\Timer::tick 设置了60秒
我晚点再设置短一点看看

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

可以设置1秒的时间间隔

from swoole-src.

NathanFreeman avatar NathanFreeman commented on July 18, 2024

@Mxmilu666 怎么样,如果还是不行的话试试异步http server

from swoole-src.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.