【问题标题】:uWSGI Signal framework: signal to ALL workers being sent to the first available workersuWSGI Signal 框架:向所有工作人员发送信号,发送给第一个可用工作人员
【发布时间】:2017-11-06 21:08:40
【问题描述】:

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

我最初的想法是:

  1. 定义一个更新所有工作人员中字典的函数。
  2. 将此函数注册为针对所有工作人员 (target="workers") 的信号的处理程序。
  3. 在需要时触发信号。

例子:

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://*.com/a/22753269
lazy-apps = true

catch-exceptions = true

【问题讨论】:

    标签: python flask frameworks signals uwsgi


    【解决方案1】:

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

    但是,就您而言,uWSGI 确实带有缓存框架。看看有没有帮助。

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

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,并将信号更改为“active-workers”而不是“workers”,因为如果向非活动工作人员发出信号,信号队列可能会溢出。另见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)
      

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

      【讨论】:

      • 欢迎来到 Stack Overflow,在回答问题时,请尝试以示例对 OP 的问题给出具体的答案,即使您有补充信息,您的答案也应该有或没有它。见how to answer
      最近更新 更多