zsxsoft/danmu-server

C stack trace issue

Closed this issue · 27 comments

Dear zsx,

这几天都在测试长时间发弹幕和长时间不发弹幕的情况下server端的情况,经过这几天的测试和观察我发现2个问题:

1、当长时间不发弹幕时,会跟踪到server端报错并停止服务,以下是抓取到的报错信息:
==== C stack trace ===============================

1: V8_Fatal
2: ??
3: v8::internal::IncrementalMarking::OldSpaceStep(long)
4: v8::internal::FreeList::Allocate(int)
5: v8::internal::PagedSpace::AllocateRaw(int)
6: v8::internal::Heap::AllocateRaw(int, v8::internal::AllocationSpace, v8::internal::AllocationSpace)
7: v8::internal::Heap::Allocate(v8::internal::Map_, v8::internal::AllocationSpace, v8::internal::AllocationSite_)
8: v8::internal::Heap::AllocateStruct(v8::internal::InstanceType)
9: v8::internal::Factory::NewStruct(v8::internal::InstanceType)
10: v8::internal::Factory::NewCodeCache()
11: v8::internal::Map::UpdateCodeCache(v8::internal::Handlev8::internal::Map, v8::internal::Handlev8::internal::Name, v8::internal::Handlev8::internal::Code)
12: v8::internal::PropertyICCompiler::ComputeKeyedLoadMonomorphic(v8::internal::Handlev8::internal::Map)
13: v8::internal::KeyedLoadIC::LoadElementStub(v8::internal::Handlev8::internal::JSObject)
14: v8::internal::KeyedLoadIC::Load(v8::internal::Handlev8::internal::Object, v8::internal::Handlev8::internal::Object)
15: v8::internal::KeyedLoadIC_Miss(int, v8::internal::Object*, v8::internal::Isolate)
16: ??
Illegal instruction

npm ERR! Linux 3.2.0-29-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.7
npm ERR! npm v2.11.3
npm ERR! code ELIFECYCLE
npm ERR! danmu-server@0.0.1 start: node app.js
npm ERR! Exit status 132
npm ERR!
npm ERR! Failed at the danmu-server@0.0.1 start script 'node app.js'.
npm ERR! This is most likely a problem with the danmu-server package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node app.js
npm ERR! You can get their info via:
npm ERR! npm owner ls danmu-server
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /var/www/tom/tom_danmu2/npm-debug.log
^C

2、当长时间不发弹幕时,发现过一次报错内存不够并停止服务。

以下是我的服务端配置,不知是否是我的配置不对导致的呢?
我配置了2个room,禁用了memcache并注释了autoban。
module.exports = {
"rooms": {
"default": {
...
},
"testdanmu": {
...
}
},
"database": {
"type": "mysql", // 数据库类型
"server": "127.0.0.1", // 数据库地址
"username": "root", // 数据库用户名
"password": "...", // 数据库密码
"port": "3306", // 数据库端口
"db": "...", // 数据库
"retry": 10, // 24小时允许断线重连最大次数,超过则自动退出程序。24小时以第一次断线时间计。
"timeout": 1000 // 数据库重连延时及Ping
},
"websocket": {
"interval": 4000, // 弹幕发送间隔
"singlesize": 1 // 每次弹幕发送数量
},
"http": {
"port": 3007, // 服务器端口
"headers": { // HTTP头
//"Access-Control-Allow-Origin": "",
//"Access-Control-Allow-Methods": "POST"
},
"sessionKey": "hey"
},
"cache": {
"type": "none", // 缓存类型,支持memcached和aliyun。后者需要npm install aliyun-sdk
//"host" : "192.168.140.129:11211", // 缓存服务器地址,可用socket
"host" : "", // 缓存服务器地址,可用socket
"auth": false, // 是否打开身份验证
"authUser": "", // 身份验证账号
"authPassword": "" // 身份验证密码
},
"ext": {
/

"weibo": {
"clientID": '', // App ID
"clientSecret": '', // App Secret
"callbackURL": 'http://test.zsxsoft.com:3000/auth/sina/callback', // 这里填写的是 网站地址/auth/sina/callback
"requireState": true // 是否打开CSRF防御
},
/
//禁用memcache时需同时禁用autoban
/

"autoban": {
"block": 3, // 被拦截超过一定数字自动封号

    }
    */
}

}

issue里面提交我的server配置信息显示起来有点问题,我把显示不好的地方截图得了:

tempissue1

长时间是多长?
出错的时候,运行跨天了吗?跨小时了吗?大概从什么时候到什么时候出错的?

升级到node 4.0试试看,v8报的错我真没见过,感觉像是socket.io那里的问题(唯一一个有用C++的库)

内存方面,可能是我的代码存在内存泄漏,也可能是express等组件的泄漏,有点难查。

另外,用pm2可以管理服务端程序,你可以试试

