TarsCloud / TarsFramework

Tars Basic service framework
BSD 3-Clause "New" or "Revised" License
200 stars 143 forks source link

监控数据丢失 #39

Closed woodwind closed 3 years ago

woodwind commented 4 years ago

在我的tars环境中,服务监控显示的调用数据远远小于实际发生的调用数据。 经过tars_client log和tars db的对比确认,该问题发生在StatServer中。

以下是有问题的代码 StatImp.cpp Line 208 - Line 226

    StatHashMap *pHashMap = g_app.getHashMapBuff(iBufferIndex, iHashKey);

    //////////////////////////////////////////////////////////////////////////////////////
    float rate =  (pHashMap->getMapHead()._iUsedChunk) * 1.0/pHashMap->allBlockChunkCount();

    if(rate >0.9)
    {
        TLOGERROR("StatImp::addHashMap hashmap will full|_iMemSize:" << pHashMap->getMapHead()._iMemSize << endl);
        FDLOG("HashMap")<<"StatImp::addHashMap hashmap will full|_iMemSize:" << pHashMap->getMapHead()._iMemSize << endl;
        return -1;
    }

    int iRet = pHashMap->add(head, body);
    if(iRet != 0)
    {
        TLOGDEBUG("StatImp::addHashMap set g_hashmap recourd erro|" << iRet << endl);
        return iRet;
    }
    return iRet;

这个StatHashmap就是用来维护Stat数据的字典,在监控数据上报后,会把数据加入到字典中。在加入前,这段代码检查了这个HashMap是否空间已经快满了,如果空间不足,会直接丢弃数据。 一方面这个HashMap不支持动态扩容,另外一方面这个校验本身是有问题的。 通过检查HashMap的代码可以看到,在add的时候,Map首先会检查key对应的value是否存在,如果存在的话,只会对value进行累加(因为是stat数据),只有key不存在的时候才会创建一个新的entry。

所以这个校验,应该先判断key在map中是否存在,如果存在的话是不应该丢弃监控数据的,可以正常添加数据。

目前我准备通过配置文件,增加hashmap的数量来解决这个问题,也想确认下这个方案有没有隐患?(因为我不太会cpp)

ruanshudong commented 4 years ago

默认给的共享内存空间太小了, 新版本缺省给了256M,