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

长连接服务端主动断开连接的时候,客户端没有检测keep_liveness然后继续去请求了 #40

Closed
ihipop opened this issue May 6, 2019 · 2 comments
Labels
question Further information is requested

Comments

@ihipop
Copy link
Contributor

ihipop commented May 6, 2019

PHP Fatal error:  Uncaught Swlib\Http\Exception\ConnectException: Connection is forcibly cut off by the remote server in /home/ihipop/Dev/workspace/composer/saber/src/Request.php:641
Stack trace:
#0 /home/ihipop/Dev/workspace/composer/taobao-top/src/client/Adapter/SaberAdapter.php(39): Swlib\Saber\Request->recv()
#1 {main}
  thrown in /home/ihipop/Dev/workspace/composer/saber/src/Request.php on line 641

v1.0.6
use pool=>true

重现代码(平均250次请求左右可以重现):

<?php
\Swoole\Runtime::enableCoroutine();
require __DIR__ . '/vendor/autoload.php';
go(function () {
    $saber = Swlib\Saber::create([
        'use_pool'   => true,
        'keep_alive' => true,
    ]);
    $i     = 1;
    while (true) {
       try{
           //        $result = $saber->psr()->withMethod('GET')->withUri(new \Swlib\Http\Uri('http://gw.api.taobao.com/router/rest'))->exec()->recv();
           $result = $saber->get('http://gw.api.taobao.com/router/rest');

           echo $result->statusCode .'=>'.$i. "\n";
       }catch (\Throwable $e){
           echo $e->__toString();
           break;
       }finally{
           $i++;
       }

    }
    echo $i;
});
@ihipop
Copy link
Contributor Author

ihipop commented May 6, 2019

swoole/swoole-src#2184

@twose
Copy link
Member

twose commented May 13, 2019

最近太忙了没有及时回复
这个地方所有人都存在严重的误解...认为连接断开客户端能立即侦测到并且重连, 这是不可能的, 网络波动或是连接断开可能发生在任意时刻, 底层keep_liveness只是一个基本的保障, 保证在由于连接悬挂时间过长的情况下(超过keep-alive指定时间), 下一次请求能够不失败(屏蔽连接的概念, 和curl一样只管请求就可以了), 这里你的请求频次过高, 可能触发了服务器端的保护机制, 总之连接断开了, 并且由于请求速度过快, 在客户端keep_liveness检测的时候, 操作系统内核并没有收到对端close连接的挥手, 导致keep_liveness检查仍是成功的, 然后在收包等待过程中, 内核才发现连接断开, 导致recv返回连接断开信息, 此时该次请求是在半途失败的, 底层不便于重新发起请求, 应由开发者自行决定是否重新请求, 所以开发者必须自己捕获这样的错误, 重新调用get方法, 此时底层会自动重连(屏蔽了连接的概念, 和curl一样, 会返回错误, 但不用关心连接), 然后就会发现可以继续请求了

@twose twose added the question Further information is requested label May 13, 2019
@ihipop ihipop closed this as completed May 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants