理解游戏服务器架构-部署架构

news2024/11/26 4:27:40

目录

前言

我所理解的服务器架构

什么是否部署架构

部署架构的职责

进程业务职责

网络链接及通讯方式

   与客户端的连接方式

   服务器之间连接关系

数据落地以及一致性 

数据库的选择

数据访问三级缓存

数据分片

 读写分离

分布式数据处理

负载均衡

热更新

配置更新

合服

合服的痛点

解决合服数据重叠问题

总结:


前言

       本人做游戏多年,当时从开发棋牌游戏开始阴差阳错进入游戏行业,服务器架构做过很多套,我曾经的小伙伴拿着我设计的架构带到新的公司,都有一个不错的表现。但是发现一个现象,后面设计的架构永远比前面设计的更为优秀或良好,也许随着时间的推移,个人技术以及新技术与理念的引入、新的业务场景等多种原因,让我们不得不对架构做一定的调整。

        我经常问我的求职者一个问题,你怎么理解服务器架构,架构两个词从字面上理解很好理解,如果对于一个系统工程了说,它可以理解为系统工程的顶层设计,如果是一个简单的单一功能,那它是单一个功能总体设计思路。   但是我们今天所讲的架构是一个承载百万人同时在线的架构设计,注定它不是一个简单问题。它包含着技术开发人员所需要掌握的技术需要的广阔性和深度,并拥有强力的设计理念。

我所理解的服务器架构

服务器架构我的理解为三个方面,它包含部署架构和逻辑底层架构、业务架构。

                

什么是否部署架构

部署架构是在考虑业务职责和各个场景的节点隶属关系、连接关系以及业务分割的服务器的概括性架构,它确定了服务器进程之间的部署关系。

部署架构的职责

     在这一层,我们应该抛开编程语言的限制,考虑进程业务职责,网络连接形式、数据落地以及一致性问题、扩展性问题、负载均衡问题、稳定性问题、热更新问题等

                        

进程业务职责

进程业务职责我们应该考虑,根据业务进行功能拆分,并确定进程应该做什么和它主要功能是什么,是我们赋予各个进程具体职责。

以游戏服务器为例,它应该需要为用户做登录认证的登录服;职责为统一网络连接和安全的网关服;为任务和养成系统等玩家具体玩法需要的游戏服;担负着全服排行榜和ID分配等全局功能功能的世界服;需要好友、聊天 等功能的社交服;需要保存数据的数据库服等

网络链接及通讯方式

   与客户端的连接方式

        当我们确定了业务职责时,那么用什么样的通讯方式就是我们具体要考虑的问题。首先我们

        需要思考一个问题,我们的业务那些进程需要与玩家进行连接呢?在游戏中一般,登陆服和

        网关服是需要与玩家进行连接。

        登陆服往往通过http的协议进行验证登陆,让然也可以选择TCP方式,以及后期发展的

        websocket的方式。websocket我们可以看着是http的变种,其实它最核心的还是http。

        当然根据实际业务场景有可能选择udp。帧同步的战斗服就是可确认的rudp协议方式。

             

   服务器之间连接关系

        在服务器部署架构中,我们要确认的一项重要内容之一就是多个服务器进程之间能够直接通

        讯。某个业务进程是被动连接还是主动连接?是一个连接还是多个连接?是一对多的关系还

        是一对一的关系?

      在连接关系中,我们同时要考虑服务器进程之间用何种方式进行通讯。我最近设计的一套服务 

      器架构,通过zookeeper进行服务器配置更新,每个服务器有自己的一个服务器节点ID,服务

      器节点ID通过zookeeper获得自己配置信息,同时将本节点注册到zookeeper上,其他节点监听

      到某个节点注册信息,zookeeper按照配置规则进行节点自动连接,一切做到自动化。

     在数据库的设计方式,我将数据功能设计成SDK的方式,数据库节点是作为server端,而使用

     数据库的为Client端,任何节点想要数据库的操作直接使用数据库SDK就可以,非常方便。

          

