2015-06-12 114 views
2

我在Pylons中有此代碼,用於計算運行web應用程序的Linux系統的網絡使用情況。基本上,爲了計算網絡利用率,我們需要兩次讀取文件/proc/net/dev,這給我們傳輸的數據量,並將減去的值除以兩次讀取之間的時間。Pyramid中的所有請求之間共享的全局變量

我不想定期做這個計算。有一個JS代碼週期性地提取這些數據。傳輸速率是每個時間單元兩次請求之間的平均傳輸字節數。在Pylons中,我使用pylons.app_globals來存儲將在隨後的請求中從下一個讀數中減去的讀數。但顯然金字塔中沒有app_globals,我不確定使用線程本地化是否是正確的行爲。此外,儘管request.registry.settings顯然是在所有請求之間共享的,但我不願意將數據存儲在那裏,因爲名稱暗示它應該只存儲設置。

def netUsage(): 
    netusage = {'rx':0, 'tx':0, 'time': time.time()} 
    rtn = {} 
    net_file = open('/proc/net/dev') 
    for line in net_file.readlines()[2:]: 
     tmp = map(string.atof, re.compile('\d+').findall(line[line.find(':'):])) 
     if line[:line.find(':')].strip() == "lo": 
      continue 
     netusage['rx'] += tmp[0] 
     netusage['tx'] += tmp[8] 
    net_file.close() 
    rx = netusage['rx'] - app_globals.prevNetusage['rx'] if app_globals.prevNetusage['rx'] else 0 
    tx = netusage['tx'] - app_globals.prevNetusage['tx'] if app_globals.prevNetusage'tx'] else 0 
    elapsed = netusage['time'] - app_globals.prevNetusage['time'] 
    rtn['rx'] = humanReadable(rx/elapsed) 
    rtn['tx'] = humanReadable(tx/elapsed) 

    app_globals.prevNetusage = netusage 
    return rtn 

@memorize(duration = 3) 
def getSysStat(): 
    memTotal, memUsed = getMemUsage() 
    net = netUsage() 
    loadavg = getLoadAverage() 
    return {'cpu': getCPUUsage(), 
      'mem': int((memUsed/memTotal) * 100), 
      'load1': loadavg[0], 
      'load5': loadavg[1], 
      'load15': loadavg[2], 
      'procNum': loadavg[3], 
      'lastProc': loadavg[4], 
      'rx': net['rx'], 
      'tx': net['tx'] 
      } 
+0

此問題還取決於所使用的Web服務器的類型。問題是你可能不知道你的Web服務器爲Python產生了多少個進程或線程。因此,如果您有兩個或更多進程,則不能再共享全局變量。 –

+0

@MikkoOhtamaa,我知道,但它不像我在那裏存儲數據庫連接池。我不認爲線程安全是我的用例的一個問題,是嗎? –

+0

我想,然後正常的Python全局爲你工作。只需將你的函數放到某個模塊並導入。除非您的Python進程重新啓動,否則記憶應該在請求之間起作用。 –

回答

2

使用請求線程局部變量被認爲是不好的設計,不應根據官方pyramid docs被濫用。

我的建議是使用一些簡單的鍵值存儲,如memcachedredis如果可能的話。

+0

嗯。看起來像矯枉過正。我更喜歡內部解決方案。 –

相關問題