最近在项目中引入了Redis来实现即时刷新排行的功能,主要是使用了它的sorted set数据结构。参考其他PHP客户端库,复杂的和超简单但是已经废弃的(太老了,也没实现最新协议),实现了轻量级的PHP客户端库用在项目里;只有一个ClientCore实现,一个排序Interface(方便更换为其他实现),一个排序实现。
从某种角度来看,排行更新可分为两种:玩家操作引起的和队列任务到期回调引起的更新。似乎没有区别,但是为了增强redis服务本身的稳定性,客户端连接的idle对于前者应该尽可能短(即使客户端库中正确地处理了关闭连接的处理,仍然可能由其他错误产生过多无效连接),后者么,则可以适当长一些;但是redis服务器对所有客户端连接的idle设定是统一的,不能定制。。。
解决方法也比较简单,检测到由此引发的请求命令失败则重新连接,但是大量的后台任务处理就不爽了,所以,给redis服务器增加CIDLE命令(主要用在后台任务队列中,配置文件中设定较短的idle),用来设定当前客户端连接的idle,涉及的源代码(redis版本:2.2.1)修改如下(注释中的+表示增加,-表示注释掉):
src/help.h:
// 在PING命令后面
{ "CIDLE", /* + by hshqcn@gmail.com */
"timeout",
"Set the maxidletime for the current connection",
8,
"2.2.1" },
|
src/redis.h:
// typedef struct redisClient 中 +字段
int maxidletime; /* -1 invalid, 0 never, >0 seconds. + by hshqcn@gmail.com */
// pingCommand 声明后面+
void cidleCommand(redisClient *c); /* + by hshqcn@gmail.com */
|
src/redis.c:
// struct redisCommand readonlyCommandTable[] 中 +成员
{"cidle",cidleCommand,2,0,NULL,0,0,0}, /* + by hshqcn@gmail.com */
// +命令函数(参考的PING和SELECT命令)
void cidleCommand(redisClient *c) { /* + by hshqcn@gmail.com */
int timeout = atoi(c->argv[1]->ptr);
c->maxidletime = timeout;
addReply(c,shared.ok);
}
|
src/networking.c:
// createClient 函数中 +初始化
c->maxidletime = -1; /* + by hshqcn@gmail.com */
// closeTimedoutClients 函数中 调整idle超时处理
/*(now - c->lastinteraction > server.maxidletime))*/ /* - by hshqcn@gmail.com */
c->maxidletime && /* + by hshqcn@gmail.com */
(now - c->lastinteraction > (c->maxidletime > 0 ? c->maxidletime : server.maxidletime))) /* + by hshqcn@gmail.com */
|
阅读(1127) | 评论(0) | 转发(0) |