数据落地以及一致性 

        数据库的选择

对于业务,我们应该充分分析它的属性以及业务当量,根据业务属性和当量我们选择合适我们自己需要的数据库类型,通用的数据库有mysql、orcale、mongoDB

             

但们也有各自的缺点,MySQL、Oracle和MongoDB各自的缺点如下:

  1. MySQL:功能相对较少,并发控制能力有限,数据安全性较低。
  2. Oracle:劣势在于成本较高,不是开源数据库,需要购买许可证才能使用。
  3. MongoDB:不适合存储关系型数据,数据一致性相对较弱,且没有类似SQL的查询语言,查询功能相对较弱

对于游戏开发,游戏本身的数据库我可能选择mongodb,因为完美的将player玩家对象整个丢进我们的数据库中,简单并且高效实现。当然在window系统下,你也可以选择sqlServer,但是发它只能在window操作系统下运行。

数据访问三级缓存

在早期的数据访问和存储是进程直接操作数据库的。由于数据库数据往往保存在磁盘中,存储和访问效率就往往是非常低,尤其是访问量比较大时容易造成拥堵。

所以后来为了提高访问效率,在用户个人数据方面,为了提高访问数据的效率可能我们需要用到三级缓存机制,即:memory、redis/memcache、db数据落地三层设计。

                

对于热点数据,首先我们从memory中查找,没有在查找redis或memcache,最后才查找database。

数据分片

如果一个业务逻辑都在某个进程中,那么数据一致性相对就简单了许多。那么更多的考虑的是因为单点会不会出现执行效率和性能的问题以及如何提高承载上线,可是问题并没有那么简单。

例如:游戏服的社交往往处理好友、聊天、帮会等通用数据,如果在拥有天量用户的游戏中,我们不可能一个服务器节点保存所有的这些数据。可能进行数据的在进程的分片,数据如何分片就需要我们做一定的考量。同样我们的角色数据不可能只有一个数据库,可能需要架设数据库服务器集群来做处理,同样表格数据也需要分片等等,让访问数据更为高效。

分片算法:

            

 读写分离

当然我们不可能所有数据都进行分片,比如拍卖行数据以及处理。拍卖行数据这个系统的特性是用户基数达到一定量及的时候,读数据的压力比改数据的压力会大很多,在设计初期我们可能需要考虑读写分离。

读写分离适用于程序使用数据较多,而更新较少、查询较多的情况。此时,设计主从主从同步,可以减少数据库压力,提高性能。

拍卖行或者商行,更新相对较小,访问量较大,当我们在全局服更新数据时,同步更新到其他服,玩家访问拍卖行或者商行时,访问的是本服的即可,这样减少了全局服的压力。

数据库数据的IO(分库分表)

在服务器性能瓶颈中往往数据库的IO会拖累整个优秀的程序设计。

MySQL为例:数据库中的表超过1000000条记录时,效率会受到多种因素的影响。以下是一些可能影响数据库效率的关键因素:

硬件性能:

  • 磁盘I/O:SSD比传统的HDD更快。
  • 内存:足够的RAM可以确保更多的数据和索引被缓存在内存中。
  • CPU:强大的CPU可以更快地处理查询。

数据库设计:

  • 表结构:正确的数据类型、适当的索引和分区可以提高查询性能。
  • 索引:为经常用于查询条件的列创建索引。
  • 规范化:避免不必要的数据重复。

查询优化:

  • 查询语句:避免使用SELECT *,只选择需要的列。
  • 避免全表扫描:使用WHERE子句和索引来限制查询的数据量。
  • 连接优化:尽量减少表之间的连接,特别是当连接条件没有索引时。

数据库配置:

  • 缓冲池大小:例如,InnoDB的缓冲池大小应足够大,以容纳大部分的数据和索引。
  • 日志和二进制日志设置:这些设置可以影响写入的性能。

