关于优化游戏服务器响应客户端消息的一点思考

现在假设有如下构建的游戏服务器,游戏服务器有一组gate服务器,用来验证客户端,并且通过gate服务器来与一组主服务器,然后主服务器与关系服务器进行通信。

其中relation服务器用来处理各种关系,例如好友关系,师徒关系等。现在有一个玩家A添加玩家B为好友,那么客户端发送给服务端的消息流程如上所示。首先gate收到客户端消息,进行验证等,然后转发给Main1服务器, 这里假设玩家A的信息存储在Main1服务器上,然后Main1服务器检测玩家A的各种要求,如果满足要求,则将消息转发给Main2服务器,这里假设玩家B在Main2服务器,然后Main2服务器进行各种检测,如果满足条件,则将消息转发给Relation服务器,Relation服务器再进行各种检测,然后回复消息给客户端。假设Main1的服务器检测和Main2的服务器检测都可以独立完成,那么消息逻辑可以改为:

上面的设计方案,假设玩家A和玩家B都在Gate1上。我们查看上面的两幅图,可以看出后面这幅图比第一幅图多出了一条消息,但是,响应客户端的消息,下面这幅图平均来说却只需要经过三条网络通信,上面的那种需要4条网络消息。也就是说,正常情况下,下面的方案响应客户端的速度更快。对客户端来说,这无疑是一个好的消息。

那么我们先考虑一下,采用下面这种方式需要解决的问题,首先Relation服务器需要同时等待Main1和Main2的消息,然后才可以处理,这个需要添加一定的缓存,还需要一定的区分同一条消息的机制,这个在有些情况下,可以通过协议ID来区分,另外,也可以通过一个例如64位ID来区分,如果Relation服务器对接收到的超过20s甚至更长时间的消息都不再处理,那么64位ID可以保证在这段时间内不会重复。这种机制不需要重复,只需要在relation服务器中接收到消息时,设置当前时间,然后每隔一段时间,例如1s中清理一下就可以了。这种问题的处理,也可以参考hadoop的reduce函数的处理,当然可以参考的资料很多。然后,这种方案需要玩家在同一个Gate上,对于很多游戏来说,一组服务器,一个Gate足以,那么这个问题,自然不用处理。对于有多个Gate的情况,也可以如果在同一个Gate上,就采用上述做法,如果不在同一个Gate上,就采用原来的做法,只需要在协议中进行区分就可以了。至于为此添加的协议中的额外字段,不会很长,对网络的增加的压力应该不大。从上来看,这种方式是一种可行的方案。

我们考虑一下这种方案存在的不利之处。首先网路中增加了一条协议,增加了一条Gate到Main的消息,增加了一条Main到Relation的消息,减少了一条Main到Main的消息。这个建议测试一下,查看一下这种通信协议的增加,会不会成为游戏服务器的瓶颈。如果Main服务器之间的通信原本比较多的话,那么这种改变,可以减少Main之间的通信量。然后,增加了设计的复杂度,尤其是Relation的复杂度,同时增加了Relation的内存占用。对于很多游戏来说,Main服务器的处理逻辑是瓶颈,这种设计方式,可以将部分需要Main服务器处理的逻辑,转交给Relation服务器进行处理。如果存在很多别的服务器,使用类似的处理的话,可能会减少Main服务器的压力,从而增加一组服务器的承载能力。所以说这种设计方式,在有些情况下,不仅可以增加服务端对客户端的响应速度,而且可以增加一组服务器的承载量。

上面只是提供了一种简单的设想,可以供设计游戏服务器的程序员予以参考,如果有什么好的建议或者意见,也欢迎反馈。

原文地址:https://www.cnblogs.com/albizzia/p/9265906.html

时间: 2024-10-09 00:56:10

关于优化游戏服务器响应客户端消息的一点思考的相关文章

服务器与客户端消息推送的原理