又花了不少时间进行观察,同样的还是发生了C stack trace issue和内存不够的问题(发生的具体时间不详,没法跟踪发生错误的时间。。。)。

内存不够的问题的报错信息是这样的:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Aborted

npm ERR! Linux 3.2.0-29-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.7
npm ERR! npm v2.11.3
npm ERR! code ELIFECYCLE
npm ERR! danmu-server@0.0.1 start: node app.js
npm ERR! Exit status 134
npm ERR!
npm ERR! Failed at the danmu-server@0.0.1 start script 'node app.js'.
npm ERR! This is most likely a problem with the danmu-server package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node app.js
npm ERR! You can get their info via:
npm ERR! npm owner ls danmu-server
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /var/www/tom/tom_danmu2/npm-debug.log

我观察到报错的情况出现都是在关闭了客户端的情况下发生的,如果客户端一直开着貌似不会发生这2个问题(是不是因为client一直有心跳从而使server端保持正常的?),所以问题貌似出现在客户端长时间跟server没有联系的时候,具体多久会发生不明确,估计有几个小时吧。

你要我升级到node 4.0,我根本没概念呢,不知道怎么弄。。。
pm2的使用也不会呢,以后看有没有空学习一下。目前我能做的也就是改下配置和前端的简单修改。

你看我能把package.json里面的一些没啥用的配置或dependencies给去掉再观察一下吗?我这边只需要基本的调用server接口功能发弹幕就行了,应该是不需要express或sina的什么功能的吧,但我不知道有哪些配置是可以去掉并支持基本弹幕功能的。。。

能抽空指导一下吗?

谢谢

Node 4.0只要覆盖掉原来的安装即可,不知道你原来是怎么安装的,是apt-get或yum的话就卸载后用官网的包重装吧,解压到/usr目录即可。

pm2只要npm install pm2 -g就好了,帮助很好找。

dependencies不能删除,ext里面可以全部注释。express是创建Web服务器用的。

严重怀疑是内存回收方面问题,可能是socket.io库导致的。这周六我尝试复现一下,顺便查一下那个库的issue。

也劳烦把整个npm-debug.log发给我下,谢谢。

Dear zsx,

以下是npm-debug.log中的内容:
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ]
2 info using npm@2.11.3
3 info using node@v0.12.7
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info prestart danmu-server@0.0.1
6 info start danmu-server@0.0.1
7 verbose unsafe-perm in lifecycle true
8 info danmu-server@0.0.1 Failed to exec start script
9 verbose stack Error: danmu-server@0.0.1 start: node app.js
9 verbose stack Exit status 1
9 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16)
9 verbose stack at EventEmitter.emit (events.js:110:17)
9 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:24:14)
9 verbose stack at ChildProcess.emit (events.js:110:17)
9 verbose stack at maybeClose (child_process.js:1015:16)
9 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5)
10 verbose pkgid danmu-server@0.0.1
11 verbose cwd /var/www/tom/tom_danmu2
12 error Linux 3.2.0-29-generic
13 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
14 error node v0.12.7
15 error npm v2.11.3
16 error code ELIFECYCLE
17 error danmu-server@0.0.1 start: node app.js
17 error Exit status 1
18 error Failed at the danmu-server@0.0.1 start script 'node app.js'.
18 error This is most likely a problem with the danmu-server package,
18 error not with npm itself.
18 error Tell the author that this fails on your system:
18 error node app.js
18 error You can get their info via:
18 error npm owner ls danmu-server
18 error There is likely additional logging output above.
19 verbose exit [ 1, true ]

昨晚7点到今早8点一直把客户端开着,但是没发弹幕,早上起来看了一下,发现报错内存不够。

忘记说了,我这边在config里面配置了2个房间,目前都是往第2个房间在发弹幕。

第一个问题,疑似Node的问题。我Google了一下错误信息,https://github.com/nodejs/node-v0.x-archive/issues/25480。 换Node 4.0再看看可能真的比较合适。

第二个问题,目前正在测试。上了1W条弹幕上了五次,结束后内存占用均回到正常水平。正在进行长时间待机测试。
测试环境:
qq 20150919141115

第二个问题测试完毕。初步定位问题在于express / mysql中。将socket.iotransfer注释掉后,内存仍会随着时间增长而增长,且gc无效,疑似发生内存泄露。

已确认mysql部分存在问题。

问题大概查清楚了。
MySQL的KeepAlive部分存在问题,这个……有点无解……
我决定去掉这个机制了,这个重连有点坑爹。请联系你的DBA改大MySQL的timeout吧,或者要不要干脆跑个无数据库或改个文本数据库?

今天重装了一个server,并一直把client开着没发弹幕,过了有好几个小时,刚才发现一个报错:
{ [Error: Connection lost: The server closed the connection.] fatal: true, code: 'PROTOCOL_CONNECTION_LOST' }
[2015-9-21 16:33:52.85] 数据库连接出错,已经重试第1次。

