2011-10-21 61 views
3

我是新的龍捲風和Python線程。我想實現的是以下幾點: 我有一個Tornado Web服務器,它接受來自用戶的請求。我想在本地存儲一些數據,並將其定期寫入數據庫作爲批量插入。龍捲風網頁和線程

import tornado.ioloop 
import tornado.web 
import threading 

# Keep userData locally in memory 
UserData = {} 

def background(f): 
    """ 
    a threading decorator 
    use @background above the function you want to thread 
    (run in the background) 
    """ 
    def bg_f(*a, **kw): 
     threading.Thread(target=f, args=a, kwargs=kw).start() 
    return bg_f 

@background 
def PostRecentDataToDBThread(iter = -1): 
    i = 0 
    while iter == -1 or i < iter: 
     #send data to DB 
     UserData = {} 
     time.sleep(5*60) 
     i = i + 1 

class AddHandler(tornado.web.RequestHandler): 
    def post(self): 
     userID = self.get_argument('ui') 
     Data = self.get_argument('data') 

     UserData[userID] = Data 


if __name__ == "__main__": 
    tornado.options.parse_command_line() 

    print("start PostRecentDataToDBThread") 
    ### Here we start a thread that periodically sends data to the data base. 
    ### The thread is called every 5min. 
    PostRecentDataToDBThread(-1) 

    print("Started tornado on port: %d" % options.port) 

    application = tornado.web.Application([ 
     (r"/", MainHandler), 
     (r"/add", AddHandler) 
    ]) 
    application.listen(options.port) 
    tornado.ioloop.IOLoop.instance().start() 

這是實現我的目標的好方法嗎?我想盡量減少服務器阻塞時間。或者我應該使用gevent還是其他什麼?我可以通過從Tornado和線程訪問UserData來遇到問題嗎?只要沒有服務器崩潰,數據一致性在這裏就不那麼重要了。

回答

6

龍捲風不打算與多線程一起使用。它基於epoll在代碼的不同部分之間切換上下文。

一般來說,我會建議通過消息隊列將數據發送到單獨的工作進程(如pika + RabbitMQ,它與Tornado集成得非常好)。工作進程可以累積帶有數據的消息並批量寫入數據庫,或者可以使用此設置實現任何其他數據處理邏輯。

或者您可以使用,例如,Redis的與brukva只是異步輸入的數據寫入到內存數據庫,這反過來將異步它轉儲到磁盤取決於Redis的配置。