其实服务端与客户端实现消息推送的方式有几种: 1.客户端不断的查询服务器,检查新的内容,也就是所谓的pull或者轮询的方式: 2.客户端与服务器之间维持一个TCP/IP长连接(在HTTP1.1中,所有的请求都认为是长连接),服务器向客户端push: 3.当服务端有新内容的时候,发送一条类似短信的信令给客户端,客户端收到货从服务器下载新内容,也就是SMS的推送方式: 对于第一种方式有以下的缺点: 1.因为需要不断地轮询,所以手机会很耗电: 2.容易被系统杀死: 对于第二种方式: 我们首先来了解一下

Java Socket应用(六)——服务器响应客户端

转载请注明:http://blog.csdn.net/uniquewonderq 通过输入流来读取客户端信息,相应的时候通过输出流来实现. 服务端类的代码: package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; imp

客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)

今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些不同的想法. 首先,个人职业发展是否成功, 技术只是其中一小块,尤其是在大公司, 更多的是依靠所谓的软实力.作为一个对技术有追求的工匠,我们下面重点说技术相关的. 现在回头看计算机行业的发展,我们看到不同的发展阶段: 1. PC时代,这个时代离我们并不遥远, 也有是2000年前后, 该时代最鲜明的特征是Win

客户端技术的一点思考

今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些不同的想法. 首先,个人职业发展是否成功, 技术只是其中一小块,尤其是在大公司, 更多的是依靠所谓的软实力.作为一个对技术有追求的工匠,我们下面重点说技术相关的. 现在回头看计算机行业的发展,我们看到不同的发展阶段: 1. PC时代,这个时代离我们并不遥远, 也有是2000年前后, 该时代最鲜明的特征是Win

erlang 游戏服务器开发

http://blog.csdn.net/slmeng2002/article/details/5532771 最近关注erlang游戏服务器开发  erlang大牛写的游戏服务器值得参考 介绍本文以我的OpenPoker项目为例子,讲述了一个构建超强伸缩性的在线多游戏玩家系统.OpenPoker是一个超强多玩家纸牌服务器,具有容错.负载均衡和无限伸缩性等特性.源代码位于我的个人站点上,大概10,000行代码,其中1/3是测试代码. 在OpenPoker最终版本敲定之前我做了大量调研,我尝试了D

unity游戏开发之服务器与客户端或页面流转之自定义交互事件

引言: 1,游戏页面与页面的交互 (1)装备背包 (2)装备信息页面 在游戏开发中,2D页面之间,有时候少不了关联性,比如游戏的背包系统,玩家进入背包系统(见上图装备背包以及装备信息页面),点击装备,查看装备信息页面,一般卡牌类游戏这些信息页面都附带增加装备 属性值的功能,比如<放开那三国>里装备的强化功能,玩家花一定量的游戏货币强化了装备后,该装备信息页面里装备属性会随着刷新.但是关闭该装备信息页面后,背包系统 页面里对应的该装备描述也要随着改变,但是背包系统怎么知道装备信息页面里已经改变了

客户端请求、服务器响应及其HTTP状态码

一JSP客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信 息头的一部分来传送的.我们可以查阅HTTP协议来获得更多的信息. 下表列出了浏览器端信息头的一些重要内容,在以后的网络编程中将会经常见到这些信息: (1)HttpServletRequest类 request对象是javax.servlet.http.HttpServletRequest类的实例.每当客户端请求一个页面时,JSP引擎就会产 生一个新的对象来代表这个请求. re

Java Web学习(1): 客户端请求、服务器响应及其HTTP状态码

一JSP客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信 息头的一部分来传送的.我们可以查阅HTTP协议来获得更多的信息. 下表列出了浏览器端信息头的一些重要内容,在以后的网络编程中将会经常见到这些信息: (1)HttpServletRequest类 request对象是javax.servlet.http.HttpServletRequest类的实例.每当客户端请求一个页面时,JSP引擎就会产 生一个新的对象来代表这个请求. re

Java Web学习(15): 客户端请求、服务器响应及其HTTP状态码

一JSP客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信 息头的一部分来传送的.我们可以查阅HTTP协议来获得更多的信息. 下表列出了浏览器端信息头的一些重要内容,在以后的网络编程中将会经常见到这些信息: (1)HttpServletRequest类 request对象是javax.servlet.http.HttpServletRequest类的实例.每当客户端请求一个页面时,JSP引擎就会产 生一个新的对象来代表这个请求. re