估计是mysql的wait_timeout时间到了,然后我查看server是否还在继续服务,发弹幕功能是正常的。说明程序重连数据库是成功的。

继续测试ing,看client一直开着但是不发弹幕的情况下server能长时间服务多久。

发生上面的错误以后,发现后台报错,数据库无法写入记录,但是弹幕可以发送到client显示,以下是报错信息:

房间testdanmu得到弹幕(7e54601d0d8201046f1c311b45a2f6f0):更好肩膀处[IMG ...
[2015-9-21 17:8:20.317] 数据库写入出错
{ [Error: Cannot enqueue Query after fatal error.] code: 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR', fatal: false }
[2015-9-21 17:8:21.123] 房间testdanmu得到弹幕(7e54601d0d8201046f1c311b45a2f6f0):可不好[IMG WI...
[2015-9-21 17:8:21.124] 数据库写入出错
{ [Error: Cannot enqueue Query after fatal error.] code: 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR', fatal: false }
[2015-9-21 17:8:21.529] 房间testdanmu得到弹幕(7e54601d0d8201046f1c311b45a2f6f0):侧击[IMG WID...
[2015-9-21 17:8:21.530] 数据库写入出错
{ [Error: Cannot enqueue Query after fatal error.] code: 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR', fatal: false }
[2015-9-21 17:8:23.101] 推送1条弹幕到testdanmu,剩余2条。
[2015-9-21 17:8:27.105] 推送1条弹幕到testdanmu,剩余1条。

这个时候数据库实际上是断开连接了。
坑爹的问题在于,如果因为各种原因导致数据库断开,node-mysql并不会重新连接。又因为fatal error的缘故,要重连也照样**。且这个库没有提供任何重连相关的API(我用了pool也没有卵用)。

还是强烈推荐直接改MySQL配置。这个问题我上周没发现好的解决方案,这周回去再研究一下。另外可能会上多套数据库方案。

什么叫多套数据库方案? 👍

比如用MongoDB来代替MySQL,或是直接用json存储也没啥问题。

Dear zsx,

又连续长时间测试了几天,即使数据库出错写不了了,弹幕仍旧可以正常在客户端显示,至少不会发生弹幕不能显示的问题了,这一点要赞一个 👍

当我kill掉长时间运行的npm和node,然后再次执行npm start时发生mysql报错并且弹幕无法使用,报错信息被我不小心弄丢了,改天再给你看看,最后我再次重新执行npm start时弹幕恢复正常。

关于多套数据库方案,能不能做成通过在config中修改参数来控制使用mysql或其他存储方式呢?另外,如果mysql有wait_timeout的问题无法解决的话,能否支持一下csv的存储方式呢?例如在推送弹幕时动态生成csv文件保存信息,每天为每个房间单独生成一个csv文件应该足够用了(也就是按天生成csv文件),例如default/20150923.csv,default/20150924.csv。
csv方式主要是方便其他程序读取和用excel打开查看。

谢谢

嗯,本身我设计就是这样,从流程图就可以看到这些东西都在端点的最后一部分,互不影响。
本身就是在配置里写的。
我本来打算就要做一个文本存储,一个MongoDB存储的。csv只是文本的一种特殊格式,做一下也蛮快。
周六晚上中秋放假一起搞。
2015年9月23日 10:31于 phperwuhan notifications@github.com写道:Dear zsx,

又连续长时间测试了几天,即使数据库出错写不了了,弹幕仍旧可以正常在客户端显示,至少不会发生弹幕不能显示的问题了,这一点要赞一个

当我kill掉长时间运行的npm和node,然后再次执行npm start时发生mysql报错,报错信息被我不小心弄丢了,改天再给你看看。

关于多套数据库方案,能不能做成通过在config中修改参数来控制使用mysql或其他存储方式呢?另外,如果mysql有wait_timeout的问题无法解决的话,能否支持一下csv的存储方式呢?例如在推送弹幕时动态生成csv文件保存信息,每天为每个房间单独生成一个csv文件应该足够用了(也就是按天生成csv文件),例如default/20150923.csv,default/20151024.csv。
csv方式主要是方便其他程序读取和用excel打开查看。

谢谢

—Reply to this email directly or view it on GitHub.

修完了,MySQL + CSV

这次貌似很多的修改哦,是不是还加了管理后台?怎么用啊?
用法和配置有变化吗?

等下测试。

刚才又更新了一波。
管理后台一直有的,只是没截图

配置稍有修改,用法不变。

亲,

后台怎么访问啊?我都一起测试得了 👍

网页接口
GET /
可以直接发布最简单的弹幕。
GET /advanced
可以发布高级弹幕(需要密码)
GET /manage
可以进行后台管理

就是直接访问/manage就可以了

我把readme基本重弄了一遍


这个后台可以直接修改config文件并保存?NX烘烘的哈

并不提供直接修改config功能,一切修改都仅限本次服务器