首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我的nodejs应用最好的方式是什么?

我的nodejs应用最好的方式是什么?
EN

Stack Overflow用户
提问于 2014-02-24 07:14:53
回答 2查看 7.9K关注 0票数 24

基本

现在,我和我的几个朋友正在开发一个用nodejs制作的浏览器游戏。它是一个多人自上而下的射手,大多数客户端和服务器端代码都是javascript。我们有一个很好的方向,我们想要进入,我们有很大的乐趣开发这个游戏。我们制作这款游戏的目标之一是尽可能地让作弊变得更难。这样做,我们有所有的游戏逻辑处理服务器端。客户端只通过web套接字将他们的输入发送给服务器,而服务器用游戏中发生的事情更新客户端(也是web )。这是我们问题的开始。

所有服务器端的计算都变得相当庞大,我们发现我们需要以某种方式来处理10多个玩家(我们希望能够容纳更多的玩家)。起初,我们认为我们可以按需要垂直缩放,但是由于nodejs是单线程的,因此is只能利用一个核心。这意味着获得一个更强大的服务器无助于解决这个问题。我们唯一的解决办法是水平缩放。

为什么我们要问这里

我们还没有找到任何关于如何扩展nodejs游戏的好例子。我们的用例非常特别,虽然我们已经尽了最大的努力自己做到这一点,但我们确实可以从外界的意见和建议中获益。

详细信息

我们已经对如何解决这个问题进行了大量的思考。我们已经做了一个多星期了。以下是我们到目前为止所做的工作:

四种类型的服务器

我们将任务分成4种不同类型的服务器。每个人都会有一个特定的任务来完成。

代理服务器

代理服务器将位于整个堆栈的前端,并且是唯一可以从internet直接访问的服务器(可能会有更多这样的服务器)。它将有一个代理,它将路由所有连接到web服务器。我们选择haproxy是因为它具有丰富的特性集、可靠性和几乎无与伦比的速度。

web服务器

网络服务器将接收网络请求,并为所有网页提供服务。他们还将处理游说创造/管理和游戏创造/管理。要做到这一点,他们会告诉游戏服务器它有什么大厅,在大厅里有什么用户,以及他们将要玩的游戏的信息。网络服务器将更新游戏服务器有关用户输入,游戏服务器将更新web服务器(后者将更新客户端)在游戏中正在发生的事情。web服务器将使用TCP套接字与游戏服务器就任何类型的管理进行通信,在通信游戏更新时使用UDP套接字。这一切都是用nodejs来完成的。

游戏服务器

游戏服务器将处理游戏的所有数学和变量更新。游戏服务器还与db服务器进行通信,以记录游戏中玩家的冷静状态。这将通过nodejs来完成。

数据库服务器

数据库服务器将承载数据库。这部分实际上是最简单的,因为我们找到了重新思考b,有史以来最酷的数据库。这种扩展非常容易,而且奇怪的是,这是扩展我们的应用程序的最简单的部分。

其他一些细节

如果你很难把你的头绕在我们的整个设备上,看看这个,这是一个半精确的图表,我们认为我们将如何扩大规模。

如果你只是好奇,或者认为看看我们的游戏可能会有帮助,它目前是托管在它的非规模状态在这里。

有些我们不想要的东西

  • 我们不想使用nodejs的集群模块。它不稳定(这里说),也不扩展到其他服务器,只有其他处理器。我们只想跳到水平缩放。

我们的问题,总结

我们希望我们朝着正确的方向前进,我们已经完成了我们的家庭作业,但我们不确定。我们当然可以学到一些关于如何用正确的方法来做这件事的建议。

谢谢

我意识到这是一个很长的问题,想出一个深思熟虑的答案并不容易,但我真的很感激。

谢谢!!

EN

回答 2

Stack Overflow用户

发布于 2014-02-24 08:05:36

按照我对你的想法:

多核使用

