我正在创建一个基于浏览器的 MMO,它具有基于时间的事件:I.E. build 一座建筑物需要 23 个小时。
我可以将其记录在我的 MySQL 数据库中,然后使用 cron 脚本或 watch
(this question was immensely helpful)循环遍历事件表(或等效表)。
似乎普遍认为我可以:
(1) 每秒为处理事件及其相关触发器的脚本运行一个 cron 作业。
(2) 每分钟运行一个 cron 作业,每秒循环 59 次迭代,处理事件及其相关触发器。
(3) 使用watch
每秒运行一个php脚本。
基本上,在事件完成后,脚本将处理一些触发器,范围从更改状态、更新数据库、触发在最近事件之后排队的其他“事件”等等。
我最担心的是每秒可能处理 10,000 多个事件和触发器。我可以使用哪些策略来避免性能问题?这些都是解决方案,还是有更好的选择?
示例事件:
Construction of Building A - 00:43:21
快进 2601 秒并执行以下触发器:
Place Building A on map at Location x,y
Update resource total given by building
Start timer on next building in the queue
Construction of Building B - 02:10:49
为了更好地解释:在游戏的早期阶段,这些事件将持续 5 分钟到一个小时。在游戏的后期阶段,这些事件将相隔数百小时。我需要实时处理这些事件,因为它们会影响游戏的其他方面(例如资源结构提高每小时提供的资源量)。因此,无论用户是否处于事件状态,这些事件都需要由服务器处理。理论上的脚本会检查过期事件,然后根据该事件运行与该事件过期相关的其他几个方法。
最佳答案
https://github.com/prggmr/prggmr
听起来事件库可能对你有很大帮助,
您可以在 prggmr 中编写一个简单的间隔,而不是尝试使用“包罗万象”来监视将来发生的所有事件,它会挑选将来需要发生的事件并将它们注册到事件中引擎在那个时候发出信号。
像下面这样的东西可能会起作用,
prggmr\interval(function(){
$query = mysql_query("SELECT event, when FROM events");
while($event = mysql_fetch_assoc($query)) {
prggmr\setTimeout(function() use ($event){
prggmr\signal($event['event']);
}, $event['when']);
}
// What this would do is look for any events that require signaling in the
// in the future such as a building construction and signal it when the
// given amount of time in milliseconds has run
}, 3600);
// This simply tells the engine to run the function every minute
要运行此代码,请说它存储在 event_detect.php 中
prggmr event_detect.php
您通常希望由另一个应用程序(例如 runit)管理进程。
通过这种方法,您可以将所有可能发生的事件构建为已注册的“信号处理程序”,并在后台运行一个实际的游戏引擎,在没有任何用户的情况下实时等待和监视事件互动。
我们实际上正在将这种方法用于我们目前正在开发的游戏的类似情况......逻辑上完全不同但非用户交互事件处理都是一样的。
此外,对于性能,您可以非常轻松地在一秒或更短时间内处理 10,000 个事件,具体取决于您的服务器。
关于php - 处理和监视存储在 MySQL 数据库中的基于时间的事件的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10855822/