00:00
大家好,欢迎来到自己教育课程的学习,本系列课程呢是自己教育的第一季,从零开始搭建游戏服务器,本节课呢是第18节,给大家讲一下并发安全map的使用。两大知识点,第一个社区资源,第二个就是我们实际给大家讲本节课的核心内容。第一个呢,就是我们还是我们社区的订阅号,大家可以关注一下。这是我小福利啊,大家回复我们客服呢,获取我们助教的微信。我们课程的通知呢啊,比如我们课程的一些呃优化啊,一些最新章节的一些更新啊,全部全部会在我们微信群里面通知,所以说大家最好加一下我们助教微信。好,那我们来讲解一下,讲解一下我们本节课的主要内容,核心内容啊,就是我们。定房安全的一个map的使用。大家对于我们。Map,病房安全这块有没有,有没有一个印象?有没有这个概念?有没有这个在使用当中遇到问题啊。
01:01
比如在高并发情况下。就是在。呃,多线程情况下。如果你购员使用的比较少的话,没有项目比较少的话,比如你用那个。然后外部服务器开发的话,可能用的不是用的,遇到的应该不是很多,但也会有啊。呃,像那个呃,应用服务器的话,大家遇没遇到过,就是使用map的时候,呃出现既读又写的情况,导致我们的那个服务器panic直接直接报出异常的。会直接让我们服务器挂掉。应该会有吧。如果你是个新手,当老手的过程的话,我觉得你应该会接触过这个这个事情好,那说一下我们的架构里面为什么需要并发安全呢?大家在这有没有一个想法,就是并购为什么要引入这个呃,并发安全的库呢?在里面我们的架构难道里面也会涉及到吗?你可以打一个问号。首先你打个问号之前呢,你要知道。
02:02
并发安全是指哪些?哪些情况下出发的?对吧,如果你是单进程服务器来来做的话。单进程啊,大家听说过单进程服务器里面没有多线程,没有多携程的情况下。并发是安全的map map是在同一进程里面去读写的。单线们应该认为是吧,就在同一进程,既读又写,就不会出现这种。竞争的关系就不会导致我们的他就他应该说有个顺序是执行我们的map的嘛。所以就不会出现我们多线程或呃高并发情况下导致的一些地图有血。这这样就使我们的map呢会。会在我们底层啊,会在我们应该是在1.9之前吧,1.5~1.1.9之前的版本过源底层版本的时候呢,版本库的时候呢,会直接挂掉,1.5之前吧,可能会爆出异常,不会挂掉服务器,由于我们这套架构呢,是在一五年给大家写出来的,也就是现在第一个版本啊,这第一个版本的雏形是我在是呃和我和我那套架构写的有点相似啊。
03:14
但有有有很多不同的,因为我们还没分层处理嘛,这些包还没分出去,底层框架之类的。呃,也就是在1.9之前呢,大家如果这么使用的话,就比如说就会之间挂掉,我看我我给大家说一下,我们架构里面为什么会需要,这跟我们架构设计有很大关系,比如我们进来。在这里面我们从主函数大家看起啊,还是说一遍。因为这课程马上快结束了,还有两节,两节是关于呃,DB操作的,比如数据库red,逻辑上呢,就不会给大家讲了,所以这点给大家再过一遍,过一遍让大家熟悉一下我们整个框架的一些流程。再说一下,我们哪里需要并发安全的一个map使用啊?好,大家看一下,这是我们主函数嘛,大家看所有的开源框架的时候呢,还是从慢函数开始。
04:00
这里面是我们监听端口,这是动态传进来了,如果动态不传进来呢,我默认是四个八。这是我们的日志服务器glo的一个刷新的,对吧,多核处理。在这里面呢,我们看我们这个函数啊,我们这个函数应该在这上面。好。这是我们的一个网络结构处理了,这是接收往下走啊,我们这个函数在哪里,应该在。Network下面吧。这是这个是我们的消息的序列化,大家也要注意一下。呃,我在最后一节总结的时候,会把这些全部分出来,分到我们相应的文件里面去啊,就不会这么乱,大家最后就可以很清晰的很清晰的找到我们所要找的一些函数啊,一些文件啊就可以了。最后也作为总结啊,好在这里哈,这是我们的什么结构体方法,作为接收者,接收者呢,我们这里一直在循环,在处理数据,大家看到这没。我们在这里面其实相当于每一个一个链接过来的时候,我们都起一个学生。
05:02
正常的操作大概是都会这么操作,这个这样是不是很看什么,其实正常的是我们写一个什么匿名函数完之后呢,来做一个。这呃,用勾主艇来起一个接收线程,一个发送线程,对吧,那样式来操作的,但是我呢,斌哥在设计的架构的时候呢,给大家尝试一下,用我们也TTB方式的一种。Web服务器的方式给大家实现这个这套流程啊,但是后面优化的时候,大家再看看我们怎么把这个优化掉的啊,这一段会优化掉的,这都是在我们后面,后面第二期甚至第三期的时候,应该会优化到这里面去的,好吧。大家看这里,这里是我们每循环一次呢,我们就过来对吧,Connect信息,那么这样子就涉及到一个问题了。就是说。每个学生之间有自己的对战,大家知道吧,有自己的占空间,大家知道是多少,不自动申请的。可以了解一下,这个是跟我们构语言很相关的这些知识,最好大家都要知道一下啊,你要学一门语言的话,你最起最起码从他的一个哲学思想,包括设计哲学里面去了解一下,为什么要设计成构语言,他想解决现在语言的一个什么什么的一些问题,对吧。
06:18
其实go的话就是。解决了一个什么问题。大家觉得?自己想一下,他就在逻辑层就可以处理高频发了吗?好,我们看一下我们这个函数继续啊。这序列化操作。那么这个操作就导致了我们一个是一个问题产生,就是说我们所有的携程在进来函数的处理的时候,包括我们下面顺序处理的时候,在这里面处理,这是主协议嘛,主协议来处理对吧,协议来主协议子协议来处理吧,包括到我们功能函数,那么做了什么事情呢?就是说了一点,就是说我们所有操作都是在我们go下面进行的每一个。每一个链接过来全部在勾入镜执行了,那么这里面涉及到一个问题,就是我们在这里。
07:00
看到没,全局保存一个玩家数据,那这样子这里面呢,相当于我是可以认为是是写入吧,这个没问题吧,写入,那么我在我们的其他线程里,其他行程里面,我们在我们的camera里面应该有一个看在这里面读。它本身我们在I函数本身就是启动一个什么,本身就是一个携程,所以说如果在高并发进来比较用户量比较大的时候呢,会导致我们既读又写,那么我们这个map就并发不安全,本身呢,它的并发不安全的在我们数据里侧,那么就会导致我们服务器挂掉。在1.9版本呢之后呢,官方呢,给我们增加了一个库,SYC下面可以呃有有几个是呃提供了几个函数可以作为病房安全的,呃但是呢,斌哥建议呢,我们还是用呃第三方来操作好一点啊,因为病房安全内库在网上看到一些资料说大于一定数量,比如说100万,1000万的时候,100万的时候你在读,大量读和写的时候呢,也会存在一些空数据。
08:03
所以说这呢,就会导致我们有些数据还是不行的,也就是说底层的底层版本库呢,需要还要需要优化一点,我给大家介绍的那个我们现在。要给大家讲的那个用的版,用的第三方库,给大家说一下,就我们去。我们去改号给大家找一下先。还是这样子,先先教大家方法,完了之后呢,我们再去看例子就可以了,本身呢,本身呢过言的一些机制啊,包括语言层面,我想大家有经验的话,这都是。不难的,对吧,这东西都不需要给大家讲太深。好,我们搜一下,我搜这个名字。应该是后面那个去掉啊。Mass去掉。好。是够的,77个哦,这是他自己。
09:03
那好吧,去我们自己目录下找呗,我们就不在这里找,我们自己的官方的,我们自己的社区的官方目录下面也是有的,比如说我们在这里面搜一下。可能没有吧,有嘛我就说嘛,对吧。我们点进去。这个就是我们我给大家推荐的宾格,大家推荐的一个病房安全的一个map使用这个使用,嗯,看一下啊。就是我自己点的吧,应该是啊。还是四年前了,四年前。已经维护了,已经测试的比较,呃,比较比较好了,已经。就是我们正常的兵哥,正常的项目里面全部用的是这个病房安全,大家可以按照自己也可以自己去实现写一下,如果你要是想觉得你技术能力比较强,或者你得没必要再用网络的上的网络这个第三方官网,我可以自己写一套啊,那你自己写一套也是可以的,你自己写一套,我觉得你跟我们1.9版本的提供那个。
10:05
兵马安全有区别吗?我想你写的应该也是。很相似的,对不对。因为这个并发安全是通过,呃,应该是通过那个Java里边转过来的,应该我之前看文章的时候,好像介绍过这个这个库的一个版本啊,说他是从Java Java的相关的相关的人员是转过来的,所以说他录了一套,你看在这里吗?多少毫秒,你看这是普通的,你普通的肯定读写锁嘛,对吧,你看这。你这可不是一个数量级的来看的时候。你看你用了400多毫秒,你这呢100多。这是get的时候,你对get的时候可能稍微费点,它这是多少每秒是。对吧,它是60多差不多这个你看这就有区别,这呢。就是区别了,To加get呢,可能就。160度,你就700度相当快的,马上到一秒了,然后这个性能差的很多了,所以说大家用的时候呢,一定要对比对比一下,我们现在有的和和我们和我们现在要大家大家那个要使用的去做一下性能测试,这样子会对我们会对我们开发呀,对我们后面一些性能优化会少少走很多弯路啊。
11:17
嗯。好,那我们就给大家先说一下我们版本库呢,这个我们给大家拷过来啊,到时候我直接大家有需要的呢,可以直接来。来我们那个盖达哈,上面啊就。呃,格哈姆斜杠。勾浪LT调这go是大写,既是大写就可以了,OK,那么我们来看一下。我们拷过来之后呢,只需要把我们的第三方库放到我们相应的相应的下。好,我们看一下那个,我们直接放到我们的,像这个。我们的一个什么glog,或者是我们的一个catch里面都可以的,上节课给大家讲了一个catch那个大家呃可以去看一下,那个也是比较需要用到的。后面我们。
12:04
好,直接我复制就可以了。出来使用呢,也比较简单,使用的话,我们看一下,我们直接直接在我们的那个。包含进来就可以包含进来。就可以使用了,给大家看一下,我们其实就在主函数里里面啊,就在int函数里边,给大家实现一个小例子,顺便呢操作一下。呃,这个实现小例子的话,其实也也实现不了多少啊,因为我们我们必须在大量的情况下才会有。嗯,给大家举个例子吧,那就。好,那我们再我看一下。我们在这里再写一个呗。我想。那我们都在这里面给大家写,OK。呃,这里面呢,我们就实现一个并发安全的一个卖法,我们看一下给大家实现一个。
13:02
好,我们在这里实现一个,那么我们就在这里。那么这里呢,我们就来做一个,那么就应该叫什么呢。我们的一个。嗯,初始化吧,应该我们全部有初始化信息的。那就。其实我们大家看例子吧,我觉得写是没必要的,大家看例子吧,因为看我写也是这样子的,你看吧,首先呢,我们要做一个什么,一个我们一个第三方库的,也就是我们对方安全库的一个初始化信息,也就是我们要。初始化我们的我们的库之后呢?我们。Put呢,就直接这样put就可以了,这是什么?第一个是K啊,大家知道吗?第一个是put是K完,第二个呢,是我们的一个存的值。同样的,这个是这样一个方法,这取你看取大小啊之类的都是可以的,包括我们put什么interface啊,这样数据怎么存啊。
14:06
都是可以的,所以说大家在拿到这个版本库的时候呢,按照这个例子去写就可以了,你看我大家写的例子,我这是之前测试之前,给大家测试之前,我在用之前呢,是写了一些例子,你看也是一样的嘛,先初始化一个完了按照自己的项目的一个结构去存,存完之后呢,怎么去取对吧,怎么歪掉去取啊,比如interface啊,这会怎么去取,你看这是怎么取到的值,对吧,为什么interface。对吧,通过类型转换来取我们数值应该这块,特别是因为斌哥在我们在我们我之前测试的时候呢,是因为我是一到是结构体的一个保存啊,因为。大家猜这个结构体是什么?这个结构体是就是按照我们玩家的那个链接信息去保存的,懂了吧?所以后面呢,我们所以还是有很多事情要做的,就是说我们包括我们并发安全的一些数据啊,全部得按照这种形式去存的。因为我们链接数据的话,如果你这样去写,你可以大家可以测试一下,如果我不在讲,我在讲第二期之前结束之前吧,如果你要是。
15:07
你要是把我们这个项目应用到你的场景里面去啊,应用你的项目当中去呢,你可以测试一下,如果超过十人的话,并发每秒20每秒用户发20人过来的是吧,你肯定会出现问题。这个我因为兵哥之前都测试过,压力都压力都测试过,在第二期讲之前呢,正式讲前几届之前呢,我会给大家测试一下我们之前的性能啊,就是我们这个版本的性能。此版本在本期呢,在第一期就不给大家讲了,第一期大家先熟悉下这个框架基础流程啊,包括我们要加入的一些库的一些形式,你看这种形式对吧,怎么移除啊,怎么去对吧,替换啊。好,这还举个例子,这是什么例子啊,看一下。安全的一个多线程的情况下去处理的,应该。变化安全啊,这是结构体信息,结构体信息怎么去取的,那个不是。这里看怎么去循环取对吧。
16:02
这是怎么循环去取?32我的头是四倍的。整体来看这个性能还是比较高的,所以建议大家呢,在项目当中能用最好是用到,包括你自己,我不建议自己去造轮子,没有必要,对吧。得看你看你个人实力了,如果你觉得真正自己写的性能比较高,那就自己写的呗,这个东西兵哥不从来不会限制你去做任何事情啊,好。那么我们就给大家说一下,我们后面的项目当中用到病房map呢,就是我们目前这个。诶,少了一个东西吧,少了一个什么少了。OK,就是他就可以了。好,应该没什么问题啊,今天呢,就给大家介绍一下这个框架,这个框架呢,大家就去研究一下,这个是需要的。呃,我之前给大家讲一下我们之前,我们之前一个经验吧,就是说我们我当时在。
17:04
呃,不说哪哪个公司了,现在那个做的一个大型m Mo的一个项目,里面呢,是讲里面是。呃,FPS游戏的副本形式的,下副本形式的,每个副本的里边可能有十四五个人啊,四五个真实玩家,剩下全部是全部是怪,小怪和和一些大boss啊之类的。我们当时做那个是用是超隔壁项目组的一个C加加的个架构项目过来完了之后用有源撸了一遍,撸了一遍的时候呢,没有怎么说呢,没有用到过源的精髓啊,全部是单进程,单进程在跑数据啊。你想想单进跑数据跑场景,再加上我们的一些物理引擎啊,一些嗯,巡逻引擎啊,所以在里面性能的话。性能的话,能承载2000人是大概在五六十毫秒左右,而且那当时做的时候是。是AI的话,还是在触角后面的话,可能还有很。很多事情要做的。
18:01
所以那个时候我就感那个时候我们全部在这单进程里面跑,就没有涉及到这个并发安全的map,但是后来我们把场景分出来了,因为场景觉得没有必要带单进程里跑嘛,就把每个场景用go入来实现了一遍。把场景放在每一个go主体里面去,大家想如果十个场景,那十个go主体,那么之前的里面单进行的架构,单进行的数据,也就相当于跟我们。构入镜是隔离的对吧,所以我们又改了一套架构,里边加channel加RPC的,呃,一些交互的信息啊,又把并发安全的全部改了一遍。你想在设计之初,如果没有考虑到这个问题的话,你后面改架构的话很痛苦的。所以说大家我我大家建议大家就是在自己设计的时候,包括自己项目组,不管不管是你自己在设计,还是自己,呃,自己在维护一套东西。一定要长远考虑一点,也就是你可能想不到那个后面的事情,但我觉得你有必要去。
19:01
了解一下其他框架,其他比较牛的框架是怎么设计的,你再对比一下你框架的一些缺点,这样子呢,你就能找到一个。优化的地方。对吧。所以我希望大家呢,就还是那么不断学习是吧,像那个得到APP里说的一样,什么终身学习,必须要终身学习才可以,真的不管你在哪个行业,对吧,你认为这套架构能足够要足够你过一辈子的吗?没必要吧,我觉得这套架构对吧。才刚刚起步而已。没有一个。成型的一个上线的项目的话,其实任何架构都是都是没有用的,懂了吧。如果这套架构如果网易用了,或者是腾讯用了,那我觉得真牛了,但是人家会用吗?人有自己的技术站,但网易全部是C加加是吧?好,这节课呢,我就不给大家讲太多了,就给大家聊一下我们后面的一些情况,因为现在我就我们看一下那个课堂的,呃。
20:00
内容的话呢,第一期就已经接近尾声了,后两节是数据库的,数据库是给大家怎么添加,怎么加进来就可以了,完了21节最后一节总结呢,是给大家整理一下我们代码,完了之后呢,可能大家再看一下就可以了,整体架构。包括总结一下实现什么内容就可以了,OK。今天的内容呢,主要病房安全这一块,也没有必要给大家写代码了,对吧,大家看一下这个例子就可,你看我刚才给大家拿过来那个,那是我一五年写的代码,也是在那里面也是那样写的,对吧,也是按照他这个例子去写的,只不过我那是结构体而已。针对性可能更强一点,因为我要针对我的使用场景嘛,对吧。当时也做了很多测试啊呃,测了大概嗯,大概40万个数据左右,发现没问题,完了我就。打算用它了。我当时自己和和之前的朋友聊了一下,说自己撸一套,撸一套出来之后性能发现跟这个差的比较远。包括在处理时间上,包括10万个数据,我这边就不住了,而且对吧,有可能卡住了或者怎么样,或者读数据是空的,而这个是没出现问题的,所以我就选,最终选了这个。
21:13
啊,大家如果有问题的话就去我们群里问吧,啊呃,有什么疑问的话都可以啊。哇,那我们看一下有没有给大家回顾的。这节课就给大家讲一个使用方式,大家怎么去使用,包括一些架构的思想。带给的思想,好吧。那那我们本节课就到这里吧,我们也不给大家浪费太多时间,就是大家要一定要去学习。不管是在兵哥的课堂上学习啊,还是在你其他的一些论坛上。对吧。终身学习,这个是比较好的一个习惯。嗯,好吧,那我们今天就到这里,我们下节课再见。
我来说两句