![](https://img-blog.csdnimg.cn/20190927151026427.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
游戏服务器经典业务开发
游戏服务器经典业务开发
.net core game
致力于.net core全栈游戏服务器开发
展开
-
游戏上下文的一种实现方式
技能系统:比如:LOL中派克的R,达到血量后,直接斩杀。比如:属性系统,每个人都有自己的属性培养。战斗系统:需要达到一定的条件触发某个东西。AI系统:达到某个条件触发某个行为。上下文设计模式用的非常之多。这里主要是战斗系统为例子。原创 2023-12-24 13:16:17 · 400 阅读 · 0 评论 -
Buff系统的设计 1.没有真正实战=0 2.Buff系统中的筛选逻辑
经过这几个项目的锻炼 和 枚举多态这种模式,我发现我对多态慢慢应用的了如指掌了,能够很自然的进行代码的设计。像这种看到:buff具有不同的功能时,我很自然就想到了多态。多态的执行,其实就是:业务实体 + Param,从而业务实体的数据被修改。这样子在不同的枚举中进行不同的生效,从而其他模块再去调用这个里面的东西,从而生效,比如:打折。我充值了,变的更强了,我打怪时战力变高了,影响了最终战斗公式的计算。Buff系统,其实就是:给各个模块带来一定的增益,比如: 购买了vip,这样子可以买其它东西时打折。原创 2023-10-27 21:44:25 · 124 阅读 · 0 评论 -
游戏中排行榜算法研究
这个所谓的二分查找,是返回自己在排行中的位置(从1开始),而且,就算自己不在list上,也是会返回位置的。重复时,默认认为是自己更小。所以,游戏中的排行榜,必然要求是:按照降序来的。所以,集合框架中的,是不满足的。里面重写了排序算法。原创 2023-09-11 13:27:12 · 750 阅读 · 3 评论 -
accountId、uid、roleId 游戏中的3种id
这个是一个很长的,玩家通过http登录授权后,通过web层,由雪花算法根据accountId生成的long值,里面可以把玩家的比如:平台信息之类的包含进来。这个是角色Id,比如:MMO中一个玩家又5个角色,那么根据uid对应 5个roleId。accountId:这个是字符串,玩家可以输入名字 或者 通过微信生成。原创 2023-06-30 18:29:56 · 727 阅读 · 0 评论 -
【装饰模式】在游戏中的使用例子
例子1:将Redisson包装为自己的GameRedis组件 // 提供一致的接口。例子2:将网络封装为自己的NetWork模块。例子3:将策划的技能配置包装为自己需要的接口。原创 2023-01-08 14:45:38 · 88 阅读 · 0 评论 -
枚举实战 1.好处:使用model避免方法参数过长,及其参数顺序换位导致的不正确 2.用途:商店、任务、活动...任何有多个分类的功能
【代码】枚举实战 1.好处:使用model避免方法参数过长,及其参数顺序换位导致的不正确 2.用途:商店、任务、活动...任何有多个分类的功能。原创 2023-01-06 10:18:07 · 90 阅读 · 0 评论 -
【Thread.sleep(xxx)方法(让出cpu执行)妙用的2个案例】 1.MapThread管理 2.RobotThread管理
线程池中只有5个线程,但是,RobotThread确有10个,而且都没有停止,一直在while循环体中不退出,那么岂不是只有5个RobotThread能够被调度,其它线程抢不到了?优化策略:我们可以在每个RobotThread的一次while循环执行结束后,根据帧率,然后sleep(x)一下,这样子让出cpu,让其它的线程得到执行。我们可以一下子取出这个阻塞队列中的所有任务,执行完毕,然后sleep(5),这样子让所有的线程都能够得到执行。2.Robot压测机器人工程中。原创 2022-12-30 15:57:06 · 486 阅读 · 0 评论 -
异步http的实现: CloseableHttpAsyncClient(比如:GameServer需要请求Gateway时)
jdk11之后,apache就提供的有 CloseableHttpAsyncClient 之类的接口,里面封装了java NIO,从而实现异步的请求。但是有一丁点网络知识的人肯定知道,带网络的这种必然要用NIO之类的去优化啊,肯定是事件的形式,不让CPU阻塞于io之上。在jdk1.7时我之前使用的都是阻塞类型的接口,有的封装的话,最多也是加上线程池之类的。原创 2022-12-29 17:39:26 · 322 阅读 · 0 评论 -
【理解Class<?>xx】 1.这个要理解为一个new出来的类对象 2.何时用enum枚举单例 3.消息派发模块的编写
在java中反射可谓用的最多了,每一个new出来的对象都有一个类型,类型是叫做类对象。 做下笔记!原创 2020-10-07 12:54:06 · 380 阅读 · 0 评论 -
思考上线后游戏数据库字段的管理
比如:拿csdn来说,在发表文章时,csdn增加了个必选的选项 "内容等级",在发表文章时,是必须勾选一个,这个属于最近新增加的功能。但是我之前发表出去的文章怎么办?但是:如果我把文章的内容:content,修改为了 data,那一下子就完蛋了,所有的文章全都不见了,引起灾难性的结果。游戏或者应用服务器在上线后,遵循的是:只增加不减少的原则。这个原则其实是很好理解的。当然了,很容易得出结论,之前已经发表过的文章,也没影响。原创 2022-12-27 14:55:38 · 85 阅读 · 0 评论 -
GM架构设计 1.web管理后台调用httpserver使用http 2.游戏客户端则是直接发送协议
好在是:netty直接支持http服务,那我们可以在游戏服启动时,顺手启动一个http服务即可,为了不阻塞游戏服,需要单独开一个线程启动,当然了,这个并发很低是内部用的,因此boss和worker线程数设置为1即可。web服的话,其实就是发送http请求,GameServer下的HttpServer就可以接到请求,进行相应的处理即可。1.是客户端输入gm,其实就是发送请求,我们直接处理。GM的本质:gm说白了就是能调用到我们在游戏服写好的GM接口。那这就涉及到了进程间的通信,毕竟gm后台是web服务。原创 2022-12-27 11:40:11 · 1380 阅读 · 0 评论 -
【游戏服使用之jdk动态代理】1.实现类要实现InvocationHandler接口并传入Object
用途:动态代理,必然是为了不入侵之前代码的基础上动态增强功能,比如:一个方法要统计耗时,那么就可以使用。原创 2022-11-30 15:36:01 · 385 阅读 · 0 评论 -
java游戏服务器性能压测神器:jprofiler
比如:一个全局的静态属性,一直往里面加东西,由于它是一个GC Root,这样子这块内存永远不会释放,导致内存泄露。正常来说,是波浪型的:先分配,持续增高,然后触发GC进行回收,内存下来,这样子内存整体是平稳状态。分析哪些方法耗时最多,然后分析这些消耗是否合理,比如:缓存穿透等,其实是可以避免的。然后能否在登录时,将一些业务异步处理,而不是上线时在一个方法内全部查询好。分析出有没有内存持续增长而没有释放出现内存泄露的情况。这时就需要去观察内存的变化。原创 2022-11-16 16:05:41 · 496 阅读 · 0 评论 -
通用游戏服务器架构设计
功能:主要没有db操作的,比如:进入到mmo中的场景服,打麻将的麻将服,再结算后,将结果post到逻辑线程池(完全是异步交互,不会出现等待),进行发奖计算等,这样子场景层的业务完全不会阻塞。功能:进行业务线程的处理,这里主要是一些带有db操作的业务逻辑,比如:任务、背包等,好友,工会,宠物。和上面的服务完全是一套代码,通过config区分到底是跨服服务器,还是游戏服务器。其实java游戏服务器就是这么简单,这种架构适合所有的游戏服务器类型。线程池:3*core 这样子的线程数。线程池:10个左右。原创 2022-11-16 15:17:14 · 1381 阅读 · 0 评论 -
循环跨3天活动的一次思考
看了别人的代码,我发现其实有一种比较好的策略:把活动情况记录到玩家身上,记录当前玩家身上的活动actSn和对应的开启和结束时间,一旦发现和当前的已经开启的不一致,那就做出对应的处理即可。活动开启:那其实就是丢到schedule里一个延时任务,计算好本次开启的时间,等着被回调开启,然后调用我们Activity里面的onStart()方法。现在跨3天循环开启的活动,其实是针对通一个actSn来说的,比如:配置11月1号到12月5号,每周6,7开启,周1领奖。那其实活动下次开启后,依然是这个活动sn。原创 2022-11-16 15:00:06 · 603 阅读 · 0 评论 -
游戏服务器性能优化之:缓存穿透(1.通过功能开启判断返回默认数据)
假如功能没开启时,玩家发起了查询请求,那么就会立马查询数据库,但是功能没开启啊,发起的是select,因此也不会加到缓存里,退出后,下次客户端再次登录,又再次会发起查询,又是去查询select,所以,是相当的耗时,等于每次查询就是select xxx from table xxx这样子执行sql语句啊。解决办法很简单了,那就是在查询时,服务器端先判断是否开启改功能,没开启,则直接返回默认数据即可。缓存击穿,意思就是:一直查询数据库,而不是查询本地缓存。原创 2022-11-16 14:23:48 · 514 阅读 · 0 评论 -
多线程编程的精髓:1.无需顺序执行 2.所有的线程按照相同的顺序拿锁就不会死锁
web的话,我想因为:经常遇到的是:一个表单,所以来说,几乎是不需要像游戏服务器那样子只修改几个字段这种情况,遇到的修改,往往是整体修改,所以这里我想是和游戏服务器架构的一点不同。这2句话是我在使用xdb的时候对线程池执行任务逻辑的思考,这2句话可能在课本上看到,但是每个人看到的时候可能直接就忽略了,今天我再次实战后的总结来说,这2句话真是价值万金!2.所有的线程按照相同的顺序拿锁就不会死锁。接着顺便扩展下,如果是:多进程,那么就是分布式事务咯!1.无需顺序执行任务。原创 2022-11-15 21:49:11 · 162 阅读 · 0 评论 -
【内部类的作用思考】1.例子:关于游戏中Excel配置文件应该暴露的接口
这样子ConfHero类中其实是有一个内部类,里面管理着数据的加载,然后使用模板引擎生成这些配置代码,最终暴露出来更加简单的接口。其实这样子,有点写的多了。原创 2022-11-14 23:28:14 · 117 阅读 · 0 评论 -
游戏服务器中多人交互逻辑业务的思考
背景:在mmo中有非常多的多人交互逻辑,比如:工会中帮主同时同意N个人假如帮派,此时,要检查所有人是否加入了帮派,如果没加入,则让它加入,但是有可能这一批人同时也申请了别的帮派,别的帮派的帮主也在做这一件事,但是这个业务同时涉及到多个帮派(帮派表)和多个玩家(玩家表),因此是十分容易出现脏数据的。而且:在无锁写法中,玩家数据和工会数据是不同的线程维护,要检查玩家的状态,需要从工会线程异步的获取玩家的数据,因此又会存在异步获取玩家工会数据时,又被别的工会线程修改的问题。原创 2022-11-14 10:23:38 · 283 阅读 · 0 评论 -
【关于游戏中多人交互业务无回调写法的2种方案】1.xdb 2.world服+只读redis+队列
十分理想,游戏业务使用这个线程模型,让你只关注业务开发即可,几乎无需考虑线程模型。再world服中,使用redis进行读操作,这样子可以一下子获取多人的数据。个人模块:全部用mongodb存储,同时redis缓存一份数据。好友等业务,则使用:redis存储。原创 2022-11-01 11:42:19 · 246 阅读 · 0 评论 -
mmo中匹配机制的思考与实现
就是玩家发起匹配请求进入匹配队列后,然后此时玩家却在副本打boss,此时是十分有可能出现:匹配成功再拉它进入别的地图的时候,却发现:拉取失败了。再逻辑层匹配,也就是用一个内存表,结构为List类型,以:匹配满5人进地图为例子,那就是每次匹配都进行检测是否满5人(同时把匹配条件不满足的剔除,如:不在匹配场景了)。玩家增多后,会开出不同的分线,场景层是单线程的,同时多个场景可能会对应不同的线程,因此匹配可以认为是使用的多线程匹配策略。即使玩家在不同的分线,其实逻辑上大家还是在一个匹配队列的。原创 2022-10-21 12:58:40 · 957 阅读 · 0 评论 -
“工会捐献一天只能捐献3次”这种业务的写法
方法1用到的业务其实挺多的,这样子查询只管查询就行了,没有多余的判断,一个方法只做一件事,但是问题就是:在凌晨5点这时,要做的业务比较多,还好这时玩家比较少,减少了这种压力。在每次进行捐献和查询捐献信息的时候,则进行 :”对比上次捐献时间和当前是否是同一天,然后如果不是,则进行进行重置“ 这个判断。玩家在登陆的时候,”对比上次捐献时间和当前是否是同一天,然后如果不是,则进行进行重置“。再每天5点的时候,重置所有的在线玩家的捐献次数。在玩家登陆时调用一次。这种的话,问题主要是:何时重置次数的问题。原创 2022-10-20 11:16:30 · 72 阅读 · 0 评论 -
“多个帮主同意某人加入工会”思考异步编程的问题
而:工会捐献等业务,其实都是:已经确定了哪个工会了,都是单线程操作了。方法2:如果是mongodb这种,那只能引入redis,使用putIfAbsent这种互斥性的操作,别的帮主同意时,则使用redis检查玩家是否再某个帮会中了。就是:帮主想同意某人加入工会的话,需要知道是否这个人已经再某个帮会中了,但是每个帮主同意时的业务处理线程都是不同的,这样子,其实会有数据并发访问的问题。解决办法1:xdb的方式,对工会 和 玩家 这2个共享资源加锁,同时事务的方式处理,这种写法非常简单,而且绝对不会出错。原创 2022-10-20 10:59:39 · 193 阅读 · 0 评论 -
成就系统和任务系统的设计
起服时都有一份,以:杀死1001这个怪10次这么一个成就为例子,然后,每个人每次杀死一只1001的怪,都会查询一下xbean是否完成了这个成就。起服时,大家公用一份,而不是:登录时,每个人都检查一遍表中的成就是否完成。每次接取的时候才注册的,也就是:是动态注册。与任务系统相比,成就系统的数量非常的多。成就都是计数相关的。原创 2022-09-09 17:03:30 · 906 阅读 · 0 评论 -
java这种多线程编程模式解决异步间隙中的问题(异步编程正确性的基石,这篇文章非常重要)
就算开始是:由roleId这个线程处理,之后是guildId线程处理,但是1000次请求发过去,其实挺乱,而且会拿到好几个工会号,导致创建多个工会,及其容易出错。比如:工会模块,我们往往有一个LogicRole对象,一个工会相关的服务器。go的话,就很方便了,对于同一个玩家,都是单独的一个协程,那就可以去阻塞这个协程,采用同步的api等待结果的返回,这样子结果么有返回,就阻塞这,这样子直接在Logic端同一时刻,只会有一个请求在进行处理,所以go这块是很好的。其实呢,还会有一个异步的问题。原创 2022-09-06 15:14:51 · 185 阅读 · 0 评论 -
跨服架构的演进
缺点:由于登录到的服务器没有逻辑db数据,因此不支持养成,这样子你会看到:可以看到玩家坐骑界面,但是打开后,无法养成。MT:依赖于消息的转发,在一个消息上增加字段isCross,本服的玩法,则在本服处理,跨服玩法,则转发到跨服服务器。由于跨服的本质是一个服务器上登出,再另外一个服务器登录,因此哪个服务器人少,就登录到哪个服务器。缺点:跨服玩法越来越多,大家都在玩跨服玩法,容易单点故障,一个跨服服务器承受不了。MT是伪通服,因为没场景,所以,根据消息的转发即可实现任意2个服务器之间的通信。..........原创 2022-08-29 16:30:51 · 401 阅读 · 0 评论 -
对redis或者mycat sharing分片机制的理解
1.首先,分片是一种拿着多个及其共同为一个服务进行服务的一种设计方式,本来redis是单线程的,但是能否把不相关的没有冲突的数据放到其它机器上计算呢?现在数据量实在太多了,a b cd 都扛不住了,那就需要加机器,那就会引起之前的路由策略失效,此时,就可以“再hash”,数据发生迁移。从而进行较为均匀的数据存储。上面既然是分片了,也就是数据data由好几台及其一起存储,比如:a,b,c,d存储,那b突然挂掉了呢?此时其实b可以部署多份:b1,b2,b3.。b1挂了,b2顶上,这就保证了包可用。.......原创 2022-08-19 01:01:06 · 182 阅读 · 0 评论 -
游戏服务器中集群网关的设计(SpringBoot+nginx)
此时,为了避免单点问题,需要把网关设计为集群,目前我们游戏中,使用的是:nginx + 多个springboot工程实现集群的。nginx可以根据玩家的ip进行路由到指定的springboot工程进行处理,这样子就能分流,挂一个网关服务器,影响也不大。可见,如果网关挂了,那么玩家连分区列表都得不到了,就无法进入游戏了。1.客户端可以请求得到分区列表。...原创 2022-08-09 17:46:17 · 1658 阅读 · 0 评论 -
mmo及时战斗游戏中的场景线程分配
MapThread池针对不同类型的玩法,如帮派战,一下子要有300人,不可能一下子让着300人进入到同一个MapThread,这种大副本和小副本(只有2个人pk),这2种玩法是不同的。首先我们采用的是java语言,那就要注意好线程的分配策略。主城从注册后,kuang一下子进来几千,上万人。LogicThread池这种是涉及到数据库的计算。...原创 2022-07-27 11:34:15 · 326 阅读 · 0 评论 -
游戏服务器中的排行榜设计
List和expireTime,之后的尝试上榜,就是直接把待更新的数据放到List中,然后进行排序,当然了,由于多线程的问题,需要加读写锁。随着访问次数的增加,访问多了,就自然会把数据全部刷新到Redis中,这样子大大减少了redis的访问频率。其实都是为了减少IO次数锁进行的一些优化,即使是Redis,也不能一直访问。先从Redis读取排行榜信息,然后存到内存List中。......原创 2022-07-21 10:38:23 · 714 阅读 · 0 评论