并发性:

  • 高并发读写可能会导致性能下降。
  • 使用连接池可以减少创建和关闭连接的开销。

数据分布:

  • 如果数据分布不均,某些查询可能会更慢。

网络延迟:

  • 如果应用程序和数据库不在同一台机器上,网络延迟也可能成为问题。

了解了更多的数据库引起瓶颈问题,除了设计修改硬件和配置属性时,我们应该避免大的表格的出现;同时,尽可能避免只有一个全局数据库的可能性。

所以应当对于大表格数据进行分表,对于一个数据无法承载的应当通过集群和分库的方式解决数据IO的瓶颈。

分布式数据处理

服务器数据的落地不应该仅仅考虑当前问题,而要考虑后期扩容或随着时间的变化服务器减少问题。不应该只考虑本线程问题而考虑跨线程问题;只考虑本进程而不考虑跨进程问题。

在实际运用中,有可能有多个进程进行同样的逻辑处理,只是处理不同的数据而已。例如:社交服处理的都是社交相关的逻辑的数据,但是一个玩家的涉及需要修改的数据只能在单个社交服处理,不能两个社交服都可以修改一个玩家的同一份数据。

一句话总结,对于数据落地,我们尽可能让数据安全地保存,同一份数据的修改同时有且只有一个地方进行修改,并用一切手段提高访问和落地的效率。

负载均衡

负载均衡是决定了游戏稳定和承载上线的总要环节,作为服务器后台开发,那一定要知道我们的瓶颈在哪里,要知道单个进程的承载和单个服的承载,要对服务器前期要有个预设值,通过这个这个预设值来进行总体的实际。服务器的瓶颈通用的有网络IO,数据库IO、内存、CPU性能等问题  

         

我们不能实现一个服务器只有单一节点的运用。如果有,那么它的体量也大不到哪里去。所以我们要知道如何进行负载均衡,如何对服务器进行横向分布,如果在游戏上线前期没有做充分的准备,出现问题都有可能是对项目致命的问题。我们不仅仅考虑正确的情况下,同时我们要对外部危险攻击做好相应的准备。

在这里分享两个例子:

第一个案例:

有一天我曾经下面的一个小伙伴去其他公司负责整个地方棋牌项目。棋牌项目的特点就是被ddos攻击的重灾区,同样类型的游戏,市场就那么大,你抢别人的蛋糕,不有点硬技术可不行。当时小伙伴打电话给我,问怎么解决?最终我发现它的登录和网关是没有做负载均衡的。对方一直打他们的login服务器和网关,登录和网关它们没有做负载均衡,这种情况只能先上高防,后期把负载均衡加上,出现类似的情况,将新玩家导入到新的服务器,让ddos攻击有高防的机器,这样影响就小了很多。当然还有很多技术细节,这里就不一一列举了。由于小伙伴在这块考虑不足,负载均衡没有加上,最后这个项目刚开始一周就胎死腹中。

第二个案例:

我面试过应聘我们后端小主程的一个小朋友,他们公司做了一个大IP项目,腾讯发行他们家的游戏,社交、工会、跨服战等功能都在单个全局服,最后发现就是这个单个全局服成了整个游戏服务器的败笔。腾讯当天导量300多万,直接将服务器整崩溃了。腾讯推的量一般是短时间巨量,当导入巨量项目组接不住时,腾讯不会再给你导入多少量了,这个项目实在可惜。

以两个失败的案例告诉我们,一个差的架构可以间接杀死一个好的项目,服务器架构的最大体现往往在游戏上线的那刻尤为重要。负载均衡没有做好,可能造成项目不可挽回的损失,给我们巨大的流量和推广也无法接住,着实可惜。

为了实现负载均衡,我们可以通过nginx、动态服务器列表、设计上扩容组合实现。在登录时,一定要设计排队功能,当有大当量用户突然访问时,最起码有一个保底机制不至于出现登录挤兑情况影响。

     

