Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在 Swoole\Coroutine\Http\Server 中的 http server 使用 sendfile 在高并发时会导致 PHP 假死并且内存泄露 #5329

Closed
Mxmilu666 opened this issue May 17, 2024 · 57 comments

Comments

@Mxmilu666
Copy link

Please answer these questions before submitting your issue.

  1. What did you do? If possible, provide a simple script for reproducing the error.
    我使用 Http\Server 搭建了一个简单的文件分发服务器,在大约2000连接数的时候PHP假死并且top显示php进程占用CPU100%

  2. What did you expect to see?
    在高并发环境下不会假死

  3. What did you see instead?
    在大约2000连接数的时候PHP假死并且top显示php进程占用CPU100%

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

php --ri swoole:

swoole
Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 5.1.2
Built => Apr 21 2024 15:24:12
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 3.0.11 19 Sep 2023
dtls => enabled
http2 => enabled
json => enabled
pcre => enabled
zlib => 1.2.13
brotli => E16777225/D16777225
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
You have new mail in /var/mail/root
  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

uname -a:

Linux root 6.1.0-11-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.38-4 (2023-08-08) x86_64 GNU/Linux

php -v:

PHP 8.2.17 (cli) (built: Mar 15 2024 10:31:18) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.17, Copyright (c) Zend Technologies

gcc -v:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 12.2.0-14' --with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-12-bTRWOB/gcc-12-12.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-bTRWOB/gcc-12-12.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (Debian 12.2.0-14) 

在假死后strace -p没有出现任何信息

我稍微长时间strace了一下php,需要可以提供假死前的记录

@NathanFreeman
Copy link
Member

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

@Mxmilu666
Copy link
Author

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

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

@NathanFreeman
Copy link
Member

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

<?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 查看当前进程

@Mxmilu666
Copy link
Author

$response->header('Content-Disposition', 'attachment; filename=recvfile.txt');

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

@NathanFreeman
Copy link
Member

strace -p看看进程在做什么

@NathanFreeman
Copy link
Member

你分发的文件有多大

@Mxmilu666
Copy link
Author

你分发的文件有多大

大概在50MB以内

@Mxmilu666
Copy link
Author

strace -p看看进程在做什么

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

@Mxmilu666
Copy link
Author

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

@Mxmilu666
Copy link
Author

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

@NathanFreeman
Copy link
Member

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

@NathanFreeman
Copy link
Member

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

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

@Mxmilu666
Copy link
Author

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

我尝试一下

@Mxmilu666
Copy link
Author

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

还是一样会假死

@NathanFreeman
Copy link
Member

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

@Mxmilu666
Copy link
Author

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

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

@NathanFreeman
Copy link
Member

php -m查看一下扩展列表

@NathanFreeman
Copy link
Member

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

@Mxmilu666
Copy link
Author

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

好的,我晚点再压测一下

@NathanFreeman
Copy link
Member

NathanFreeman commented May 22, 2024

@Mxmilu666 怎么样,可以吗

@Mxmilu666
Copy link
Author

@Mxmilu666 怎么样,可以吗

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

@Mxmilu666
Copy link
Author

@Mxmilu666 怎么样,可以吗

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

@NathanFreeman
Copy link
Member

可以设置1秒的时间间隔

@NathanFreeman
Copy link
Member

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

@Mxmilu666
Copy link
Author

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

好的,但是我用协程http server是因为我还要上报信息,外面还有逻辑,我再尝试一下吧

@Mxmilu666
Copy link
Author

Mxmilu666 commented May 25, 2024

@NathanFreeman 复现了,具体代码如下:

