redis的monitor命令
功能
通过执行monitor命令,可将客户机更改为监视器。实时打印出 Redis 服务器接收到的命令,一般是在调试的时候使用这个命令
原理
monitor命令的原理是客户端的REDIS_MONITOR开启监视器标志,然后将客户端信息添加到服务器的监视器链接列表之中。服务器初始化replicationFeedMonitors迭代所有监控器,并将接管到的命令信息传送给所有监控器
这个方法的功能就是将参数列表中的参数发送给监控器
void replicationFeedMonitors(client *c, list *monitors, int dictid, robj **argv, int argc) {
listNode *ln;
listIter li;
int j;
sds cmdrepr = sdsnew("+");
robj *cmdobj;
struct timeval tv;
gettimeofday(&tv,NULL);
cmdrepr = sdscatprintf(cmdrepr,"%ld.%06ld ",(long)tv.tv_sec,(long)tv.tv_usec);
if (c->flags & CLIENT_LUA) {
cmdrepr = sdscatprintf(cmdrepr,"[%d lua] ",dictid);
} else if (c->flags & CLIENT_UNIX_SOCKET) {
cmdrepr = sdscatprintf(cmdrepr,"[%d unix:%s] ",dictid,server.unixsocket);
} else {
cmdrepr = sdscatprintf(cmdrepr,"[%d %s] ",dictid,getClientPeerId(c));
}
for (j = 0; j < argc; j++) {
if (argv[j]->encoding == OBJ_ENCODING_INT) {
cmdrepr = sdscatprintf(cmdrepr, ""%ld"", (long)argv[j]->ptr);
} else {
cmdrepr = sdscatrepr(cmdrepr,(char*)argv[j]->ptr,
sdslen(argv[j]->ptr));
}
if (j != argc-1)
cmdrepr = sdscatlen(cmdrepr," ",1);
}
cmdrepr = sdscatlen(cmdrepr,"\r\n",2);
cmdobj = createObject(OBJ_STRING,cmdrepr);
listRewind(monitors,&li);
while((ln = listNext(&li))) {
client *monitor = ln->value;
addReply(monitor,cmdobj);
}
decrRefCount(cmdobj);
}
- 调用gettimeofday()方法获取当前时间
- 将获取到的时间保存在cmdrepr中
- 然后根据client不同的状态,将不同信息追加到cmdrepr中
- 遍历传入的所有的参数,将参数添加到cmdrepr中
- 将cmdrepr构建成字符串对象
- 遍历监控器链表,将命令对象添加到当前监控器的回复中
当客户端把命令发送给服务端的时候,服务器会对这条命令进行处理,同时它还会将命令请求的相关信息发送给监视器,监视器会打印出被监视服务器的命令请求信息。
总结
这里做个小总结,redis监视器的实现比较简单,就是通过Monitor命令修改客户端的标识,然后加入监视器链表中server.monitors,在redis服务器将命令发送完成后,依次遍历监视器链表,将信息发送给链表中的监视器。
到目前为止,redis的大致内容就写到这里了,后面可能会写一些java企业级框架的东西,也可能写点别的内容,拭目以待吧。