Nginx(engine x)是基于 C 语言实现的一个高性能、轻量级的 HTTP 和反向代理 Web 服务器,同时也提供 IMAP/POP3/SMT服务。

Nginx 既可用作静态服务器,提供图片、视频服务,也可用作反向代理或负载均衡服务器。Nginx 作为反向代理,当代理后端应用集群时,需要进行负载均衡。

Nginx 提供了对上游服务器(真实业务逻辑访问的服务器)的负载均衡、故障转移、失败重试、容错、健康检查等功能,以一种廉价有效透明的方法扩展了网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
Nginx 具有高并发连接、低内存消耗、低成本、配置简单灵活、支持热部署、稳定性高、可扩展性好等优点,这些优点都得益于其优秀的架构设计(模块化、多进程和多路I/O复用模型)。

                                     

热更新

服务器热更新是指在不停机或者不关服的前提下,对服务器上的应用程序或系统进行更新。它的好处在于能够保证系统的高可用性,避免了系统在更新过程中的不可用现象,并且将系统升级的周期缩短到了最小

实践证明,每次重启服务器,都有可能一定概率造成玩家的流失,现如今获取一个付费用户是多么的不容易。更新可以分为,配置更新、代码更新、合服等

        

配置更新

配置更新是最频繁的更新,极限情况一天可能都要更新好几次,如果每次都要重新启服来进行更新,损失太大了。频繁的启服对用户的体验很不友好,同时让人不敢在游戏中消费。

所以配置的更新一定是热更新实现。当配置需要更新的时候,可以通过GM命令通知各个服务器,进行配置的重新装载。

代码热更新

对于代码,并不是所有代码都支持热更新的,对于Java它所支持的热更程度为代码的函数和成员变量都不能改变,但是函数内部的实现能够变化。如果是代码C++和Lua的结合,能够比较友好的实现代码热更新。所以代码的更新也取决与所选择的逻辑编程语言。

对于语言的限制技术上往往是有无力感的,因为对于技术的我们没有办法做什么。但是我有一种策略是可以将影响做到最小,当我们需要更新代码的时候,可以将现有玩家快速切换到更新好了的服务器,同时将当前服务器关闭进行更新,等当前服务器更新成功后再让新玩家进入当前服务器。当然这种情况玩家并不会无感,但起码影响小了很多。

合服

合服的痛点

肯定奇怪,合服为什么属于热更新范围内。其实合服也是更新的一部分。

合服通用做法是将需要合服的服务器关闭,同时进行数据库合并。但是并没有那么简单,因为1服和2服的数据往往不相通的,那么某些ID作为数据Index(索引)就有可能重叠问题。

比如:玩家数据库表格以playerId作为index(索引),采用自增的方式,1服如此,2服如此,自然就会有重叠的地方。而且之中情况是连锁反应的,因为玩家的道具、任务表格都是以playerId作为关键index(索引),这就一一去重,非常麻烦,即使我们客户通过工具来实现,实际起来非常的费劲,总有特例需要处理。

解决合服数据重叠问题

能够有一个长效机制让我们合服不怎么麻烦呢?答案肯定是有的,ID的唯一性其实给了启发。如果有一个机制能够让ID在不同进程之间产生不同无法重叠的ID,那么是否不是就可以解决ID重用问题?

是的,我们可以参考雪花算法。雪花算法生成的ID为64位整数,具体的格式如下:

0 | 0000000000 0000000000 0000000000 000000000 | 00000 | 00000 | 000000000000

其中,第1位为符号位,固定为0;接下来的41位为时间戳(毫秒级),记录了生成ID的时间;然后是10位的机器ID,5位数据中心ID和5位工作机器ID,用于标识不同的机器;最后是12位的序列号,用于表示在同一毫秒内生成的多个ID的顺序。

