如何利用 cgi-plugin + heartbeat 与 nginx 结合配置 uwsgi 的 Emperor-mode

如何利用 cgi-plugin + heartbeat 与 nginx 结合配置 uwsgi 的 Emperor-mode

在我的待办事项列表中从 fcgiwrap 迁移到 uWSGI(它还带来了很多我计划使用的其他好处)一段时间后,我终于设法设置了一个以 uWSGI v2.0 和 nginx v1.4.4 为特色的 debian-wheezy 测试系统。

第一步我想通过运行 .cgi-scriptsuWSGI 的 cgi 插件可靠且开销最小(下面的硬件相当弱),同时可以选择轻松增强我的配置,以便第二步通过 bottle/flask/django 等框架部署应用程序。

因此我选择使用uWSGI 的皇帝模式,它当前被设置为只控制一个vassal,该vassal被配置为在2个worker上运行uWSGI-cgi-plugin,每个worker有2个线程。

在检查了各种功能后,设置现在基本可以正常运行,但有两个奇怪的行为,我认为是错误的

  • 一旦附庸被配置为向皇帝发送心跳(例如通过添加heartbeat = 20到.ini),如果.cgi 没有在定义的心跳时间范围内运行,皇帝将反复杀死/重生附庸的主人。这里配置的工人数量似乎并不重要。
  • 附庸忽略该选项,reload-mercy = 10因为它仍然记录your mercy for graceful operations on workers is 60 seconds(这是默认值)。好的,这只是一个小问题,与我没什么大关系。

使用心跳选项的原因是我想尽可能使用内置的 uWSGI 机制来确保我的 cgis/apps 的可用性。

有什么提示我可能误解了什么或做错了什么吗?我看不出有什么明显的原因,为什么在我的配置中不能将心跳选项与 cgi 模块结合使用,但如果能提供进一步的见解,我将不胜感激!我认为 nginx 与上述问题无关,而且我还仔细检查了文件和目录权限……uWSGI 是通过 init.d 脚本启动的,但手动启动时的行为是相同的。

我的配置如下:

  • nginx.conf 中的部分:

    location ~ ^/cgi-bin/.*\..+$ {
       root            /usr/local/nginx/vhosts/testdomain.com/cgi-bin;
       gzip            off;
       include         uwsgi_params;
       uwsgi_modifier1 9;
       uwsgi_pass      unix:///var/run/nginx/testdomain_cgi-bin_uwsgi.sock;
     }
    
  • 皇帝配置文件:

    [uwsgi]
    uid = www-data
    gid = www-data
    emperor = /etc/uwsgi/vassals
    emperor-pidfile = /var/run/uwsgi/emperor.pid
    daemonize = /var/log/uwsgi_emperor.log 
    
  • 测试域_cgi-bin.ini:

    [uwsgi]
    uid = www-data
    gid = www-data
    chdir = /usr/local/nginx/vhosts/testdomain/cgi-bin
    plugins = cgi
    cgi = /cgi-bin=/usr/local/nginx/vhosts/testdomain/cgi-bin
    cgi-allowed-ext = .cgi
    socket = /var/run/nginx/testdomain_cgi-bin_uwsgi.sock
    master = true
    #heartbeat = 25
    processes = 2
    threads = 2
    reload-mercy = 10
    no-orphans = true
    post-buffering = 4096
    max-requests = 2048
    vacuum = true
    logto = /usr/local/nginx/logs/uwsgi_testdomain_cgi-bin.log
    

