Eventlet/通用异步I/O任务粒度

2024-04-26 22:02:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个web后端/API提供者,它从第三方web API获取实时数据,将其放入MySQL数据库,并通过HTTP/JSON API提供。在

我用flask提供API,并使用SQLAlchemy内核与DB一起工作。在

对于实时数据获取部分,我有一些函数,通过发送请求、将返回的xml解析为Python dict并返回它来包装第三方API。我们将这些API称为包装器。在

然后我在其他方法中调用这些函数,这些方法获取各自的数据,如果需要,进行任何处理(如时区转换等),并将其放入数据库中。我们称之为处理器。在

我读过关于异步I/O和eventlet的文章,我印象很深刻。在

我将把它合并到我的数据采集代码中,但我首先有一些问题:

  1. 我用猴子修补所有东西安全吗?考虑到我有flask、SQLAlchemy和其他一些lib,monkey补丁有什么缺点吗(假设没有后期绑定)?

  2. 我应该把我的任务划分到什么样的粒度?我在考虑创建一个池,定期产生处理器。然后,一旦处理器到达调用API包装器的部分,API包装器将启动一个绿色堆,用以获取实际的HTTP数据eventlet.green.urllib2. 这是个好方法吗?

  3. 超时-我要确保没有绿色线程挂起。设置eventlet。超时每一条绿线都要10-15秒?在

仅供参考,我有大约10组不同的实时数据,每隔5-10秒就会产生一个处理器。在

谢谢!在


Tags: 数据方法函数apiweb数据库jsonhttp
2条回答

修补由纯python编写的模块并使用标准库是安全的。在

  • 纯mysql适配器很少:
  • PyMysql有一个sqlalchemy测试套件,您可以为您的案例运行测试。在
  • 有一个名为pymysql_sa的模块为sqlalchemy提供方言
  • Flask是由纯python编写的,完全兼容wsgi1.0。em使用>事件集.wsgi提供服务。在

尽可能使用绿色模块将任务划分为单个获取。将作业放入一个队列中,队列也是由eventlet提供的,每个任务工作人员从队列中获取一个作业,完成获取后将结果保存到数据库中,或者发送到事件。事件对象来触发等待任务的作业完成。或者两个过程中的两个。在

更新时间:

eventlet官方文档强烈建议在主模块的第一行使用补丁,多次调用monkey_补丁是安全的。在http://eventlet.net/doc/patching.html页阅读更多内容

有一些绿色模块可以与eventlet一起工作,它们都在eventlet.绿色. bitbucket上的列表。 确保在代码中使用绿色模块,或者在导入第3个使用标准lib的模块之前修补它们。在

但是monkey_补丁只接受少数模块,需要手工导入绿色模块。在

def monkey_patch(**on):
    """Globally patches certain system modules to be greenthread-friendly.

    The keyword arguments afford some control over which modules are patched.
    If no keyword arguments are supplied, all possible modules are patched.
    If keywords are set to True, only the specified modules are patched.  E.g.,
    ``monkey_patch(socket=True, select=True)`` patches only the select and 
    socket modules.  Most arguments patch the single module of the same name 
    (os, time, select).  The exceptions are socket, which also patches the ssl 
    module if present; and thread, which patches thread, threading, and Queue.

    It's safe to call monkey_patch multiple times.
    """    
    accepted_args = set(('os', 'select', 'socket', 
                         'thread', 'time', 'psycopg', 'MySQLdb'))
    default_on = on.pop("all",None)

我认为将Flask/SQLAlchemy与异步风格(或事件驱动)编程模型混合使用是不明智的。在

但是,既然您声明使用RDBMS(MySQL)作为中间存储,为什么不创建一个异步工作器,将来自第三方Web服务的结果存储在RDMBS中,并保持前端(Flask/SQLAlchemy)同步?在

在这种情况下,您不需要monkeypatch Flask或SQLAlchemy。在

关于粒度,您可能希望使用mapreduce范例来执行webapi调用和处理。这个模式可能会给你一些关于如何在逻辑上分离连续步骤,以及如何控制所涉及的过程的一些想法。在

就我个人而言,我不会使用异步框架来实现这一点。最好使用多处理,Celery,或者像Hadoop这样的真正的mapreduce系统。在

只是一个提示:从小处开始,保持简单和模块化,如果您需要更好的性能,可以稍后进行优化。这也可能会受到你想要的信息实时性的严重影响。在

相关问题 更多 >