服务器定时器的管理优化(思路借鉴)

作为一个游戏服务器,必然有很多定时器的使用,算是游戏服务器开发的基础模块,我们经常需要在我们预期的某个时间点执行某项特定的操作。比如每天M点开启某个活动,N小时后之后刷新排行榜等等。这些功能通常需要定时器控制,之前我们的服务器代码中每加一个延迟执行的功能就启动一个定时器,这样到最后往往代码特别臃肿,而且定时器时稀缺资源,过多的定时器必然导致效率问题,于是要想办法优化。

想要优化定时器就要看定时器一共有多少种:

1.只执行一次的定时器,比如60秒后执行操作A。

2.循环执行的定时器,比如每隔30分钟执行一次操作B。

3.每日/每周/每月特定时间点执行一次的操作C。(eg.每天下午6点执行操作C)

我们要做的就是,把一整套需要定时器的操作整合到一个定时器管理器Manager里面,然后每次有新的定时器要添加,调用Add接口加到Manager里面,Manager只会启动一个定时器,它会自动寻找最近需要执行的定时器然后到时间点后处理相关逻辑。这样我们每次增加定时器操作就是往管理器里面添加一个操作就行了,其他的管理器会替我们解决。

from common import Timer
from util import TimeUtil
from base.Defines import *

class TimerObj(object):
"""封装一个定时器对象"""
def __init__(self, start_time, interval, callback):
"""
:param start_time:定时器开始时间
:param interval:定时器间隔,如果只执行一次,填0
:param callback:触发定时器时执行的函数
:return:
"""
super(TimerObj, self).__init__()
self.start = start_time
self.interval = interval
self.callback = callback

def getEndTime(self):
if self.interval <= 0:
return self.start
return None

def getNextTime(self):
now_time = int(TimeUtil.now_time())
if now_time < self.start:
return self.start
else:
if self.getEndTime() is not None:
return None
num = 0
while self.start + num <= now_time:
num += self.interval
return self.start + num

class TimerManager(object):
"""管理所有的定时器"""
def __init__(self):
super(TimerManager, self).__init__()
self.timer_list = []
self.timer = None

def addTimerObj(self, obj):
self.timer_list.append(obj)
self.stopTimer()
self.startTimer()

def removeTimeObj(self, type):
pass

def getMinNextTimer(self):
min_next = INT_MAX
result = []
self.timer_list = filter(lambda x:x.getNextTime() is not None, self.timer_list)
for obj in self.timer_list:
next = obj.getNextTime()
if next < min_next:
min_next = next
result = []
result.append(obj)
elif next == min_next:
result.append(obj)

if min_next == INT_MAX:
return None,None
#print "getMinNextTimer",min_next,int(TimeUtil.now_time())
return min_next, result

def startTimer(self):
timestamp, objlist = self.getMinNextTimer()
if timestamp is None:
return
self.stopTimer()
delay = int(timestamp) - int(TimeUtil.now_time())
if delay == 0:
delay = 1
self.timer = Timer.addTimer(delay, lambda :self.callTimer(objlist))

def callTimer(self, objlist):
#print "callTimer",int(TimeUtil.now_time())
self.startTimer()
for obj in objlist:
obj.callback()

def stopTimer(self):
if self.timer is not None:
self.timer.cancel()
self.timer = None

我用一个列表储存需要管理的定时器对象列表,addTimerObj用来增加定时器对象。startTimer启动管理器的定时器,它会取最小的下次定时器触发时间以及对象列表(因为同一个时间点可能有多个事件),然后启动定时器,到点执行操作。

代码还有需要优化的点:

1.为了简单我用了列表存储,可以考虑其他更好的数据结构,比如使用类似libevent的最小堆。

2.我每次stopTimer再startTimer这点可以考虑优化。

3.我在每次getMinNextTimer的时候才过滤已经过期的定时器。

4.我暴露了TimerObj对象,可以在TimerManager里面增加一个接口,然后根据参数创建TimerObj,就不需要TimerObj给用户。

5. ...

使用很简单,创建一个TimerManager对象,然后需要增加的时候,创建一个TimerObj对象,把启动时间,间隔,以及回调传进去,然后调用addTimerObj加到TimerManager对象里面。

onlineCountingTimer = TimerObj(now_time, 5 * 60, lambda : self.onlineCounting())

self.timerManager.addTimerObj(onlineCountingTimer)

转:http://blog.csdn.net/majianfei1023/article/details/52769133

时间: 2024-11-10 07:47:42

服务器定时器的管理优化(思路借鉴)的相关文章

游戏服务器之服务器优化思路

本文只是提供一些游戏服务器优化思路,其中一些思路是用在不同场合的,不是同个架构的.需要根据应用场景选用合适方式. 一.框架设计优化 1.分静态服务器和动态服务器. 2.动态服务器使用两层负载均衡:多网关  和 多场景.网关的选择是登陆服务器根据网关的负载来选择.场景则作为分线和副本等分开. 框架图参考:http://blog.csdn.net/chenjiayi_yun/article/details/18891591 3.中心服务器负责服务器依赖检查和内部消息转发和控制登录流程.中心服务器会主