$server = new Server(0.0.0.0, 4000, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
        $server->set([
            'ssl_cert_file' => './cert/'.$this->cert,
            'ssl_key_file' => './cert/'.$this->key,
            'open_http2_protocol' => true,
        ]);
        $server->handle('/', function ($request, $response) {
            $code = 200;
            $response->header('Content-Type', 'application/octet-stream');
            $response->header('Content-Disposition', 'attachment; filename=test');
            $response->sendfile('./20');
            if(!isset($request->server['query_string'])){
                $url = $request->server['request_uri'];
            }
            else{
                $url = $request->server['request_uri']."?".$request->server['query_string'];
            }
            echo(" Serve {$code} | {$request->server['remote_addr']} | {$request->server['server_protocol']} | {$url} | {$request->header['user-agent']};") ;
        });
        echo("Start Http Server on {$this->host}:{$this->port}");
        $server->start();

这段代码为一个 class 在 Coroutine 中运行

压测命令

ab -c 10000 -n 200000 https://127.0.0.1:4000/

php几乎会占满系统的所有内存,看起来不像是php的内存管理机制

服务器配置12核6g

@Mxmilu666 Mxmilu666 changed the title 在 Http\Server 中使用 sendfile 在高并发时会导致 PHP 假死 在 Swoole\Coroutine\Http\Server 中的 http server 使用 sendfile 在高并发时会导致 PHP 假死并且内存泄露 May 25, 2024
@Mxmilu666
Copy link
Author

Mxmilu666 commented May 25, 2024

@NathanFreeman 复现了,具体代码如下:

$server = new Server(0.0.0.0, 4000, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
        $server->set([
            'ssl_cert_file' => './cert/'.$this->cert,
            'ssl_key_file' => './cert/'.$this->key,
            'open_http2_protocol' => true,
        ]);
        $server->handle('/', function ($request, $response) {
            $code = 200;
            $response->header('Content-Type', 'application/octet-stream');
            $response->header('Content-Disposition', 'attachment; filename=test');
            $response->sendfile('./20');
            if(!isset($request->server['query_string'])){
                $url = $request->server['request_uri'];
            }
            else{
                $url = $request->server['request_uri']."?".$request->server['query_string'];
            }
            echo(" Serve {$code} | {$request->server['remote_addr']} | {$request->server['server_protocol']} | {$url} | {$request->header['user-agent']};") ;
        });
        echo("Start Http Server on {$this->host}:{$this->port}");
        $server->start();

这段代码为一个 class 在 Coroutine 中运行

压测命令

ab -c 10000 -n 200000 https://127.0.0.1:4000/

php几乎会占满系统的所有内存,看起来不像是php的内存管理机制

服务器配置12核6g

附上 top 截图:
top

@NathanFreeman
Copy link
Member

有用到jemalloc吗

@NathanFreeman
Copy link
Member

你看看你的内存是否增长到一个固定的值就不再增长了。压测的时候传输的文件也会占用内存,调小一下文件的大小看看那会不会出现这个问题。试试用wrk压测看看

@Mxmilu666
Copy link
Author

@NathanFreeman
好像内存低的情况下也会假死?

image

如图 CPU100% 但是 php 已经停止运行了

@NathanFreeman
Copy link
Member

strace -p查看php进程阻塞在哪里

@Mxmilu666
Copy link
Author

我考虑用异步尝试一下了,话说有考虑在异步 http server 加入 handle 吗

@Mxmilu666
Copy link
Author

strace -p

image

无输出

@NathanFreeman
Copy link
Member

你PHP占用CPU100%是不是ab压测还没结束

@Mxmilu666
Copy link
Author

你PHP占用CPU100%是不是ab压测还没结束

这是正式环境,我没压测,正常跑就假死了

@Mxmilu666
Copy link
Author

Mxmilu666 commented May 25, 2024

你PHP占用CPU100%是不是ab压测还没结束

conntrack -C 如下
image

@NathanFreeman
Copy link
Member

还是要strace -p长时间执行看看php进程忙碌在哪一步

@Mxmilu666
Copy link
Author

还是要strace -p长时间执行看看php进程忙碌在哪一步

我 strace -p 一个小时试试

@NathanFreeman
Copy link
Member

或者perf top -g -p看看php执行最多的函数

@NathanFreeman
Copy link
Member

NathanFreeman commented May 25, 2024

或者pidstat -p 1 5看看是哪里的CPU用的多

@NathanFreeman
Copy link
Member

NathanFreeman commented May 25, 2024

#$server = new Server(0.0.0.0, 4000, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$server = new Server(0.0.0.0, 4000, true);

协程服务端构造函数这里有问题

@Mxmilu666
Copy link
Author

#$server = new Server(0.0.0.0, 4000, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$server = new Server(0.0.0.0, 4000, true);

协程服务端构造函数这里有问题

这个我早上排了,我改了还是一样的,现在的构造函数是:

        $this->server = $server = new Server($this->host, $this->port, true);
        $server->set([
            'ssl_cert_file' => './cert/'.$this->cert,
            'ssl_key_file' => './cert/'.$this->key,
            'heartbeat_check_interval' => 60,  // 表示每60秒遍历一次
        ]);

@NathanFreeman
Copy link
Member

array(
    'heartbeat_idle_time'      => 600, // 表示一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭
    'heartbeat_check_interval' => 60,  // 表示每60秒遍历一次
);

心跳加上heartbeat_idle_time试试

@Mxmilu666
Copy link
Author

perf top -g -p

image

@NathanFreeman
Copy link
Member

有个协程客户端在用recv接受数据,但是这个方法是升级成websocket协议才有用。
https://wiki.swoole.com/zh-cn/#/coroutine_client/http_client?id=recv

@Mxmilu666
Copy link
Author

有个协程客户端在用recv接受数据,但是这个方法是升级成websocket协议才有用。
https://wiki.swoole.com/zh-cn/#/coroutine_client/http_client?id=recv

这是 websocket 服务,用来上报数据的,但是明明已经升级了?

@Mxmilu666
Copy link
Author

有个协程客户端在用recv接受数据,但是这个方法是升级成websocket协议才有用。
https://wiki.swoole.com/zh-cn/#/coroutine_client/http_client?id=recv

我再看看

@NathanFreeman
Copy link
Member

看一下协程客户端返回的错误码吧

@NathanFreeman
Copy link
Member

你也可以按一下向下的方向键,回车看看第一个函数的父函数是谁

@Mxmilu666
Copy link
Author

你也可以按一下向下的方向键,回车看看第一个函数的父函数是谁

好的,等问题再次出现我再试试,麻烦了

@NathanFreeman
Copy link
Member

你的代码是怎么使用协程客户端的

@NathanFreeman
Copy link
Member

你现在CPU100%,可以用perf top -g -p采样看看进程在做什么

@Mxmilu666
Copy link
Author

你的代码是怎么使用协程客户端的

我是用协程客户端的 ws 造了一个 socket.io 的轮子来连接主控
可能是哪里写的有问题,我再去看看

@Mxmilu666
Copy link
Author

你现在CPU100%,可以用perf top -g -p采样看看进程在做什么

目前还没有假死,等假死了我再看看

@NathanFreeman
Copy link
Member

@Mxmilu666 怎么样,可以了吗

@Mxmilu666
Copy link
Author

解决了,因为我使用了 while(true) 来获取recv() 当外部 close 时会导致还在循环 recv() 导致无限重连

@Mxmilu666
Copy link
Author

感谢大佬耐心解答我的问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants