memcache-2.2.4 中的一点小知识

在一次抓包的过程中,发现我的PHP在访问memcache的时候时不时的会多出一个“version”的操作,结果就是返回memcached的版本号;疑惑不解,我发誓自己没有写这部分代码的,为什么会凭空多出一个“version”操作呢?看看源代码吧!

源码中发现这么一段:
int mmc_open(mmc_t *mmcint force_connectchar **error_stringint *errnum TSRMLS_DC/* {{{ */
{
    switch (
mmc->status) {
        case 
MMC_STATUS_DISCONNECTED:
            return 
_mmc_open(mmcerror_stringerrnum TSRMLS_CC);

        case MMC_STATUS_CONNECTED:
            return 
1;

        case MMC_STATUS_UNKNOWN:
            
/* check connection if needed */
            
if (force_connect) {
                
char *version;
                if ((
version mmc_get_version(mmc TSRMLS_CC)) == NULL && !_mmc_open(mmcerror_stringerrnum TSRMLS_CC)) {
                    break;
                }
                if (
version) {
                    
efree(version);
                }
                
mmc->status MMC_STATUS_CONNECTED;
            }
            return 
1;

        case MMC_STATUS_FAILED:
            if (
mmc->retry_interval >= && (long)time(NULL) >= mmc->failed mmc->retry_interval) {
                if (
_mmc_open(mmcerror_stringerrnum TSRMLS_CC/*&& mmc_flush(mmc, 0 TSRMLS_CC) > 0*/) {
                    return 
1;
                }
            }
            break;
    }
    return 
0;
}


如果连接状态为
MMC_STATUS_UNKNOWN 就会通过“version”操作来检查连接的状态。那么什么情况下连接的状态会是MMC_STATUS_UNKNOWN 呢?
参看函数: mmc_find_persistent , 其逻辑大致为:
1. 如果在hash表中没有查到该连接,则初始化一个连接句柄,并注册一个长连接
2. 如果查到了,发现连接明显有一些问题,比如根本没有成功连接,则从hash表中删除,重新初始化、注册;
3. 如果查到了,并且没有发现明显的错误标识,则将状态置为
MMC_STATUS_UNKNOWN,如此则发送一个“version”命令检查连接的有效性。

如此看来,如果长连接被重用,则一定会先有一个version命令的。

由此也可以看出,长连接关闭被动关闭时,PHP是没有被通知的,(猜测一下,通常这种情况下,连接是半关闭状态的)
 
 

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据