node.js也可以用多个核进行缩放。如何阅读举个例子 (或者想想看:在一个内核上运行一个线程/进程,您需要使用多个内核?多线程或多进程。将工作从主线程推送到其他线程或进程,您就完成了)。

我个人认为开发一个不使用多核的应用程序是幼稚的。如果您使用了一些后台进程,好的,但如果到目前为止您只在node.js主事件循环中工作,那么您肯定应该投入一些时间来使应用程序在内核上可伸缩。

顺便说一句,实现像IPC这样的东西并不容易。您可以这样做,但是如果您的情况很复杂,也许可以使用集群模块。这显然不是你最喜欢的,但仅仅因为某些东西被称为“实验”,并不意味着它是垃圾。只要试一试,也许你甚至可以修复一些错误的模块在路上。对于复杂的问题,最好使用一些广泛使用的软件,而不是发明一个新的轮子。

您还应该(如果还没有)考虑(明智地)使用nextTick功能。这允许主事件循环暂停一些cpu密集型任务,同时执行其他工作。你可以读到它,举个例子

关于计算的一般思考

你绝对应该仔细看看你的游戏引擎算法。你已经注意到这是你现在的瓶颈,实际上计算是每个游戏中最关键的部分。缩放确实在某种程度上解决了这个问题,但是Scaling引入了其他问题。此外,你不能抛出“缩放”作为问题解决者的一切,并期待每一个问题消失。

你最好的选择是使你的游戏代码优雅和快速。思考如何有效地解决问题。如果您不能有效地解决Javascript中的一些问题,但是问题可以很容易地解决,那么为什么不编写一个小小的C组件呢?这也是一个单独的过程,它减少了主node.js事件循环的负载。

代理?

就我个人而言,我现在看不到代理级别的优势。您似乎不期望大量的用户,因此,您将不需要解决问题,如CDN解决或任何.可以考虑一下,但我现在不会花太多时间在那里。

从技术上讲,您的your服务器软件提供代理功能的可能性很大。所以把它放在纸上是可以的,但是我现在不打算用专用的硬件。

结束语

其余的对我来说似乎还不错。

票数 12
EN

Stack Overflow用户

发布于 2015-09-20 15:16:43

游戏有点晚了,但是看看这里:http://goldfirestudios.com/blog/136/Horizontally-Scaling-Node.js-and-WebSockets-with-Redis

您没有提到与内存管理有任何关系。如您所知,nodejs不与其他进程共享它的内存,因此,如果您想要扩展,那么内存中的数据库是必须的。(RedisMemcache等)。您需要在每个节点上设置发布服务器和订阅服务器事件,以接受来自redis的传入请求。通过这种方式,您可以扩展scale数量的服务器(HAProxy前端),并利用从redis传输的数据。

还有一个node addon:http://blog.varunajayasiri.com/shared-memory-with-nodejs,它允许您在进程之间共享内存,但只能在Linux下工作。如果您不想一直在本地进程之间发送数据,或者必须处理nodes ipc api,这将有所帮助。

您还可以在node中为新的v8隔离分叉子进程,以帮助处理昂贵的cpu绑定任务。例如,玩家可以在我的动作rpg游戏中杀死怪物并获得相当多的战利品。我有一个名为LootGenerater的子进程,基本上每当玩家杀死怪物时,它都会通过默认的IPC api .send向进程发送游戏idmob_iduser_id。一旦子进程接收到它,它就会遍历大型战利品表,并管理项目(存储到redis或其他任何东西),并将其输送回去。

这有助于极大地释放事件循环,而我只想出一个想法来帮助您进行扩展。但是最重要的是,您需要使用内存中的数据库系统,并确保您的游戏代码体系结构是围绕您使用的任何数据库系统设计的。不要犯我现在所犯的错误,必须重写一切:)

希望这能有所帮助!

注意:如果您确实决定使用Memcache,则需要使用另一个pub/子系统。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21981186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档