在使用特定设备访问接口的情况下,swoole服务会卡住,不再接收其它接口的访问请求
zhan3333 opened this issue · comments
一句话描述
- 在使用
hprose-swoole 2.0.7
搭建服务,用户使用iphone 6s QQ浏览器访问服务发布的接口时,接口会停止服务,其它任何方式的访问接口都无返回值,重启服务后恢复正常。 - 对于这个问题,我目前的解决办法是使用
hprose 1.5.6
版本。 - 希望确认问题后与我联系,这个bug稳定重现。
bug重现环境
bug出现环境:
- 服务端
- 使用库:hprose-swoole: 2.0.7/2.0.11
- 客户端
- 操作系统: apple 6s
- 浏览器:qq浏览器 7.0.0.2825
- 操作
- 使用上述客户端,通过hprose-html5访问接口,处理该次请求的服务器进程即拒绝包含这次服务的以后所有服务,只有通过重启服务解决。
异常数据头信息
{
"host":"192.168.2.67:8003",
"origin":"http://192.168.2.102:8080",
"accept-encoding":"gzip, deflate",
"connection":"keep-alive",
"accept":"*/*",
"user-agent":"Mozilla/5.0 (iPhone 6sp; CPU iPhone OS 10_1_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0 MQQBrowser/7.2 Mobile/14B100 Safari/8536.25 MttCustomUA/2 QBWebViewType/1",
"content-length":"0",
"referer":"http://192.168.2.102:8080/hprose-web/index.html?_ijt=g21st5f9d04he2p1dd96tbhgoh",
"accept-language":"zh-cn"
}
测试
测试目标
- 使用
hprose-swoole
库的不同版本 - 使用
hprose
库的不同版本 - 使用不同浏览器
- 使用不同操作系统
- 使用不同方式访问:
hprose
和http
- 模拟异常数据头信息进行访问
测试结果
- 使用
hprose-swoole
在2.0.7与2.0.11两个版本中,使用apple 6s qq浏览器
通过hprose
访问,将出现这个问题。其中2.0.11
为最新版本。 - 使用
hprose
版本为1.5.6
时,任意浏览器或访问方式均访问正常。1.5.6
为1.*.*
最后一个版本。其中1.*.*
自带swoole服务的创建,而到了2.*.*
时,不带swoole服务的创建,已经转向了hprose-swoole
库中。 - 使用
arc
工具模拟异常包的头信息发送,bug未重现。 - 在
红米note3上的qq浏览器
,使用hprose
访问接口,bug未出现。 - 使用
apple 6s qq浏览器
通过http
访问接口,无bug出现。 - 在服务器获取到异常包时,手动
unset
掉content-length
头信息,无效果。
重现方式
- 服务端使用下面测试代码中的
hprose-swoole-2.0.11
代码 - web端使用下面的
web端代码
代码 - 使用
apple 6s qq浏览器
访问web端页面,此时bug重现。
结论
- 这是存在于
hprose-swoole
库中的一个bug。 - 目前只发现在使用
iphone 6s qq浏览器
通过hprose
方式访问hprose-swoole
的服务时,会出现此bug。 - 因为发现异常包与正常包之间,差别在于:只存在于异常包的
content-length: 0
,故临时解决办法,在服务器获取到content-length: 0
的包时,不做处理直接return。 - 长远解决办法
- 提交bug到
hprose-swoole
的git issues中,等待bug确认并修复。 hprose-swoole
库更换为1.5.6
版本的hprose
库
- 提交bug到
附测试代码
web端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script type="text/javascript" src="hprose/hprose-html5.src.js"></script>
<script src="//cdn.jsdelivr.net/eruda/1.0.5/eruda.min.js"></script>
<script>eruda.init();</script>
</head>
<body>
<div id="retData"></div>
<script type="text/javascript">
var retData = document.getElementById('retData')
var url = 'http://192.168.2.67:8089' // 服务地址
var client = hprose.Client.create(url)
// 访问服务
client.invoke('hello', [], function (data) {
console.info('success', data)
retData.textContent = data
},function (error) {
console.info('error', error)
retData.textContent = error
})
</script>
</body>
</html>
hprose-swoole-2.0.11 代码
composer.json
{
"require": {
"hprose/hprose-swoole": "2.0.11"
}
}
SwooleServer.php
<?php
require_once "./vendor/autoload.php";
use Hprose\Swoole\Server;
function hello($name) {
return "Hello $name!";
}
$url = "http://0.0.0.0:8089";
echo "url is $url" . PHP_EOL;
$server = new Server($url);
$server->addFunction('hello');
$server->start();
hprose-swoole-2.0.7 代码
composer.json
{
"require": {
"hprose/hprose-swoole": "2.0.7"
}
}
SwooleServer
<?php
require_once "./vendor/autoload.php";
use Hprose\Swoole\Server;
function hello($name) {
return "Hello $name!";
}
$url = "http://0.0.0.0:8086";
echo "url is $url" . PHP_EOL;
$server = new Server("http://0.0.0.0:8086");
$server->addFunction('hello');
$server->start();
hprose-1.5.6
composer.json
{
"require": {
"hprose/hprose": "1.5.6"
}
}
SwooleServer.json
<?php
require_once "./vendor/autoload.php";
use Hprose\Swoole\Server;
function hello($name) {
return 'Hello ' . $name;
}
$url = "http://0.0.0.0:8087";
echo "url is $url" . PHP_EOL;
$server = new Hprose\Swoole\Server($url);
$server->addFunction('hello');
$server->start();
使用 hprose 1.5.6 时,使用的 swoole 扩展是哪个版本的?跟使用 hprose-swoole 2.0.x 时使用的 swoole 扩展是否是相同版本?我看代码中,1.5.6 和 2.0.x 中获取请求都是使用的 $request->rawContent();
并没有发现在获取请求数据时,有什么不同之处。
1.5.6与2.0.*版本均使用swoole 1.8.9版本。以上测试中,只更改了库的版本,并没有更换测试环境其他东西。
如果仅仅是头部异常会触发这个问题的话,那应该模拟异常包的头信息发送时也会导致 bug 重现才对,但是看你的描述,貌似只有用 apple 6s + 7.0.0.2825 QQ 浏览器才会重写该 bug,这种情况下,我没办法定位 bug 的位置啊。
对,特定设备与浏览器下才会重现这个bug,所以我定位不到,只能根据头信息的差别来去掉异常访问。是异常访问->差别头信息,而不是差别头信息->bug。重现方式已经提供了,也就是在其它任何使用了高版本的hprose-swoole
服务中,能够有稳定的办法中止掉服务。这个bug是必须解决。