Linux进程管理优化及性能评估工具介绍

衡量Linux CPU使用的指标 需要关注以下地方: 第一段需要关注的值: ·使用率 ·在用户空间所消耗的时间百分比 ·在系统空间锁消耗的时间百分比 ·消耗在IO等待上的时间 如果一个主机上有大量的cpu消耗在IO等待上,那么说明IO活动非常频繁,而IO子系统性能非常差. 因此我们看到wite的时间居高不下时,说明IO活动非常频繁的,IO子系统非常差 但如果wite的时间不是特别离谱,一般而言问题都不大 第二段需要关注的值: ·空闲时间 ·平均负载,CPU等待运行活动队列中等待运行的进程的个数

系统性能排查命令及优化思路

最近笔者经常处理了一些线上的问题机器.特抽空写一篇文章将处理系统性能问题和优化思路进行总结,方便后续工作中系统故障的排查.作为运维,收到网管系统性能报警应该是常有的事情.而快速进行问题定位并解决则是工作的关键.我们在排查或者优化一个系统的时候无外乎从以下几个方面考虑: 1.CPU的使用率异常,如某个核心的使用率过高,而其它核心则处于空闲的状况. 2.内存的使用状况:通常需要注意是否程序内存泄漏导致的. 3.磁盘IO性能:通常磁盘IO不正常时我们需要判断程序是否处在顺序读写的状态. 4.网络IO负

XMPP——xmpp协议详解、优点、缺点及优化思路

XMPP(Extensible Messaging and Presence Protocol,前称Jabber)协议介绍 可扩展消息处理现场协议(eXtensible Messaging and Presence Protocol , XMPP) 是一种基于可扩展标记语言(eXtensible Markup Language, XML)的近端串流式即时通信协议.它将现场和上下文敏感信息标记嵌入到XML 结构化数据中, 使得人与人之间.应用系统之间以及人与应用系统之间能即时相互通信 XMPP是一

C#列表 定时器的管理

上一篇文章提到列表定时器,后来在开发中,项目中增加了 延时功能. 问题来了 我如何对已经运行的Timer 进行管理呢 思路:初始化,循环实体对象的时候,动态创建n个Timer 当某个属性的值变化时,就将对应的Timer 清除,重新创建一个Timer 下面看看,我改进的Timer function Timer_V1(itemid, timeridname) { if (eval("boo" + itemid + "==false")) { var temp = $('

关于秒杀的系统架构优化思路

一.问题的提出 秒杀或抢购活动一般会经过 预约,下单,支付 ,扛不住的地方在于下单,一般会带来2个问题: 1.高并发 比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验. 2.超卖 任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难题. 秒杀系统难做的原因:库存只有一份,瞬间大量用户读和写这些数据. 例如小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万 二.架构 常见站点架构如

Web下的整体测试 --性能测试及优化思路

随着Internet的日益普及,现在基于B/S结构的大型应用越来越多,可如何对这些应用进行测试成为日益迫切的问题.有许多测试人员来信问我B/S的测试如何做,由于工作较繁忙,对大家提出的问题也是头痛医头脚痛医脚,没有对WEB的测试过程做一个整体的概述.希望通过本篇能够让大家了解大型Web应用是如何来进行测试的. B/S下的功能测试比较简单,关键是如何做好性能测试.目前大多数的测试人员认为只要跑一些测试工具证明我的产品是可以达到性能的就ok了,为了证明而去测试是没有任何价值的,关键是要发现产品性能上

Nginx 0.7.x + PHP 5.2.6(FastCGI)+ MySQL 5.1 在128M小内存VPS服务器上的配置优化

Nginx 0.7.x + PHP 5.2.6(FastCGI)+ MySQL 5.1 在128M小内存VPS服务器上的配置优化  大 | 中 | 小  [ 2008-10-28 16:55 | by 张宴 ] [文章作者:张宴 本文版本:v1.0 最后修改:2008.10.28 转载请注明原文链接:http://blog.zyan.cc/post/375/] VPS(全称Virtual Private Server)是利用最新虚拟化技术在一台物理服务器上创建多个相互隔离的虚拟私有主机.它们以最

spark(二)优化思路

优化思路 内存优化 内存优化大概分为三个方向 1.所有对象的总内存(包括数据和java对象) 2.访问这些对象的开销 3.垃圾回收的开销 其中Java的原生对象往往都能被很快的访问,但是会多占据2-5倍或更多的内存,有下面4点原因 ·每个单独的java对象都有一个对象头(16字节),其中包括指向对象的指针(栈->堆),如果该对象只有几个属性,那么对象头可能比实际数据占用的空间都大(严重浪费资源) ·java每个string都包含了40字节的额外开销(因为底层其实是存储在数组,需要记录数组的指针,