实际使用时,每台机器需要配置一个唯一的机器ID,以保证生成的ID不与其他机器生成的ID重复。同时,需要注意时钟回拨的问题,即当本地时钟发生回拨时,可能会导致生成的ID出现重复或者乱序的情况。

当然这只是抛砖引玉,还有其它类似算法,这里就不一一详举了。

我们在给角色命名或修改名字的时候,同样会出现类似的重叠问题。这以问题的解决就有待于读者去思考了。

总结:

在部署架构阶段,我们考虑的是我们架构设计的愿景,或者说是我们向往架构的设计的蓝图。告诉我们将要做什么,确定我们最重要的目标和方向,划分职责。犹如宪法在法典中的意义一样重要,它是指导思想。接下了的逻辑顶层架构设计以及业务架构设计都要依照部署架构的设计而进行落地。

我们应该抛开语言而考虑每个进程需要做什么,它们之间的连接关系,数据落地和分割,瓶颈问题的解决,这样从全局上考虑问题,思路就非常清晰了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1557363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flowable-ui后台显式非中文

把flowable-ui的war包发布后,后台界面显示的是非中文 用的是6.7.2版本,经过了解该版本是有国际化配置文件的,支持中文 猜测可能是浏览器语言导致未显示中文,在控制台输入navigator.language,查看到果然是英文 解决方案…

[项目实践]---RSTP生成树

[项目实践] 目录 [项目实践] 一、项目环境 二、项目规划 三、项目实施 四、项目测试 |验证 ---RSTP生成树 一、项目环境 Jan16 公司为提高网络的可靠性,使用了两台高性能交换机作为核心交换机,接入层交 换机与核心层交换机互联,形成冗…

【Linux】生产者消费者模型{基于BlockingQueue的PC模型/RAII风格的加锁方式/串行,并行,并发}

文章目录 1.认识PC模型2.基于BlockingQueue的PC模型2.1串行,并行,并发2.2理解linux下的并发2.2RAII风格的加锁方式2.3阻塞队列2.4深入理解pthread_cond_wait2.5整体代码1.Task.hpp2.lockGuard.hpp3.BlockQueue.hpp4.pcModel.cc 3.总结PC模型 1.认识PC模型…

蓝桥杯第十三届电子类单片机组程序设计

目录 前言 单片机资源数据包_2023 一、第十三届比赛省赛 1.比赛题目 2.赛题解读 二、部分功能实现 1.继电器的开启与关闭 2.长按切换显示状态功能的实现 3.对于温度传感器小数部分的处理 4.其他处理 1)关于数码管显示小数的处理 2)关于5s后继…

(完结)Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(三)项目优化

本文参考自 Springboot3微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第(三)章——项目优化,本篇将讲解该项目最后的优化部分以及一些压测知识点 本章目录 一、压力测试-高并发优化前后的性能对比1.压力测试相关…

系统需求分析报告(原件获取)

第1章 序言 第2章 引言 2.1 项目概述 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 第4章 项目建设内容 第5章 系统安全需求 5.1 物理设计安全 5.2 系统安全设计 5.3 网络安全设计 5.4 应用安全设计 5.5 对用户安全管理 …

Android 自定义EditText

文章目录 Android 自定义EditText概述源码可清空内容的EditText可显示密码的EditText 使用源码下载 Android 自定义EditText 概述 定义一款可清空内容的 ClearEditText 和可显示密码的 PasswordEditText,支持修改提示图标和大小、背景图片等。 源码 基类&#xf…

相机标定学习记录

相机标定是计算机视觉和机器视觉领域中的一项基本技术,它的主要目的是通过获取相机的内部参数(内参)和外部参数(外参),以及镜头畸变参数,建立起现实世界中的点与相机成像平面上对应像素点之间准…

枚举--enum和动态内存管理(malloc和free)

