Skip to content

Commit

Permalink
[update]更新介绍文档
Browse files Browse the repository at this point in the history
  • Loading branch information
Realself-Ma committed Nov 6, 2020
1 parent e72b60f commit ec66fe4
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 1 deletion.
1 change: 1 addition & 0 deletions 版本历史.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@
> - 添加静音功能
> - 修复Mysql连接超时问题带来的程序崩溃问题
> - 修复多人进入同一房间的BUG
> - 修复内存泄漏及服务器易崩溃问题,可以实现上万级房间数的并发PK
> - 修复了一些BUG
5 changes: 4 additions & 1 deletion 遇到的困难.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@
- 解决办法是:客户端的请求都加上一个终止标志位,服务器在接收到一长串请求消息时,根据这个终止位来拆分不同的请求,将这些请求消息存放到一个容器中,最后,再从容器中依次取出请求消息来做出响应。
3. 长时间(1天以上)不连接服务器,再次连接,服务器会发生崩溃?
- 通过生成core dump文件,运用gdb调试core dump文件,发现崩溃的原因是程序收到了SIGSEGV信号,出错的位置在mysql_fetch_row ()函数调用时,发现是在mysql_query()函数执行出错时,调用mysql_store_result()会返回NULL,此时再调用mysql_fetch_row ()就会发生段错误。然后,又考虑为什么只有1天后再次连接服务器会报错,重启服务器后,再次连接一切正常?最后,考虑到可能是mysql有超时机制,长时间没有查询请求后,会自动关闭连接,结果在网上一搜真的是这样:Mysql默认连接超时时长为8小时,无查询请求8小时后,Mysql会自动关闭连接,此时再调用mysql_query()函数,就会执行失败
- 解决办法有两种:第一种是,修改Mysql配置文件,将超时时长设置为最大值31536000s=1年,但这种解决方法并不完美,终究会超时。第二种解决方法是,在调用mysql_query()函数失败时,如果失败返回的错误码为CR_SERVER_LOST,则代表服务器不可用,Mysql服务器断开了超时的连接,此时再调用mysql_real_connect()重连一下Mysql服务器,再执行查询,就能查询成功了
- 解决办法有两种:第一种是,修改Mysql配置文件,将超时时长设置为最大值31536000s=1年,但这种解决方法并不完美,终究会超时。第二种解决方法是,在调用mysql_query()函数失败时,如果失败返回的错误码为CR_SERVER_LOST,则代表服务器不可用,Mysql服务器断开了超时的连接,此时再调用mysql_real_connect()重连一下Mysql服务器,再执行查询,就能查询成功了
4. 测试过程中发现,不能支持多个玩家同时匹配游戏,服务器存在崩溃以及内存泄漏的问题?
- 通过调试core dump文件发现,崩溃的原因是内存用完,出现bad_alloc异常,发生在splitRequestMsg函数中。最开始,认为是存放客户端请求信息的RqMsgList数组,在处理完消息后,没有释放内存导致的,结果在每次处理完毕后,调用shrink_to_fit,也不能解决崩溃问题,后来又考虑是不是vector分配内存时两倍扩容的机制导致的问题,把vector换成了deque,也没有解决问题。最后考虑可能存在死循环,让RqMsgList一直在申请内存,导致内存用完,最后发现在拆分请求字符串时确实存在死循环的可能,修改后,bad_alloc异常不再出现
- 虽然服务器不会出现bad_alloc异常而崩溃了,但是在测试的过程中,却发现了内存泄漏问题。每次测试200左右房间数的对战,内存总是会被占用2M左右,而且在服务器处理完毕后,也不会释放。最开始考虑到,可能是在堆上申请内存的对象,在使用完毕后,没有释放内存导致的,但是一行行检查代码时,没有发现这个问题。后来想借助内存泄漏检查工具valgrind来检测内存泄漏的位置,但是valgrind不支持muduo库的一些语法,不能检测。然后,就想着在请求信息处理函数onMessage中,一行行的注释,每次去掉一些功能,去掉一些处理的逻辑,再测试看有没有内存泄漏的现象。因为内存泄漏发生的很快,也很容易出现,所以就定位到问题出在编解码器的处理函数deCodeMessage中,在deCodeMessage中用相同的办法,定位到了Mysql类中的Register函数,在Register函数中用相同的办法,终于定位到了内存泄漏的罪魁祸首-mysql_store_result与mysql_free_result,当保存了查询结果后,必须释放,不然mysql申请的用来保存结果的内存就不能被释放,也不能被再次使用,从而导致内存泄漏。定位到这个问题后,发现之前写的代码中,很多函数都有类似的问题,修改后,内存泄漏问题解决了。

0 comments on commit ec66fe4

Please sign in to comment.