用c++搭建游戏服务器的一些疑问
小弟最近在学习c++后端,目前的水平是可以用epoll多路io复用,然后现在在用libevent,并且用主从reactor进行并发。目前第一个小目标是做一个可以组播、广播的聊天服务器,协议用tcp。现在遇到了一些问题,希望有大佬可以解答我的疑惑。
问题1:
我在实现多reactor多线程这种模型的时候,实现方式是“主reactor”在main中只负责监听accept,然后用几个线程去实现子reactor监听write和read。使用线程来实现子reactor对不对?
问题2:
我了解了一些关于服务器架构上的资料,似乎他们使用到了消息队列,我觉得后面我要是做游戏服务器的话,大概率,会用到这个技术。但是我有些不明白这个东西该怎么和libevent结合在一起,或者说,使用消息队列的对象是谁,希望可以有老哥详细讲一下这个流程。
问题3:
假设,我现在要做一个游戏服务器,里面有100个怪物,我是不是只需要一个线程来处理这100个怪物的血量和其他属性。还是说我专门弄一个进程来管理游戏的业务。那是不是要弄聊天服务器,战斗服务器,等等等等服务器,然后一个一个独立启动?因为我以前尝试弄私服游戏服务器搭建的时候,他们似乎都是好几个服务器程序各自启动的。
谢谢大佬! 问题1:多Reactor多线程模型
每个子Reactor线程需要独立的事件循环来处理IO事件,而不是简单地在主Reactor中分发事件给线程。每个线程应该拥有自己的事件驱动框架,如libevent,以独立处理事件。
线程之间的通信需要谨慎处理,以避免竞态条件。可以使用线程安全的数据结构或互斥锁来保护共享资源,例如连接池。
线程数目的选择需要平衡性能和系统资源。过多的线程可能导致线程竞争和上下文切换开销增加。
问题2:消息队列
消息队列是用于实现不同组件之间异步通信的强大工具。在服务器开发中,你可以使用消息队列来实现以下功能:
异步任务处理:将耗时的任务放入消息队列,然后由工作线程异步处理,以避免阻塞主线程或IO线程。
事件通知:不同组件之间可以通过消息队列来传递事件通知,例如,游戏中的玩家之间的消息通信可以通过消息队列来实现。
与libevent结合使用消息队列时,你可以考虑以下模式:
主Reactor接收到连接后,可以将连接句柄交给工作线程池,工作线程池负责处理具体的IO操作。
工作线程可以使用消息队列来协调任务的执行,例如,将接收到的数据放入队列,由其他线程来处理。
在游戏服务器中,可以使用消息队列来处理玩家之间的消息通信,例如,玩家之间的聊天消息可以通过消息队列传递。
问题3:游戏服务器的架构
游戏服务器的架构取决于游戏的需求和规模。一般来说,游戏服务器可以分为多个组件,每个组件独立运行:
登录服务器:负责用户登录和身份验证。
聊天服务器:处理玩家之间的聊天和社交功能。
战斗服务器:负责处理游戏战斗逻辑。
数据库服务器:用于存储和管理游戏数据。
你可以将这些组件分别独立部署,并使用通信协议(如HTTP或自定义协议)将它们连接起来。每个组件可以运行在独立的进程或容器中,以提高可伸缩性和容错性。
对于游戏中的怪物等非玩家角色,通常会由战斗服务器来管理。每个怪物可以有自己的属性,由战斗服务器来处理其行为和状态。这可以在单个线程中处理,但如果怪物数量非常大,也可以采用多线程或多进程来分摊负载。
总之,游戏服务器的架构取决于游戏的特定需求和规模。你可以根据需求设计合适的服务器架构,并使用合适的工具和技术来实现。 感觉你在整体上没把握住服务器结构或者架构的情况下, 问了太多实现上的细节.
accept线程和IO线程有必要么? 这个看情况的, 起码对一个使用C++网络编程的学习者完全没必要, 凭空增加复杂度.
消息队列有必要么? 得先看你说的什么消息队列, 如果是zeromq, 它更像一个网络框架, 如果是kafka那种, 对一个学习项目我想不出来用在哪, 你需要的最多只是一个简单的队列, 一个线程安全的queue, 来管理收到发出的消息.
多个服务器有必要么? 这个倒是可以有, 把登录, 聊天这些剥离出去, 用个简单的http服务器就行, 游戏服务器那块有个网关认证下玩家, 然后在游戏服务器创建个世界让玩家加入就行了.
马克一下 我也在用c++做游戏后端开发 游戏后端用Java好还是C好,Java好像有现成的Netty框架解决了这些协议问题 kiseyzed 发表于 2023-11-3 10:53
游戏后端用Java好还是C好,Java好像有现成的Netty框架解决了这些协议问题
那个语言都有现成的框架,只不过只是用框架有好多都不明白。 FDE9 发表于 2023-11-3 01:22
感觉你在整体上没把握住服务器结构或者架构的情况下, 问了太多实现上的细节.
accept线程和IO线程有必要 ...
谢谢老哥的解答,确实,自学c++后端一直在摸着黑走,看了几本网络编程的书也只是入门,但是到具体业务上面,真的一头雾水:loveliness: c19971130 发表于 2023-11-3 11:21
谢谢老哥的解答,确实,自学c++后端一直在摸着黑走,看了几本网络编程的书也只是入门,但是到具体业务上 ...
前期你可以忽略很多问题, 你甚至可以用同步阻塞, 一个线程一个连接, 你可以不考虑并发性能, 把整个游戏状态用一把大锁锁住来更新
你先把: 从客户端接收输入, 客户端序列化发包, 服务端收包解包, 服务端处理, 服务端广播同步游戏状态给客户端, 客户端根据回复更新状态, 这整个流程理解跑通
之后再考虑一步一步优化替换: 把同步阻塞换成非阻塞多路复用, 把自造的通讯协议换成protobuf, 服务端收到包怎么管理缓冲区减少复制提高性能防止内存泄漏, 怎么处理tcp流的边界, 服务端怎么尽可能少的同步状态来提高网络流量等等等等
网上也有很多开源的服务端实现, 比如那种小棋牌, 私f实现, 还有一些文章, 比如对quake的网络部分的分析, 都可以参考. 不是c++的也可以参考, 大致能看懂然后整理出来个流程就行, 看别人怎么做的.
页:
[1]