为了账号安全,请及时绑定邮箱和手机立即绑定

记录一次在github上帮iris找bug和修复的经历(Go最好的Web框架之一)

2018.08.09 14:14 3795浏览


Go的web框架有好多,详细对比可以参考《最好的6个Go语言Web框架

其中iris算是比较出类拔萃的,于是在Web应用的开发中,就用它啦。

https://img4.mukewang.com/5b6bd8bd0001941a02450273.jpg

自己想用websocket来做一个简单的在线聊天应用,刚好iris也支持,于是就用它自带的 _examples/websocket ,愉快的玩耍啦。

如果只是玩一玩,这个事情也就过去了。

只是我对并发请求会出现的线程安全性问题比较有兴趣,于是看了看iris做的websockect长连接是怎么维护的。

不看不知道,一看吓一跳,直接用的 slice ,也没有用到锁。

这不是在开玩笑嘛?虽然 slice 结构在并发操作的时候不像 map 结构那样经常报错,但肯定不是线程安全的啊。

而且iris自己的网站还基于websocket做了一个聊天室,难道也就这么放心大胆的线上运行着?


【6月8日】

发现了问题,我没有马上去反馈,而是去历史的问题清单里面找了下关于websocket的问题。 

还真有人【akiraho】质疑过websocket的connections&rooms怎么不用map来替换slice结构,效率会更高啊? 

然而,这个人【akiraho】的质疑被无情的拒绝了,理由是:map虽然在更新的时候快,但是读写时全部要加锁,整体效率也就比不上slice的结构。

https://img2.mukewang.com/5b6bd94a0001511b07580488.jpg

看到上面的问题和回答,谈到的只是性能方面,并没有谈到线程安全方面。

于是我就补了一刀,说现在的实现方式存在线程安全性问题。

很快,开发者【kataras】就给了我答复,鼓励我发现问题后可以直接提交修复方案.如果没有准备好来修复的话,也可以把问题出现的示例给出来,以便于他们复现问题。

https://img1.mukewang.com/5b6bd97300010b2d07530296.jpg

【6月11日】

那好吧,我就直接上去改下代码吧。

于是,要在github上第一次写代码了。蹩脚的表演开始了,见笑。

https://github.com/yz124/iris/

我把 websocket/server.go 中关于connections的读写给加上了互斥锁。

过程中,我还考虑性能方面怎么能更好些,在 func (cs *connections) add 里面使用互斥锁,想节省点运算。

这次提交也很快得到了【kataras】的答复,回复了4个质疑,我改动的方法不合理。

https://img3.mukewang.com/5b6bd9ce0001920507390445.jpg

嗯,他说的都很有道理的,比如:锁是值类型传递的话,会导致新的锁,效率低是一方面,最重要的是锁会失效,因为值类型copy出来是新锁。

他也建议,如果用锁的话,为什么不在更高层来加,既简单也不容易出问题。


【6月15日】

本来之前想为了性能而考虑的地方,反而成了很不好的代码实现。

于是,我就再次修正,把锁从方法里面提到了方法外面。

而这次修改提交是在github上直接修改提交的,并没有在本地验证过。

大家能想到后果是什么吗?

github对提交的代码会做自动测试和检查,我提交的代码无法编译通过,而自动拒绝提交。

有没有感觉很强大,机器审一遍,节省了多少人力啊,效率极大提升有木有?

于是又做了两次提交,终于通过了。

——自己测试验证是多么重要呀,也是负责任的表现

这次的提交,我附带把一个线程安全的测试用例也一起发出来了。

“用现在的程序,因为线程不安全,我发起1w次并发链接,最后服务端的connections只有不到8k的连接,丢失了2k连接”

https://img.mukewang.com/5b6bd9fe000147d207440330.jpg

这次的提交就没有那么快得到响应了(6月15日 - 8月8日),我还以为就这么不了了之了,还做了好多种猜想。

“是不是我提的这个线程安全性问题,他们就不觉得是多大点事,不理了啊”

“是不是我的提交和整个问答互动过程,让人家觉得太菜,不予理睬了啊”

一开始几天,我还每天上github看下有没有新消息,时间久了我也就不怎么关注这个问题了。

https://img4.mukewang.com/5b6bda1c0001e73e07440165.jpg

【8月8日】

直到昨天,我竟然收到一个邮件,【kataras】修复并且关闭了这个问题,而且还用了两种方法。

一种是用 map + 读写锁,一种是用 sync.Map 。

最终在iris主干上的版本,使用的 sync.Map 。

https://github.com/kataras/iris/pull/1023#event-1777396646

过去了这么长时间,我都对这个问题不关注了,没想到iris的开发者还是把这个问题修复了,赞。

https://img4.mukewang.com/5b6bda8d0001a76009560388.jpg

【总结一下】

这还是自己第一次在github上主动提问题和更新代码,到现在也对整个流程不是很了解,所以很菜,也请大家理解。

从这次经历中,大家是否也能感受到,参与开源并没有想象中那么难。

开源的优势也能有所体现:哪怕牛人写的代码也是有bug的,很多人共同来维护和提出建议,才能更快的前进。

最后,希望更多人能参与到开源中来,我自己也希望能发挥更多的贡献吧。

欢迎关注我的实战课程《PHP秒杀系统 高并发高性能的极致挑战》

点击查看更多内容

本文首次发布于慕课网 ,转载请注明出处,谢谢合作

21人点赞

若觉得本文不错,就分享一下吧!

评论

相关文章推荐

正在加载中
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消