Java游戏服务端开发
分享Java游戏服务端开发经验和技术总结
wgslucky
技术的道路,充满了挑战,每攻克一个问题时,也收获了成就,路漫漫其修远矣,吾将上下而求索。
展开
-
Java项目开发注释规范
上面@author 表示作者名,自己修改为自己的名字即,@date是时间,这个不是java doc标准的注释荐,但是idea会提示你添加为自定义的tag项。好的规范可以增加代码的阅读性及明确阐述代码的意义,它也是代码开发中重要的一部分。这也是为什么我们阅读spring的源码时,感觉非常舒适与单间的原因。所以,在我们开发代码时,就可以直接参考spring的注释写法,完善,丰富自己代码的注释。团队之间以这个为约定也是一个不错的选择。配置新创建的类的头注释。原创 2024-03-28 11:31:22 · 253 阅读 · 0 评论 -
dockerfile ENTRYPOINT 执行.sh脚本提示找不到文件或文件不存在 No such file or directory
解决Dockerfile启动时找不到文件的一种思路原创 2023-12-23 09:40:11 · 2111 阅读 · 1 评论 -
申请免费的ssl证书
下载acme.sh 工具脚本,地址:https://github.com/acmesh-official/acme.sh/wiki/Install-in-China。下载成功之后的acme.sh是一个目录,进去之后才是脚本。申请网站: https://freessl.cn/解密域名,添加cname跳转。然后就可以配置证书了。原创 2023-11-28 23:36:03 · 184 阅读 · 0 评论 -
idea gradle 项目打开总是先下载gradle压缩包
解决ideal加载gradle项目时,下载不了gradle安装包,下载超时的问题原创 2023-05-12 21:22:18 · 3870 阅读 · 9 评论 -
单一职责模式:解决大类对象和传参过多的问题
如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作,因此要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变则可将它们封装在同一类中。第二个是开始的时候这个业务不是那么复杂,但是随着业务的发展,变得越来越复杂,修改的地方也越来越多,这个时候就有一个量变到质变的过程,为了以后更好的维护,就需要对代码进行重构,而且重构时间越早越好,重构完成之后,后面的修改就方便了很多且影响也较小。原创 2022-10-05 21:52:12 · 884 阅读 · 0 评论 -
阿里一个面试题:使用两个线程,交替输出字母和数字
了解多线程并发操作的主要类示例原创 2022-06-26 13:56:08 · 283 阅读 · 1 评论 -
Error Code: 2013. Lost connection to MySQL server during query
今天使用mysql官方的图形化工具mysqlworkbench查询视图的时候,报了这个错误:Error Code: 2013. Lost connection to MySQL server during query如果不是磁盘满了,可以使用下面的方法解决:修改红框中的超时时间,默认是10秒,如果表数据太大,查询时间长,就会返回上面的那个错误。...原创 2022-05-19 09:47:40 · 4810 阅读 · 2 评论 -
jdk.tools:jdk.tools:jar must specify an absolute path but is ${JAVA_HOME}/lib/tools.jar
最近把mac本搞了一次升级,升级之后,maven打包突然就不能使用了,报错:jdk.tools:jdk.tools:jar must specify an absolute path but is ${JAVA_HOME}/lib/tools.jar因为在maven中配置了本地jdk的tools.jar工具包 <dependency> <groupId>jdk.tools</groupId> <artifactId>jdk.tools&l原创 2022-05-09 09:51:04 · 2148 阅读 · 0 评论 -
idea yml配置中显示java注释乱码
在java的配置类中,定义的字段中注释使用中文:/** * @author 王广帅 * @since 2022/4/14 22:01 */@Configuration@ConfigurationProperties(prefix = "app.server.config")@Datapublic class AppServerConfig { /** * 申请的appId */ private String appId; /** * 我原创 2022-04-15 01:08:59 · 2176 阅读 · 2 评论 -
IDEA mvn 报错GC overhead limit exceeded
在idea中添加maven的构建命令,执行的时候报错:[ERROR] GC overhead limit exceeded -> [Help 1]这是因为项目太大了,mvn在执行过程中内存不够了,需要在idea中给mvn配置足够大的内存原创 2022-04-13 00:17:57 · 1442 阅读 · 1 评论 -
JCE cannot authenticate the provider BC
我是使用的RSA非对称加解时遇到的这个问题,加密的原理不是很了解,有相关的文章可以详细学习,但是使用下面的方法解决了问题,在此记录一下:在java下找到 jre/lib/security/java.security,添加一行代码:security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider这里的9我理解应该是一种序号,如果当前电脑的java中已有其它的security.provider使用了9,新添加的使用10即可。原创 2021-11-28 12:18:59 · 1210 阅读 · 0 评论 -
游戏服务器单元测试实施的必要条件
说起单元测试,很多人都知道它是一个好东西,也有很多人认识到单元测试的好处之后,想在自己的项目中实施单元测试。但是往往是不尽人意,理想太丰富,实现太骨感,变成从调研到实施,再到放弃。这就值得我们静下心来研究一下,只有充分了解了它的本质和规律,才能更好的便用它。单元测试需要在服务器框架层面支持。单元测试不仅是业务的一部分,也是服务器框架的一部分,并且,它首先是服务器框架的一部分,然后才是业务的一部分。所以在设计服务器框架的时候,要充分考虑到单元测试的实施,把单元测试框架嵌入到服务器框架的设计之中,和整个服务器原创 2021-04-27 23:40:21 · 604 阅读 · 0 评论 -
Java 匿名类热更新失败的原因
一般来说,现在游戏服务器都实现了java代码热更新的机制,这样就可以不用重启服务器,在服务器运行的状态中修改一些Java代码,修改一些小Bug,这给我们带来了很好的方便,但是Java服务器热更新也有一些限制,比如不能添加新方法,不能修改原方法的签名(不能修改返回类型,不能原方法修改参数)等。但是有时候在不知不觉中就可能违反了这些限制,导致热更新失败。在服务器热更新对象的时候,一定要注意匿名类的热更新,它最容易引起方法参数不一致问题,导致热更新失败。即使强制替换了class文件,也会导致报错:java.la原创 2021-01-15 10:31:33 · 1353 阅读 · 0 评论 -
IDEA中如何在一个窗口中打开多个项目
idea在一个窗口如何打开多个项目在使用Spring进行微服务开发时,需要同时打开很多个项目,但是如果每一个项目都单独一个窗口的话,切换就很麻烦,最方便的就是在IDEA一个窗口中管理多个项目。在IDEA之中,它的一个项目就代码了一个工作空间,可以通过下面的方式,在一IDEA中的一个窗口中同时打开多个项目,这里说的项目其实就是IDEA定义的Modules.先创建一个空项目![image.png](https://img-blog.csdnimg.cn/img_convert/b26848549ec原创 2020-12-26 11:32:09 · 11568 阅读 · 0 评论 -
看阿里的代码Java是如何获取本地IP地址的
在服务器开发过程中,有时候为了方便,可以使用代码获取本机的IP地址,而不需要再手动配置了。阿里的代码一直是业界的标准,在看RocketMQ的源码的时候,看到了他们的一个获取本机IP地址的工具类,在这里给大家分享出来,有时候的拿来就可以使用。public static String getLocalAddress() { try { // Traversal Network interface to get the first non-loopback and non原创 2020-05-31 18:29:52 · 467 阅读 · 0 评论 -
既然使用Logback,应该对它多些了解(四)
1. Mapped Diagnostic Context (MDC)logback的设计目前之一就是可以很好的在分布式系统中使用。在一个服务系统中,一般都会有多个线程,不同的客户端请求由不同的系统处理。MDC类似一个缓存,当收到客户端的请求时,可以将一些信息放在MDC中,在记录日志的时候可以从MDC中直接获取。统一记录用户ID和请求ID在游戏服务器开发中,平时打印日志的时候,都需要打印用户的ID和请求ID,这样才能方便的找到是哪个用户的操作日志。一般情况下是这样做的:Log.system.debug原创 2020-05-17 12:48:39 · 263 阅读 · 0 评论 -
既然使用Logback,应该对它多些了解(三)
1. AsyncAppender 异步记录日志AsyncAppender仅仅是做为一个日志分发器存在,因此,它必须绑定到其它的Appender上面。AsyncAppender会将日志缓存在一个BlockingQueue之中,然后启动一个线程从队列中取日志输出。默认情况下,缓存队列的长度是256。如果缓存占了队列的80%的时候,AsyncAppender就会丢弃trace,debug,info级别的日志。如果不想丢掉日志,可以配置AsyncAppender的discardingThreshold为0。原创 2020-05-17 12:47:33 · 901 阅读 · 2 评论 -
既然使用Logback,应该对它多些了解(一)
1. 打印logback的内部状态信息import org.slf4j.Logger;import org.slf4j.LoggerFactory;import ch.qos.logback.classic.LoggerContext;import ch.qos.logback.core.util.StatusPrinter;public class HelloWorld2 { public static void main(String[] args) { Logger logg原创 2020-05-17 12:46:03 · 353 阅读 · 0 评论 -
终于理解了设计模式-创建型模式
1. 简单工厂模式简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式一般包含以下几个角色:工厂角色(Factory):负责对象的创建,直接面向需要创建新产品对象的调用者,屏蔽产品具体的实现。抽象产品角色(Product): 这里所说的抽象接口角色,原创 2020-05-17 12:45:16 · 258 阅读 · 0 评论 -
使用Spring Shell 快速开发自己的命令交互窗口
Spring Shell有时候,为了方便开发和测试服务器,并不需要一个漂亮的用户界面,使用一个简单的命令窗口即可。如下所示:这里介绍一个快速,方便,易用,简单的交互式命令窗口开发组件-Spring Shell没错,又是spring 生态中的。源码地址https://gitee.com/wgslucky/spring-shell-demo创建项目本项目是使用Eclipse作为开发的I...原创 2020-04-29 20:30:34 · 1245 阅读 · 1 评论 -
终于理解了设计模式-创建型模式
1. 简单工厂模式简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式一般包含以下几个角色:工厂角色(Factory):负责对象的创建,直接面...原创 2020-04-29 20:29:07 · 222 阅读 · 0 评论 -
RocketMQ是如何使用Netty框架的
Apache RocketMQ作为阿里开源的一款高性能、高吞吐量的分布式消息中间件,它的通信能力已得到业界的公认。它的通信层是借助于异常网络框架Netty实现的。在开发网络游戏的时候,Netty也常用于游戏服务器或网关的通信层框架,所以,可以通过学习RocketMQ是如何使用Netty框架,从中借鉴一此应用技巧。在RocketMQ中的rocketmq-remoting项目就是针对网络层封装的项目...原创 2020-04-12 10:43:03 · 2004 阅读 · 0 评论 -
RocketMQ Namesrv服务启动时的参数配置
上篇文章说了一下在Namesrv启动时,它主要做了什么事情,从中可以知道,如果想正确的启动或修改Namesrv的启动配置时,会有几种不同的方式。添加日志配置文件如果是在本地Eclipse中使用Rocketmq的源码项目启动,需要添加日志配置文件,在项目下创建conf文件夹,添加配置文件:logback-namesrv.xml,内容如下:<?xml version="1.0" encod...原创 2020-04-10 10:17:26 · 4014 阅读 · 0 评论 -
Rocketmq的Namesrv服务启动时都做了什么
rocketmq-namesrv服务的启动类是NamesrvStartup。在启动的时候,首要的加载两个配置文件的信息,这两个配置文件对应的类是NamesrvConfig和NettyServerConfig。NamesrvConfig它的配置内容是:private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PR...原创 2020-04-10 10:15:28 · 610 阅读 · 0 评论 -
游戏服务器开源框架(xinyue-game-frame)
今天给大家介绍一个开源的游戏框架,它是基于Spring Cloud + Netty实现的一个分布式游戏服务器框架,支持负载均衡,集群部署,动态扩展和伸缩,能基本满足休闲游,卡牌游戏,SLG游戏的服务器框架快速搭建。此框架配合Unity3d,提供了一个简单的捕鱼游戏案例,方便大家学习。源码克隆地址:https://gitee.com/wgslucky/xinyue-game-frame游戏案例地...原创 2020-03-24 08:56:02 · 6227 阅读 · 0 评论 -
Netty零拷贝之CompositeByteBuf实际用法
Netty所谓的零拷贝就是在数据序列化操作的时候,尽量减少数据的复制。比如将一个byte[]转化为ByteBuf,如果这样写,就会多一次数据的复制: String a = "ccc"; byte[] bytesSrc = a.getBytes(CharsetUtil.UTF_8); ByteBuf byteBuf = Unpooled.buffer(...原创 2020-03-23 09:56:13 · 270 阅读 · 0 评论 -
游戏服务器架构-数据持久化之数据复制
为了提高游戏服务器的吞吐量,玩家数据会在登陆的时候加载到服务器内存之中,在玩家玩游戏的过程中,操作的都是内存中的数据。但是这样子设计,如果服务器重启时,没有及时将数据更新到数据库,数据就会有丢失的风险。在设计服务器架构的时候,这个问题是架构师必须要解决的。因为在业务开发的时候,开发人员不应该关心数据的持久化。想要保证数据百分百不丢失,就需要考虑极端的情况,但是这样所付的时间和精力是很庞大的,而且...原创 2020-01-08 12:09:01 · 1107 阅读 · 0 评论 -
Unity3d C# Socket异步发送与接收数据
在网络游戏开发中,一些游戏需要使用长连接的方式进行网络通信,即使用Socket建立长连接。那么在Unity3d中,如何使用C#与服务端建立长连接呢?为什么 要说使用异步呢?我们知道,在Unity3d中,每个游戏画面的播放都是以帖的概念循环播放的。而且只能在UI线程中播放,在其它线程不可以操作UI有关的东西,这都是网络通信需要解决的问题。使用Socket创建连接众所周知,在游戏客户端启动之后,一......原创 2019-12-08 23:25:26 · 3929 阅读 · 0 评论 -
使用Spring Cloud Gateway搭建游戏服务网关(1)
在游戏服务器构架中,Web服务是其中重要的部分之一,像获取公告,游戏区列表,账号登陆与注册,礼包码的使用充值等,这些都可以使用Web服务实现,快捷又方便扩展,通过简单的配置就可以以集群的方式提供服务。 在架构设计中,最重要的一个概念就是架构必须有足够的扩展性,可以随着业务量的增加,可以通加增加服务器的数量来提升服务能力,以适应业务的增涨。比如初始的构架部署是这样的:再过段时间,随着业务的...原创 2019-10-28 01:44:57 · 1218 阅读 · 0 评论 -
大型多人在线游戏服务器架构设计
由于大型多人在线游戏服务器理论上需要支持无限多的玩家,所以对服务器端是一个非常大的考验。服务器必须是安全的,可维护性高的,可伸缩性高的,可负载均衡的,支持高并发请求的。面对这些需求,我们在设计服务器的时候就需要慎重考虑,特别是架构的设计,如果前期设计不好,最后面临的很可能是重构。一款游戏服务器的架构都是慢慢从小变大的,不可能一下子就上来一个完善的服务器构架,目前流行的说法是游戏先上线,再...原创 2016-09-24 20:37:54 · 23047 阅读 · 3 评论 -
游戏服务器开发都要学什么
一,游戏服务器开发工作介绍近来遇到有很多人想从其它开发领域转到游戏服务器开发行业上来,他们或许觉得游戏服务器开发工资高,或许觉得做游戏服务器需要掌握的技术更高级,可以锻炼自己,或许觉得想换个环境等等。不管出于什么原因吧,做为一名几年的游戏服务器开发者,当然是持欢迎态度的,那么我就先介绍一下游戏服务器开发的工作吧,游戏服务器开发具体要做哪些工作呢?1,团队沟通基本上不管做什么开发,都是一...原创 2019-08-22 17:26:27 · 32588 阅读 · 7 评论 -
大型多人在线游戏服务器架构设计 - RPC封装原理
RPC框架分为客户端部分与服务端部分:RPC-client的部分又分为:(1)序列化反序列化的部分(上图中的1、4)(2)发送字节流与接收字节流的部分(上图中的2、3)前一篇文章讨论了序列化与范序列化的细节,这一篇文章将讨论发送字节流与接收字节流的部分。客户端调用又分为同步调用与异步调用同步调用的代码片段为:Result = Add(Obj1, Obj2转载 2016-09-22 22:31:29 · 9350 阅读 · 0 评论 -
游戏服务器背包设计与实现
在游戏开发中,背包是一个非常重要的功能。几乎每个复杂点的游戏都会有背包的功能。不管是手游戏还是网页游戏,不管是SLG游戏,还是ARPG游戏,背包是必不可少的。背包的功能根据策划的要求,有的简单,有的复杂。以下我们就讨论一下几种游戏服务器背包的实现。1,简单的游戏背包设计简单的游戏背包到底简单到什么程度呢?那么这个游戏背包只是用来存放物品,不需要记录物品在背包中的位置,只需要记录物品的id和...原创 2016-11-19 01:23:38 · 7392 阅读 · 2 评论 -
common-pool2对象池的详解与使用
我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等。在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响。一种办法就是使用对象池,每次创建的对象并不实际销毁,而是缓存在对象池中,下次使用的时候,不用再重新创建,直接从对象池的缓存中取即可。为了避免重新造轮子,我们可以使用优秀的开源对象池化组件apache-co原创 2016-11-26 20:02:20 · 3189 阅读 · 0 评论 -
游戏服务器生成全局唯一ID的几种方法
比如手机游戏,可以使用简单的redis方式,简单不容易出错,由于这种游戏单服并发新建id量并不太大,完全可以满足需要。而对于大型的世界游戏服务器,它本身就是以分布式为主的,所以可以使用snowflake的方式,上面的snowflake代码只是一个例子,需要自己根据自己的需求去定制,所以有额外的开发量,而且要注意上述所说的注意事项转载 2016-10-26 22:37:21 · 3807 阅读 · 0 评论 -
棋牌游戏服务器架构设计
一,棋牌类服务器的特点1,棋牌类不分区不分服一般来说,棋牌游戏都是不分区不分服的。所以棋牌类服务器要满足随着用户量的增加而扩展的需要。2,房间模式即在同一局游戏中就是在同一个房间中,同一个房间中的人可以接收到其他人的消息。3,每个房间的操作必须是顺序性这个特性类似与一般游戏的回合制,每个玩家的操作都是有顺序性的。二,需要解决的技术点1,数据共享因为棋牌类游戏不分...原创 2017-02-21 21:41:42 · 7567 阅读 · 2 评论 -
游戏协议加密(1)-消息摘要
消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。消息摘要采用单向Hash函数将需加密的明文"摘要"成一串128bit的密文,这原创 2016-08-16 21:42:29 · 3702 阅读 · 0 评论 -
游戏服务器设计之观察者模式
在游戏开发中,不同的系统之间可能都会有交互,怎么设计这些系统,可以让他们达到解藕,增加系统的可扩展性,这里我们可以使用观察者模式,让系统更加简洁。原创 2016-10-17 22:35:53 · 1706 阅读 · 0 评论 -
游戏服务器网关设计
网关,通俗的讲,是消息达到服务器的第一关,它负责与客户端建立连接,接收客户端发送过来的消息,并对消息进行验证,分发等。不同的服务系统网关负责的功能多少可能不太一样。但是本质是不变的。1,网关的功能1.1 与客户端建立连接这个应该是网关最基本的网功了,一个服务做为网关,所有客户端来的消息都必须先到达这里。客户端与网关可能是长连接,比如socket,也可以是短连接,比如http。1...原创 2017-05-30 18:53:31 · 10654 阅读 · 0 评论 -
Spring Cloud Gateway Ribbon 自定义负载均
在微服务开发中,使用Spring Cloud Gateway做为服务的网关,网关后面启动N个业务服务。但是有这样一个需求,同一个用户的操作,有时候需要保证顺序性,如果使用默认负载均衡策略,同一个用户的请求可能会转发到不同的服务实例上面。所以需要实现一个负载均衡规则。1,重写LoadBalancerClientFilterimport static org.springframework...原创 2019-03-15 16:06:17 · 5643 阅读 · 5 评论