【问题标题】:Tornado Web and ThreadsTornado 网络和线程
【发布时间】:2011-12-12 09:04:15
【问题描述】:

我是 Tornado 和 Python 线程的新手。我想要达到的目标如下: 我有一个 Tornado 网络服务器,它接受用户的请求。我想在本地存储一些数据,并定期将其作为批量插入写入数据库。

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 遇到问题吗?只要没有服务器崩溃,数据一致性在这里就不那么重要了。

【问题讨论】:

    标签: python tornado


    【解决方案1】:

    Tornado 不适用于多线程。它基于 epoll 在代码的不同部分之间切换上下文。

    一般来说,我建议通过消息队列将数据发送到单独的工作进程(如pika+RabbitMQ,它与 Tornado 集成得很好)。工作进程可以累积带有数据的消息并将它们批量写入数据库,或者您可以使用此设置实现任何其他数据处理逻辑。

    例如,您也可以使用带有brukva 的 Redis 将传入数据异步写入内存数据库,然后根据 Redis 配置将其异步转储到磁盘。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-20
      • 2011-02-21
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多