日志(当启用选项心跳时):

  • /var/log/uwsgi_emperor.log:

    *** Starting uWSGI 2.0 (32bit) on [Wed Feb  5 11:35:36 2014] ***
    compiled with version: 4.7.2 on 31 January 2014 08:46:00
    os: Linux-3.2.0-4-686-pae #1 SMP Debian 3.2.51-1
    nodename: testnode
    machine: i686
    clock source: unix
    pcre jit disabled
    detected number of CPU cores: 1
    current working directory: /
    *** running under screen session 1111.myscrn ***
    detected binary path: /usr/local/bin/uwsgi
    setgid() to 33
    setuid() to 33
    *** WARNING: you are running uWSGI without its master process manager ***
    your processes number limit is 3940
    your memory page size is 4096 bytes
    detected max file descriptor number: 1024
    writing pidfile to /var/run/uwsgi/emperor.pid
    *** starting uWSGI Emperor ***
    *** has_emperor mode detected (fd: 6) ***
    [uWSGI] getting INI configuration from testdomain_cgi-bin.ini
    Wed Feb  5 11:35:36 2014 - [emperor] vassal testdomain_cgi-bin.ini has been spawned
    Wed Feb  5 11:35:36 2014 - [emperor] vassal testdomain_cgi-bin.ini is ready to accept requests
    Wed Feb  5 11:35:43 2014 - [emperor] vassal testdomain_cgi-bin.ini is now loyal
    [emperor] vassal testdomain_cgi-bin.ini sent no heartbeat in last 30 seconds, brutally respawning it...
    Wed Feb  5 11:38:56 2014 - [emperor] removed uwsgi instance testdomain_cgi-bin.ini
    [emperor] unrecognized vassal event on fd 5
    [emperor] unrecognized vassal event on fd 5
        ... above lines repeaded for about another 50 times ... 
    *** has_emperor mode detected (fd: 6) ***
    [uWSGI] getting INI configuration from testdomain_cgi-bin.ini
    Wed Feb  5 11:38:56 2014 - [emperor] vassal testdomain_cgi-bin.ini has been spawned
    Wed Feb  5 11:38:56 2014 - [emperor] vassal testdomain_cgi-bin.ini is ready to accept requests
    
  • /usr/local/nginx/logs/uwsgi_testdomain_cgi-bin.log:

    *** Starting uWSGI 2.0 (32bit) on [Wed Feb  5 11:35:36 2014] ***
    compiled with version: 4.7.2 on 31 January 2014 08:46:00
    os: Linux-3.2.0-4-686-pae #1 SMP Debian 3.2.51-1
    nodename: testnode
    machine: i686
    clock source: unix
    pcre jit disabled
    detected number of CPU cores: 1
    current working directory: /etc/uwsgi/vassals
    *** running under screen session 1111.myscrn ***
    detected binary path: /usr/local/bin/uwsgi
    your processes number limit is 3940
    your memory page size is 4096 bytes
    detected max file descriptor number: 1024
    lock engine: pthread robust mutexes
    thunder lock: disabled (you can enable it with --thunder-lock)
    uwsgi socket 0 bound to UNIX address /var/run/nginx/testdomain_cgi-bin_uwsgi.sock fd 3
    your server socket listen backlog is limited to 100 connections
    your mercy for graceful operations on workers is 60 seconds
    mapped 175536 bytes (171 KB) for 2 cores
    *** Operational MODE: threaded ***
    initialized CGI mountpoint: /cgi-bin = /usr/local/nginx/vhosts/testdomain.com/cgi-bin
    *** no app loaded. going in full dynamic mode ***
    *** uWSGI is running in multiple interpreter mode ***
    spawned uWSGI master process (pid: 20825)
    spawned uWSGI worker 1 (pid: 20826, cores: 2)
    [pid: 20826|app: -1|req: -1/1] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:35:43 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 13 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    announcing my loyalty to the Emperor...
    [pid: 20826|app: -1|req: -1/2] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:35:54 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 2 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 1)
    [pid: 20826|app: -1|req: -1/3] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:36:04 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 5 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    [pid: 20826|app: -1|req: -1/4] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:36:16 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 3 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 1)
    [pid: 20826|app: -1|req: -1/5] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:36:28 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 3 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    [pid: 20826|app: -1|req: -1/6] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:36:39 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 3 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 1)
    [pid: 20826|app: -1|req: -1/7] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:36:51 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 5 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    [pid: 20826|app: -1|req: -1/8] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:37:03 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 2 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 1)
    [pid: 20826|app: -1|req: -1/9] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:37:15 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 3 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    [pid: 20826|app: -1|req: -1/10] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:37:27 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 6 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 1)
    [pid: 20826|app: -1|req: -1/11] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:37:39 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 12 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    [pid: 20826|app: -1|req: -1/12] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:37:51 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 4 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 1)
    [pid: 20826|app: -1|req: -1/13] XX.XX.XX.XXX () {42 vars in 678 bytes} [Wed Feb  5 11:38:03 2014] GET /cgi-bin/hellow.cgi => generated 282 bytes in 3 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)
    Wed Feb  5 11:38:56 2014 - uWSGI worker 1 screams: UAAAAAAH my master disconnected: i will kill myself !!!
    *** Starting uWSGI 2.0 (32bit) on [Wed Feb  5 11:38:56 2014] ***
    compiled with version: 4.7.2 on 31 January 2014 08:46:00
    os: Linux-3.2.0-4-686-pae #1 SMP Debian 3.2.51-1
    nodename: testnode
    machine: i686
    clock source: unix
    pcre jit disabled
    detected number of CPU cores: 1
    current working directory: /etc/uwsgi/vassals
    *** running under screen session 1111.myscrn ***
    detected binary path: /usr/local/bin/uwsgi
    your processes number limit is 3940
    your memory page size is 4096 bytes
    detected max file descriptor number: 1024
    lock engine: pthread robust mutexes
    thunder lock: disabled (you can enable it with --thunder-lock)
    uwsgi socket 0 bound to UNIX address /var/run/nginx/testdomain_cgi-bin_uwsgi.sock fd 3
    your server socket listen backlog is limited to 100 connections
    your mercy for graceful operations on workers is 60 seconds
    mapped 175536 bytes (171 KB) for 2 cores
    *** Operational MODE: threaded ***
    initialized CGI mountpoint: /cgi-bin = /usr/local/nginx/vhosts/testdomain.com/cgi-bin
    *** no app loaded. going in full dynamic mode ***
    *** uWSGI is running in multiple interpreter mode ***
    spawned uWSGI master process (pid: 20881)
    spawned uWSGI worker 1 (pid: 20882, cores: 2)
    

uWSGI 文档对于 vassal 选项heartbeat

    Argument: number

    (Vassal option) Announce vassal health to the emperor every N seconds.

uWSGI 文档对于皇帝的选择emperor-required-heartbeat

    Argument: number Default: 30

    Set the Emperor tolerance about heartbeats.

    When a vassal asks for ‘heartbeat mode’ the emperor will 
    also expect a ‘heartbeat’ at least every <secs> seconds.

答案1

使用 github 上的 2.0.1,它有更好的心跳代码。你的问题是 Emperor 容忍度(30 秒)和心跳频率(25)之间的时间差很小。2.0 中的一个错误是,每次请求时都会重置工作超时。除此之外,2.0.1 心跳会在第一个工作进程生成后立即触发,从而产生更好的结果(立即检测到损坏的应用程序)。关于工作进程重新加载仁慈,正确的选项是--worker-reload-mercy--reload-mercy适用于非工作进程)

相关内容