uWSGI信号框架:向发送给第一批可用工人的所有工人发出信号

时间:2017-06-06 01:24:05

标签: python flask frameworks signals uwsgi

我正在使用在docker容器中运行的uWSGI部署Flask应用程序。在具有4个工作程序的应用程序中,有一些内存中的字典可以存储"缓存的值"应用程序使用它来防止每次都需要查询数据库。这些dicts是在初始化工作人员时创建的,我正在尝试使用uWSGI的Signal Framework来强制更新所有工作人员的缓存。

我最初的想法是:

  1. 定义一个更新所有工作人员字典的功能。
  2. 将此功能注册为针对所有工作人员的信号处理程序(目标="工人")。
  3. 需要时触发信号。
  4. 示例:

    def update_dicts(sig):
        # Update dictionaries here
        print('Received signal {}: updating dicts in worker {}'.format(sig, uwsgi.worker_id()))
    
    uwsgi.register_signal(100, "workers", update_dicts)
    

    并在需要时触发任何工人的信号:

    uwsgi.signal(100)
    

    然而,即使信号定位"工人",信号也只由一名工人接收和处理,好像它有"工人"作为目标

    我还尝试为每个工作人员注册一个信号(使用目标" workerN")并触发所有这些信号,但信号被发送给任何工作人员,而不是发送给指定的工作人员:

    # Each worker executes this 
    # Signal registrations: 111, 112, 113, 114
    uwsgi.register_signal(110 + uwsgi.worker_id(), "worker{}".format(uwsgi.worker_id()), update_service_dicts)
    
    # To trigger the signals:
    for i in [1,2,3,4]:
        uwsgi.signal(110 + i)
    

    应用程序的日志:

    [uwsgi-signal] signum 113 registered (wid: 3 modifier1: 0 target: worker3)
    [uwsgi-signal] signum 112 registered (wid: 2 modifier1: 0 target: worker2)
    [uwsgi-signal] signum 114 registered (wid: 4 modifier1: 0 target: worker4)
    [uwsgi-signal] signum 111 registered (wid: 1 modifier1: 0 target: worker1)
    Mon Jun  5 18:17:51 2017 - error managing signal 112 on worker 4
    Received signal 111: updating dicts in worker 1.
    Received signal 113: updating dicts in worker 3.
    Received signal 114: updating dicts in worker 4.
    

    再次触发:

    Mon Jun  5 18:18:01 2017 - error managing signal 111 on worker 4
    Mon Jun  5 18:18:01 2017 - error managing signal 113 on worker 4
    Mon Jun  5 18:18:01 2017 - error managing signal 112 on worker 4
    Received signal 114: updating dicts in worker 4.
    

    我在这里遗漏了什么,或者这些目标尚未实施?

    我目前正在使用以下uwsgi配置:

    [uwsgi]
    
    die-on-term = true
    
    http = 0.0.0.0:9090
    mount = /=/path/to/my/app/file.py
    callable = app
    chdir = /path/to/my/app/
    
    ; enable the stats server on port 9191
    stats = 0.0.0.0:9191
    
    ; log configuration
    logto = /var/log/uwsgi/uwsgi.log
    
    ; spawn 2 threads in 4 processes (concurrency level: 8)
    processes = 4
    threads = 2
    
    ; drop privileges
    uid = pmais
    gid = pmais
    
    ; Loads apps independently to solve error related to DB connection:
    ;     "SSL error: decryption failed or bad record mac uwsgi"
    ; Reference: http://stackoverflow.com/a/22753269
    lazy-apps = true
    
    catch-exceptions = true
    

2 个答案:

答案 0 :(得分:0)

uWSGI似乎没有提供很多内部数据交换机制。我的意思是,他们自己在示例中使用Redis。

但是,在您的情况下,uWSGI确实带有缓存框架。看看是否有帮助。

  

https://uwsgi-docs.readthedocs.io/en/latest/Caching.html

答案 1 :(得分:0)

我遇到了类似的问题,并将信号传递更改为“活动工人”而不是“工人”,因为如果向非活动工人发出信号,则信号发送队列可能会溢出。另请参见https://github.com/unbit/uwsgi/issues/775

def update_dicts(sig):
    # Update dictionaries here
    print('Received signal {}: updating dicts in worker {}'.format(sig, uwsgi.worker_id()))
    
    uwsgi.register_signal(100, "active-workers", update_dicts)

另外请注意,使用“惰性应用程序”会将应用程序加载到工作程序中,可能会多次注册信号。