枚举---enum&#xff1a;它的本意就是列举事物&#xff0c;比如&#xff0c;颜色和性别&#xff0c;则代码为&#xff1a; #include<stdio.h> //枚举的示例&#xff1a;性别&#xff0c;颜色 enum sex//性别 {MALE,FEMALE,SECRTY }; enum clore//颜色 {ROW,BLUS,GREEN …

查找某数据在单链表中出现的次数

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct LinkNode {ElemType data;LinkNode* next; }LinkNode, * LinkList; //尾插法建立单链表 void creatLinkList(LinkList& L) {L (LinkNode*)mallo…

Vue系列——数据对象

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>el:挂载点</title> </head> <body&g…

本地项目上传到GitHub

本文档因使用实际项目提交做为案例&#xff0c;故使用xxx等字符进行脱敏&#xff0c;同时隐藏了部分输出&#xff0c;已实际项目和命令行输出为准 0、 Git 安装与GitHub注册 1&#xff09; 在下述地址下载Git&#xff0c;安装一路默认下一步即可。安装完成后&#xff0c;随便…

【面试经典150 | 动态规划】零钱兑换

文章目录 Tag题目来源解题思路方法一&#xff1a;动态规划 写在最后 Tag 【动态规划】【数组】 题目来源 322. 零钱兑换 解题思路 方法一&#xff1a;动态规划 定义状态 dp[i] 表示凑成总金额的最少硬币个数。 状态转移 从小到大枚举要凑成的金额 i&#xff0c;如果当前…

电动车“锂”改“铅”屡被查?新国标或疏于考虑用户真实需求

最近几个月&#xff0c;电动自行车又走到了舆论中心。 “315期间”&#xff0c;不少媒体集中报道了超标电动自行车改装上牌事件。3月18日至20日&#xff0c;新华社推出电动自行车安全隐患系列调查&#xff0c;聚焦点之一就是改装超标问题。而在近段时间&#xff0c;综合媒体报…

MarTech调研总结整理

整体介绍 概念解释&#xff1a; Martech是一种智慧营销的概念&#xff0c;将割裂的营销&#xff08;Marketing&#xff09;、技术&#xff08;Technology&#xff09;与管理&#xff08;Management&#xff09;联系在一起&#xff0c;Martech将技术溶于全营销流程中&#xff0…

基于Java实验室预约管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

《操作系统导论》第14章读书笔记:插叙:内存操作API

《操作系统导论》第14章读书笔记&#xff1a;插叙&#xff1a;内存操作API —— 杭州 2024-03-30 夜 文章目录 《操作系统导论》第14章读书笔记&#xff1a;插叙&#xff1a;内存操作API1.内存类型1.1.栈内存&#xff1a;它的申请和释放操作是编译器来隐式管理的&#xff0c;所…

FebHost:意大利.IT域名一张意大利网络名片

.IT域名是意大利的国家顶级域名&#xff0c;对于意大利企业和个人而言,拥有一个属于自己的”.IT”域名无疑是件令人自豪的事。这个被誉为意大利互联网标志性代表的域名,不仅隐含着浓厚的意大利文化特色,还为使用者在当地市场的推广铺平了道路。 对于那些希望在意大利市场建立强…

2核4G服务器可以承载多少用户?卡不卡?

腾讯云轻量应用服务器2核4G5M配置性能测评&#xff0c;腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;并发数10&#xff0c;支持每天5000IP人数访问&#xff0c;腾讯云百科txybk.com整理2核4G服务器支持多少人同时在线&#xff1f;并发数测试、CPU性能、内存性能、…

手把手在K210上部署自己在线训练的YOLO模型

小白花了两天时间学习了一下K210&#xff0c;将在线训练的模型部署在K210&#xff08;代码后面给出&#xff09;上&#xff0c;能够识别卡皮巴拉水杯&#xff08;没错&#xff0c;卡皮巴拉&#xff0c;情绪稳定&#xff0c;真的可爱&#xff01;&#xff09;。数据集是用K210拍…