乐趣区

关于后端:Go-WebSocket-多房间的聊天室五用多个小锁代替大锁提高效率

我是 HullQin,公众号 线下团聚游戏 的作者(欢送关注公众号,发送加微信,交个敌人),转发本文前需取得作者 HullQin 受权。我独立开发了《联机桌游合集》,是个网页,能够很不便的跟敌人联机玩斗地主、五子棋等游戏,不免费没广告。还开发了《Dice Crush》加入 Game Jam 2022。喜爱能够关注我 HullQin 噢~我有空了会分享做游戏的相干技术。

背景

在专栏《Go WebSocket》里,有一些前置文章:

第一篇文章:《为什么我选用 Go 重构 Python 版本的 WebSocket 服务?》,介绍了我的指标。

第二篇文章:《你的第一个 Go WebSocket 服务: echo server》,介绍了一下怎么写一个 WebSocket server。

第三篇文章:《单房间的聊天室》,介绍了如何实现一个单房间的聊天室。

第四篇文章:《多房间的聊天室(一)思考篇》,介绍了实现一个多房间的聊天室的思路。

第五篇文章:《多房间的聊天室(二)代码实现》,介绍了实现一个多房间的聊天室的代码。

第六篇文章:《多房间的聊天室(三)主动清理无人房间》,介绍了如何清理无人的房间,防止内存有限增长的问题。

第七篇文章:《多房间的聊天室(三)主动清理无人房间》,介绍了如何防止并发导致的资源竞争的问题,是通过乐观锁解决的。

第八篇文章:《多房间的聊天室(三)主动清理无人房间》,介绍了基于 Go WebSocket 手写一个简略的 Web Shell,能够体验间接在浏览器中输出 linux 命令的感觉~

舒适提醒:浏览本文前,须要至多浏览前 7 篇文章。如果你没浏览前 7 篇文章,肯定要先看一下,因为这篇文章更简单,如果你不弄懂下面几篇,这篇可能跟不上节奏噢。

回顾:register 和 unregister 竞争

上篇文章咱们提到,存在黑天鹅事件(小概率事件),register 和 unregister 会竞争资源,导致数据异样。

最终咱们通过减少「乐观锁」解决问题。

须要留神的是,咱们上文加的锁是一个全局的锁。

这意味着,同时有 100 个客户端(即便是不同的房间)申请连贯时,他们必须排好队,一个一个解决。等上一个申请加锁、开释锁后,才解决下一个申请。不能施展 goroutine 并行的劣势。

换句话说,这个「锁」太大了!影响了程序运行效率。

怎么解决呢?咱们把「锁」拆分成更多小锁,每个房间用一把锁,这就解决了问题。保障能够同时解决「不同的房间的用户连贯申请」。

用小锁代替大锁

用「多个小锁」代替「大锁」,能够显著进步各场景下的并行效率。

如下:

main.go

client.go

hub.go

然而给每个房间加锁,寄存在同一个 map 里,读取这个 map 有须要引入一个全局锁mutexForRoomMutexes

其实,大可不必放心,当初曾经优化了很多了!

因为你能够看到,这个锁开释的十分快,影响不大。然而上篇文章的锁mutex,不仅是全局锁,而且占用工夫较长。

源码

仓库地址:github.com/HullQin/go-websocket-examples

关注这个 commit:github.com/HullQin/go-websocket-examples/commit/b12271a9531360d407c22c54c854e177e7e48fda

写在最初

我是 HullQin,公众号 线下团聚游戏 的作者(欢送关注公众号,发送加微信,交个敌人),转发本文前需取得作者 HullQin 受权。我独立开发了《联机桌游合集》,是个网页,能够很不便的跟敌人联机玩斗地主、五子棋等游戏,不免费没广告。还开发了《Dice Crush》加入 Game Jam 2022。喜爱能够关注我 HullQin 噢~我有空了会分享做游戏的相干技术。

退出移动版