nginx, supervisor, celery

资料:

supervisor和nginx使用


1 、supervisor  管理进程工具
2 、nginx  反向代理, 负载均衡


安装nginx
$ sudo apt-get update
$ sudo apt-get install nginx
$ nginx -v
nginx version: nginx/1.10.3 (Ubuntu)


安装成功后请求服务器返回
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.



安装supervisor
$pip install supervisor
$ supervisord -v
3.3.3


一、nginx操作
nx/sites
nginx文件配置 /etc/nginx/conf.d目录下创建配置文件tornado_003.conf  然后将创建的配置文件加载到conf.d同目录下的nginx.conf文件的
‘Virtualenv Host Config’处, include /etc/nginx/conf.d/*.conf; #include /etc/nginx/sites-enabled/*; # 设置n个服务器,也叫集群 upstream tornadoes { server 127.0.0.1:9000; server 127.0.0.1:9001; } server { listen 10000 default_server; server_name localhost;      # 访问静态文件从该目录获取 location /static/ { alias /home/ubuntu/work/tornado_test_003/static/; }      # websocket模块,需要指定 1.1版本 该路由为websocket建立连接的路由 location /ws { proxy_http_version 1.1; proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://tornadoes; }      # 其他所有url location / { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_pass http://tornadoes; } } 检查语法 $ sudo service nginx configtest 重新加载配置文件并重启nginx $ sudo service nginx reload 重启nginx $ sudo service nginx restart 启动 $ sudo service nginx start 停止 $ sudo service nginx stop 查看nginx进程 $ ps aux | grep nginx 查看配置文件 $ vim /etc/nginx/nginx.conf 配置文件目录说明 sites-available 目录下放配置文件 sites-enabled 目录下放软连接文件,链接到sites-available目录中要使用的配置 点击:更多nginx参数说明二、supervisor操作 --点击 supervisor参数说明
项目目录创建supervisord.conf文件写入配置 [group:tornadoes] programs=tornado-9000,tornado-9001 [program:tornado-9000] command=python server.py -runserver -port=9000 directory=/home/ubuntu/work/tornado_test_003 use=ubuntu autorestart=true redirect_stderr=true stdout_logfile=/home/ubuntu/work/tornado_test_003/tornado003.log loglevel=info [program:tornado-9001] command=python server.py -runserver -port=9001 directory=/home/ubuntu/work/tornado_test_003 use=pyvip autorestart=true redirect_stderr=true stdout_logfile=/home/ubuntu/work/tornado_test_003/tornado003.log loglevel=info [supervisord] [supervisorctl] serverurl=http://192.168.10.128:9999 username=superadmin password=222 [inet_http_server] port=:9999 username=superadmin password=222 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 启动supervisor supervisord -c supervisord.conf 启动客户端 supervisorctl -c supervisord.conf 客户端内操作进程 > status # 查看程序状态 > stop tornadoes:tornado-8000 # 关闭 程序 > start tornadoes:tornado-8000 # 启动 程序 > restart tornadoes:tornado-8000 # 重启 程序 > reread # 读取有更新(增加)的配置文件,不会启动新添加的程序 > update # 重启配置文件修改过的程序 控制台操作进程 $ supervisorctl status $ supervisorctl stop tornadoes:tornado-8000 $ supervisorctl start tornadoes:tornado-8000 $ supervisorctl restart tornadoes:tornado-8000 $ supervisorctl reread $ supervisorctl update 操作步骤 (friend_server_test1) rock1@rock1:~/work/tornado_test/friends_server$ supervisorctl -c supervisord.conf tornadoes:tornado-8000 RUNNING pid 2534, uptime 0:00:19 tornadoes:tornado-8001 RUNNING pid 2535, uptime 0:00:19 supervisor> status tornadoes:tornado-8000 RUNNING pid 2534, uptime 0:02:39 tornadoes:tornado-8001 RUNNING pid 2535, uptime 0:02:39 supervisor> stop tornadoes:tornado-8000 tornadoes:tornado-8000: stopped supervisor> status tornadoes:tornado-8000 STOPPED Jul 24 04:28 AM tornadoes:tornado-8001 RUNNING pid 2535, uptime 0:03:04 supervisor> start tornadoes:tornado-8000 tornadoes:tornado-8000: started supervisor> status tornadoes:tornado-8000 RUNNING pid 2553, uptime 0:00:07 tornadoes:tornado-8001 RUNNING pid 2535, uptime 0:03:47 supervisor> restart tornadoes:tornado-8000 tornadoes:tornado-8000: stopped tornadoes:tornado-8000: started supervisor> reread tornadoes: changed supervisor> update tornadoes: stopped tornadoes: updated process group supervisor> 四、资料 nginx.conf文件默认内容 #启动进程的用户名 user www-data; #开启的工作进程数量,常设置成和cpu的数量相等 worker_processes auto; #进程的PID存放的位置 pid /run/nginx.pid; #工作模式及连接数上限 events { #单个后台worker process进程的最大并发链接数 worker_connections 768; # multi_accept on; } #设定http服务器,利用它的反向代理功能提供负载均衡支持 http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## #记录客户端链接 access_log /var/log/nginx/access.log; #记录错误日志 error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; gzip_disable "msie6"; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } #mail { # # See sample authentication script at: # # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript # # # auth_http localhost/auth.php; # # pop3_capabilities "TOP" "USER"; # # imap_capabilities "IMAP4rev1" "UIDPLUS"; # # server { # listen localhost:110; # protocol pop3; # proxy on; # } # # server { # listen localhost:143; # protocol imap; # proxy on; # } #} sites-enabled/default文件内容 ## # You should look at the following URL's in order to grasp a solid understanding # of Nginx configuration files in order to fully unleash the power of Nginx. # http://wiki.nginx.org/Pitfalls # http://wiki.nginx.org/QuickStart # http://wiki.nginx.org/Configuration # # Generally, you will want to move this file somewhere, and start with a clean # file but keep this around for reference. Or just disable in sites-enabled. # # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. ## # Default server configuration # server { #nginx监听主机和端口,default_server是当前server块是默认主机 listen 80 default_server; listen [::]:80 default_server; # SSL configuration # # listen 443 ssl default_server; # listen [::]:443 ssl default_server; # # Note: You should disable gzip for SSL traffic. # See: https://bugs.debian.org/773332 # # Read up on ssl_ciphers to ensure a secure configuration. # See: https://bugs.debian.org/765782 # # Self signed certs generated by the ssl-cert package # Don't use them in a production server! # # include snippets/snakeoil.conf; root /var/www/html; # Add index.php to the list if you are using PHP index index.html index.htm index.nginx-debian.html; #主机名,在收到http请求后,获取请求头中的HOST,与每个server中的server_name匹配 server_name _; #本地块在server块内部,通过server_name找到一台主机,location划分路径 #~ 大小写敏感 #~*忽略大小写 #^~ 只需匹配前面的部分 #@用于处理nginx内部的请求之间重定向,不直接处理请求 #/匹配所有路径 #以root设置资源路径, #location /aaa/ { # root /tmp/a/; #} #用户请求"/aaa/page"相当于 "/tmp/a/aaa/page" #以别名方式设置资源路径alias #location /aaa/ { alias /tmp/a/; #} #用户请求"/aaa/page"相当于 "/tmp/a/page" #配置首页 #location / { # root path; # index /index.html /index.php #} #返回码页面重定向 #location / { error_page 404 @aaa #location @aaa { # proxy_pass http://abc; #反向代理到其它服务器上 #} location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # include snippets/fastcgi-php.conf; # # # With php7.0-cgi alone: # fastcgi_pass 127.0.0.1:9000; # # With php7.0-fpm: # fastcgi_pass unix:/run/php/php7.0-fpm.sock; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # Virtual Host configuration for example.com # # You can move that to a different file under sites-available/ and symlink that # to sites-enabled/ to enable it. # #server { # listen 80; # listen [::]:80; # # server_name example.com; # # root /var/www/example.com; # index index.html; # # location / { # try_files $uri $uri/ =404; # } #} supervisor配置详解 http://lixcto.blog.51cto.com/4834175/1539136 有阵子没写博客了,这段时间一直在研究python django框架和前端相关的东西。楼主学通信的,对web这一块啥也不懂,学了一个礼拜django,接着学了2个礼拜前端,感觉还是做不出来一个好看的页面。周末去了趟上海,蹭大神的讲课,学会了套用bootstrap框架和heighcharts,页面上也终于出来能看的东西了,也算是在web开发方面迈出了阶段性的一步。 这两天公司终于派任务给我做了,不容易了啊,来了五个月了,终于有活干了。虽然只给了内测游戏服务器上的权限,不过也够楼主捣腾一段时间了。 这两天干的活,是让楼主写一个supervisor的listener,用来监控supervisor所管理子进程的状态,当子进程异常退出时,楼主写的这个listener将会触发报警。在这里总结下supervisor的知识吧 先说说supervisor是干什么的吧? supervisor这东西,其实就是用来管理进程的。咱们为什么要用supervisor呢?因为,相对于我们linux传统的进程管理方式来说,它有很多的优势,要不然咱们也不会闲着没事去用supervisor了。 OK,下面来看看supervisor有哪些好处吧。 简单 为啥简单呢?因为咱们通常管理linux进程的时候,一般来说都需要自己编写一个能够实现进程start/stop/restart/reload功能的脚本,然后丢到/etc/init.d/下面。这么做有很多不好的地方,第一我们要编写这个脚本,这就很耗时耗力了。第二,当这个进程挂掉的时候,linux不会自动重启它的,想要自动重启的话,我们还要自己写一个监控重启脚本。而,supervisor则可以完美的解决这些问题。好,怎么解决的呢,其实supervisor管理进程,就是通过fork/exec的方式把这些被管理的进程,当作supervisor的子进程来启动。这样的话,我们只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去就OK了。这样就省下了我们如同linux管理进程的时候,自己写控制脚本的麻烦了。第二,被管理进程作为supervisor的子进程,当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,所以当然也就可以对挂掉的子进程进行自动重启了,当然重启还是不重启,也要看你的配置文件里面有木有设置autostart=true了,这是后话。 精确 为啥说精确呢?因为linux对进程状态的反馈,有时候不太准确。为啥不准确?这个楼主也不知道啊,官方文档是这么说的,知道的告诉楼主一下吧,感激不尽。而supervisor监控子进程,得到的子进程状态无疑是准确的。 进程组 supervisor可以对进程组统一管理,也就是说咱们可以把需要管理的进程写到一个组里面,然后我们把这个组作为一个对象进行管理,如启动,停止,重启等等操作。而linux系统则是没有这种功能的,我们想要停止一个进程,只能一个一个的去停止,要么就自己写个脚本去批量停止。 集中式管理 supervisor管理的进程,进程组信息,全部都写在一个ini格式的文件里就OK了。而且,我们管理supervisor的时候的可以在本地进行管理,也可以远程管理,而且supervisor提供了一个web界面,我们可以在web界面上监控,管理进程。 当然了,本地,远程和web管理的时候,需要调用supervisor的xml_rpc接口,这个也是后话。 有效性 当supervisor的子进程挂掉的时候,操作系统会直接给supervisor发信号。而其他的一些类似supervisor的工具,则是通过进程的pid文件,来发送信号的,然后定期轮询来重启失败的进程。显然supervisor更加高效。。。至于是哪些类似supervisor工具,这个楼主就不太清楚了,楼主还听说过god,director,但是没用过。有兴趣的朋友可以玩玩 可扩展性 supervisor是个开源软件,牛逼点的,可以直接去改软件。不过咱们大多数人还是老老实实研究supervisot提供的接口吧,supervisor主要提供了两个可扩展的功能。一个是event机制,这个就是楼主这两天干的活要用到的东西。再一个是xml_rpc,supervisor的web管理端和远程调用的时候,就要用到它了。 权限 大伙都知道linux的进程,特别是侦听在1024端口之下的进程,一般用户大多数情况下,是不能对其进行控制的。想要控制的话,必须要有root权限。而supervisor提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程了。 不过这功能,用不用就看大伙自己的环境了 还有一些什么兼容性,稳定性,感觉用处不大,就不扯了。 安装 安装方法很简单。楼主的系统是debian,其它系统就不说了 pip install supervisor 生成配置文件 安装好supervisor之后,默认是没有生成配置文件的。可以通过以下命令生成配置文件 echo_supervisord_conf > /etc/supervisord.conf 我们通常是把配置文件放到/etc/下面,当然也可以放到任意路径下面。 启动 以下启动顺序由上到下优先级,依次递减 supervisord #默认去找$CWD/supervisord.conf,也就是当前目录 supervisord #默认$CWD/etc/supervisord.conf,也就当前目录下的etc目录 supervisord #默认去找/etc/supervisord.conf的配置文件 supervisord -c supervisord.conf #到指定路径下去找配置文件 supervisor组件 supervisord supervisord是supervisor的服务端程序。 干的活:启动supervisor程序自身,启动supervisor管理的子进程,响应来自clients的请求,重启闪退或异常退出的子进程,把子进程的stderr或stdout记录到日志文件中,生成和处理Event supervisorctl 这东西还是有点用的,如果说supervisord是supervisor的服务端程序,那么supervisorctl就是client端程序了。supervisorctl有一个类型shell的命令行界面,我们可以利用它来查看子进程状态,启动/停止/重启子进程,获取running子进程的列表等等。。。最牛逼的一点是,supervisorctl不仅可以连接到本机上的supervisord,还可以连接到远程的supervisord,当然在本机上面是通过UNIX socket连接的,远程是通过TCP socket连接的。supervisorctl和supervisord之间的通信,是通过xml_rpc完成的。 相应的配置在[supervisorctl]块里面 Web Server Web Server主要可以在界面上管理进程,Web Server其实是通过XML_RPC来实现的,可以向supervisor请求数据,也可以控制supervisor及子进程。配置在[inet_http_server]块里面 XML_RPC接口 这个就是远程调用的,上面的supervisorctl和Web Server就是它弄的 配置文件详解 [unix_http_server] file=/tmp/supervisor.sock ; socket文件的路径,supervisorctl用XML_RPC和supervisord通信就是通过它进行 的。如果不设置的话,supervisorctl也就不能用了 不设置的话,默认为none。 非必须设置 chmod=0700 ; 这个简单,就是修改上面的那个socket文件的权限为0700 不设置的话,默认为0700。 非必须设置 chown=nobody:nogroup ; 这个一样,修改上面的那个socket文件的属组为user.group 不设置的话,默认为启动supervisord进程的用户及属组。非必须设置 username=user ; 使用supervisorctl连接的时候,认证的用户 不设置的话,默认为不需要用户。 非必须设置 password=123 ; 和上面的用户名对应的密码,可以直接使用明码,也可以使用SHA加密 如:{SHA}82ab876d1387bfafe46cc1c8a2ef074eae50cb1d 默认不设置。。。非必须设置 [inet_http_server] ; 侦听在TCP上的socket,Web Server和远程的supervisorctl都要用到他 不设置的话,默认为不开启。非必须设置 port=127.0.0.1:9001 ; 这个是侦听的IP和端口,侦听所有IP用 :9001或*:9001。 这个必须设置,只要上面的[inet_http_server]开启了,就必须设置它 username=user ; 这个和上面的uinx_http_server一个样。非必须设置 password=123 ; 这个也一个样。非必须设置 [supervisord] ;这个主要是定义supervisord这个服务端进程的一些参数的 这个必须设置,不设置,supervisor就不用干活了 logfile=/tmp/supervisord.log ; 这个是supervisord这个主进程的日志路径,注意和子进程的日志不搭嘎。 默认路径$CWD/supervisord.log,$CWD是当前目录。。非必须设置 logfile_maxbytes=50MB ; 这个是上面那个日志文件的最大的大小,当超过50M的时候,会生成一个新的日 志文件。当设置为0时,表示不限制文件大小 默认值是50M,非必须设置。 logfile_backups=10 ; 日志文件保持的数量,上面的日志文件大于50M时,就会生成一个新文件。文件 数量大于10时,最初的老文件被新文件覆盖,文件数量将保持为10 当设置为0时,表示不限制文件的数量。 默认情况下为10。。。非必须设置 loglevel=info ; 日志级别,有critical, error, warn, info, debug, trace, or blather等 默认为info。。。非必须设置项 pidfile=/tmp/supervisord.pid ; supervisord的pid文件路径。 默认为$CWD/supervisord.pid。。。非必须设置 nodaemon=false ; 如果是true,supervisord进程将在前台运行 默认为false,也就是后台以守护进程运行。。。非必须设置 minfds=1024 ; 这个是最少系统空闲的文件描述符,低于这个值supervisor将不会启动。 系统的文件描述符在这里设置cat /proc/sys/fs/file-max 默认情况下为1024。。。非必须设置 minprocs=200 ; 最小可用的进程描述符,低于这个值supervisor也将不会正常启动。 ulimit -u这个命令,可以查看linux下面用户的最大进程数 默认为200。。。非必须设置 umask=022 ; 进程创建文件的掩码 默认为022。。非必须设置项 user=chrism ; 这个参数可以设置一个非root用户,当我们以root用户启动supervisord之后。 我这里面设置的这个用户,也可以对supervisord进行管理 默认情况是不设置。。。非必须设置项 identifier=supervisor ; 这个参数是supervisord的标识符,主要是给XML_RPC用的。当你有多个 supervisor的时候,而且想调用XML_RPC统一管理,就需要为每个 supervisor设置不同的标识符了 默认是supervisord。。。非必需设置 directory=/tmp ; 这个参数是当supervisord作为守护进程运行的时候,设置这个参数的话,启动 supervisord进程之前,会先切换到这个目录 默认不设置。。。非必须设置 nocleanup=true ; 这个参数当为false的时候,会在supervisord进程启动的时候,把以前子进程 产生的日志文件(路径为AUTO的情况下)清除掉。有时候咱们想要看历史日志,当 然不想日志被清除了。所以可以设置为true 默认是false,有调试需求的同学可以设置为true。。。非必须设置 childlogdir=/tmp ; 当子进程日志路径为AUTO的时候,子进程日志文件的存放路径。 默认路径是这个东西,执行下面的这个命令看看就OK了,处理的东西就默认路径 python -c "import tempfile;print tempfile.gettempdir()" 非必须设置 environment=KEY="value" ; 这个是用来设置环境变量的,supervisord在linux中启动默认继承了linux的 环境变量,在这里可以设置supervisord进程特有的其他环境变量。 supervisord启动子进程时,子进程会拷贝父进程的内存空间内容。 所以设置的 这些环境变量也会被子进程继承。 小例子:environment=name="haha",age="hehe" 默认为不设置。。。非必须设置 strip_ansi=false ; 这个选项如果设置为true,会清除子进程日志中的所有ANSI 序列。什么是ANSI 序列呢?就是我们的\n,\t这些东西。 默认为false。。。非必须设置 the below section must remain in the config file for RPC (supervisorctl/web interface) to work, additional interfaces may be added by defining them in separate rpcinterface: sections [rpcinterface:supervisor] ;这个选项是给XML_RPC用的,当然你如果想使用supervisord或者web server 这 个选项必须要开启的 supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] ;这个主要是针对supervisorctl的一些配置 serverurl=unix:///tmp/supervisor.sock ; 这个是supervisorctl本地连接supervisord的时候,本地UNIX socket 路径,注意这个是和前面的[unix_http_server]对应的 默认值就是unix:///tmp/supervisor.sock。。非必须设置 serverurl=http://127.0.0.1:9001 ; 这个是supervisorctl远程连接supervisord的时候,用到的TCP socket路径 注意这个和前面的[inet_http_server]对应 默认就是http://127.0.0.1:9001。。。非必须项 username=chris ; 用户名 默认空。。非必须设置 password=123 ; 密码 默认空。。非必须设置 prompt=mysupervisor ; 输入用户名密码时候的提示符 默认supervisor。。非必须设置 history_file=~/.sc_history ; 这个参数和shell中的history类似,我们可以用上下键来查找前面执行过的命令 默认是no file的。。所以我们想要有这种功能,必须指定一个文件。。。非 必须设置 The below sample program section shows all possible program subsection values, create one or more 'real' program: sections to be able to control them under supervisor. [program:theprogramname] ;这个就是咱们要管理的子进程了,":"后面的是名字,最好别乱写和实际进程 有点关联最好。这样的program我们可以设置一个或多个,一个program就是 要被管理的一个进程 command=/bin/cat ; 这个就是我们的要启动进程的命令路径了,可以带参数 例子:/home/test.py -a 'hehe' 有一点需要注意的是,我们的command只能是那种在终端运行的进程,不能是 守护进程。这个想想也知道了,比如说command=service httpd start。 httpd这个进程被linux的service管理了,我们的supervisor再去启动这个命令 这已经不是严格意义的子进程了。 这个是个必须设置的项 process_name=%(program_name)s ; 这个是进程名,如果我们下面的numprocs参数为1的话,就不用管这个参数 了,它默认值%(program_name)s也就是上面的那个program冒号后面的名字, 但是如果numprocs为多个的话,那就不能这么干了。想想也知道,不可能每个 进程都用同一个进程名吧。 numprocs=1 ; 启动进程的数目。当不为1时,就是进程池的概念,注意process_name的设置 默认为1 。。非必须设置 directory=/tmp ; 进程运行前,会前切换到这个目录 默认不设置。。。非必须设置 umask=022 ; 进程掩码,默认none,非必须 priority=999 ; 子进程启动关闭优先级,优先级低的,最先启动,关闭的时候最后关闭 默认值为999 。。非必须设置 autostart=true ; 如果是true的话,子进程将在supervisord启动后被自动启动 默认就是true 。。非必须设置 autorestart=unexpected ; 这个是设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected 和true。如果为false的时候,无论什么情况下,都不会被重新启动, 如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的退 出码的时候,才会被自动重启。当为true的时候,只要子进程挂掉,将会被无 条件的重启 startsecs=1 ; 这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启 动成功了 默认值为1 。。非必须设置 startretries=3 ; 当进程启动失败后,最大尝试启动的次数。。当超过3次后,supervisor将把 此进程的状态置为FAIL 默认值为3 。。非必须设置 exitcodes=0,2 ; 注意和上面的的autorestart=unexpected对应。。exitcodes里面的定义的 退出码是expected的。 stopsignal=QUIT ; 进程停止信号,可以为TERM, HUP, INT, QUIT, KILL, USR1, or USR2等信号 默认为TERM 。。当用设定的信号去干掉进程,退出码会被认为是expected 非必须设置 stopwaitsecs=10 ; 这个是当我们向子进程发送stopsignal信号后,到系统返回信息 给supervisord,所等待的最大时间。 超过这个时间,supervisord会向该 子进程发送一个强制kill的信号。 默认为10秒。。非必须设置 stopasgroup=false ; 这个东西主要用于,supervisord管理的子进程,这个子进程本身还有 子进程。那么我们如果仅仅干掉supervisord的子进程的话,子进程的子进程 有可能会变成孤儿进程。所以咱们可以设置可个选项,把整个该子进程的 整个进程组都干掉。 设置为true的话,一般killasgroup也会被设置为true。 需要注意的是,该选项发送的是stop信号 默认为false。。非必须设置。。 killasgroup=false ; 这个和上面的stopasgroup类似,不过发送的是kill信号 user=chrism ; 如果supervisord是root启动,我们在这里设置这个非root用户,可以用来 管理该program 默认不设置。。。非必须设置项 redirect_stderr=true ; 如果为true,则stderr的日志会被写入stdout日志文件中 默认为false,非必须设置 stdout_logfile=/a/path ; 子进程的stdout的日志路径,可以指定路径,AUTO,none等三个选项。 设置为none的话,将没有日志产生。设置为AUTO的话,将随机找一个地方 生成日志文件,而且当supervisord重新启动的时候,以前的日志文件会被 清空。当 redirect_stderr=true的时候,sterr也会写进这个日志文件 stdout_logfile_maxbytes=1MB ; 日志文件最大大小,和[supervisord]中定义的一样。默认为50 stdout_logfile_backups=10 ; 和[supervisord]定义的一样。默认10 stdout_capture_maxbytes=1MB ; 这个东西是设定capture管道的大小,当值不为0的时候,子进程可以从stdout 发送信息,而supervisor可以根据信息,发送相应的event。 默认为0,为0的时候表达关闭管道。。。非必须项 stdout_events_enabled=false ; 当设置为ture的时候,当子进程由stdout向文件描述符中写日志的时候,将 触发supervisord发送PROCESS_LOG_STDOUT类型的event 默认为false。。。非必须设置 stderr_logfile=/a/path ; 这个东西是设置stderr写的日志路径,当redirect_stderr=true。这个就不用 设置了,设置了也是白搭。因为它会被写入stdout_logfile的同一个文件中 默认为AUTO,也就是随便找个地存,supervisord重启被清空。。非必须设置 stderr_logfile_maxbytes=1MB ; 这个出现好几次了,就不重复了 stderr_logfile_backups=10 ; 这个也是 stderr_capture_maxbytes=1MB ; 这个一样,和stdout_capture一样。 默认为0,关闭状态 stderr_events_enabled=false ; 这个也是一样,默认为false environment=A="1",B="2" ; 这个是该子进程的环境变量,和别的子进程是不共享的 serverurl=AUTO ; The below sample eventlistener section shows all possible eventlistener subsection values, create one or more 'real' eventlistener: sections to be able to handle event notifications sent by supervisor. [eventlistener:theeventlistenername] ;这个东西其实和program的地位是一样的,也是suopervisor启动的子进 程,不过它干的活是订阅supervisord发送的event。他的名字就叫 listener了。我们可以在listener里面做一系列处理,比如报警等等 楼主这两天干的活,就是弄的这玩意 command=/bin/eventlistener ; 这个和上面的program一样,表示listener的可执行文件的路径 process_name=%(program_name)s ; 这个也一样,进程名,当下面的numprocs为多个的时候,才需要。否则默认就 OK了 numprocs=1 ; 相同的listener启动的个数 events=EVENT ; event事件的类型,也就是说,只有写在这个地方的事件类型。才会被发送 buffer_size=10 ; 这个是event队列缓存大小,单位不太清楚,楼主猜测应该是个吧。当buffer 超过10的时候,最旧的event将会被清除,并把新的event放进去。 默认值为10。。非必须选项 directory=/tmp ; 进程执行前,会切换到这个目录下执行 默认为不切换。。。非必须 umask=022 ; 淹没,默认为none,不说了 priority=-1 ; 启动优先级,默认-1,也不扯了 autostart=true ; 是否随supervisord启动一起启动,默认true autorestart=unexpected ; 是否自动重启,和program一个样,分true,false,unexpected等,注意 unexpected和exitcodes的关系 startsecs=1 ; 也是一样,进程启动后跑了几秒钟,才被认定为成功启动,默认1 startretries=3 ; 失败最大尝试次数,默认3 exitcodes=0,2 ; 期望或者说预料中的进程退出码, stopsignal=QUIT ; 干掉进程的信号,默认为TERM,比如设置为QUIT,那么如果QUIT来干这个进程 那么会被认为是正常维护,退出码也被认为是expected中的 stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10) stopasgroup=false ; send stop signal to the UNIX process group (default false) killasgroup=false ; SIGKILL the UNIX process group (def false) user=chrism ;设置普通用户,可以用来管理该listener进程。 默认为空。。非必须设置 redirect_stderr=true ; 为true的话,stderr的log会并入stdout的log里面 默认为false。。。非必须设置 stdout_logfile=/a/path ; 这个不说了,好几遍了 stdout_logfile_maxbytes=1MB ; 这个也是 stdout_logfile_backups=10 ; 这个也是 stdout_events_enabled=false ; 这个其实是错的,listener是不能发送event stderr_logfile=/a/path ; 这个也是 stderr_logfile_maxbytes=1MB ; 这个也是 stderr_logfile_backups ; 这个不说了 stderr_events_enabled=false ; 这个也是错的,listener不能发送event environment=A="1",B="2" ; 这个是该子进程的环境变量 默认为空。。。非必须设置 serverurl=AUTO ; override serverurl computation (childutils) The below sample group section shows all possible group values, create one or more 'real' group: sections to create "heterogeneous" process groups. [group:thegroupname] ;这个东西就是给programs分组,划分到组里面的program。我们就不用一个一个去操作了 我们可以对组名进行统一的操作。 注意:program被划分到组里面之后,就相当于原来 的配置从supervisor的配置文件里消失了。。。supervisor只会对组进行管理,而不再 会对组里面的单个program进行管理了 programs=progname1,progname2 ; 组成员,用逗号分开 这个是个必须的设置项 priority=999 ; 优先级,相对于组和组之间说的 默认999。。非必须选项 The [include] section can just contain the "files" setting. This setting can list multiple files (separated by whitespace or newlines). It can also contain wildcards. The filenames are interpreted as relative to this file. Included files *cannot* include files themselves. [include] ;这个东西挺有用的,当我们要管理的进程很多的时候,写在一个文件里面 就有点大了。我们可以把配置信息写到多个文件中,然后include过来 files = relative/directory/*.ini Nginx配置文件nginx.conf中文详解 http://www.cnblogs.com/hunttown/p/5759959.html #定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数。 worker_processes 8; #全局错误日志定义类型,[ debug | info | notice | warn | error | crit ] error_log /usr/local/nginx/logs/error.log info; #进程pid文件 pid /usr/local/nginx/logs/nginx.pid; #指定进程可以打开的最大描述符:数目 #工作模式与连接数上限 #这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。 #现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。 #这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。 worker_rlimit_nofile 65535; events { #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型 #是Linux 2.6以上版本内核中的高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。 #补充说明: #与apache相类,nginx针对不同的操作系统,有不同的事件模型 #A)标准事件模型 #Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll #B)高效事件模型 #Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。 #Epoll:使用于Linux内核2.6版本及以后的系统。 #/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。 #Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。 use epoll; #单个进程最大连接数(最大连接数=连接数*进程数) #根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为。 worker_connections 65535; #keepalive超时时间。 keepalive_timeout 60; #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。 #分页大小可以用命令getconf PAGESIZE 取得。 #[root@web001 ~]# getconf PAGESIZE #4096 #但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。 client_header_buffer_size 4k; #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 open_file_cache max=65535 inactive=60s; #这个是指多长时间检查一次缓存的有效信息。 #语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息. open_file_cache_valid 80s; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。 #语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location 这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态. open_file_cache_min_uses 1; #语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误. open_file_cache_errors on; } #设定http服务器,利用它的反向代理功能提供负载均衡支持 http{ #文件扩展名与文件类型映射表 include mime.types; #默认文件类型 default_type application/octet-stream; #默认编码 #charset utf-8; #服务器名字的hash表大小 #保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小. server_names_hash_bucket_size 128; #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。 client_header_buffer_size 32k; #客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。 large_client_header_buffers 4 64k; #设定通过nginx上传文件的大小 client_max_body_size 8m; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。 #sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。 sendfile on; #开启目录列表访问,合适下载服务器,默认关闭。 autoindex off; #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用 tcp_nopush on; tcp_nodelay on; #长连接超时时间,单位是秒 keepalive_timeout 120; #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。 fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; #gzip模块设置 gzip on; #开启gzip压缩输出 gzip_min_length 1k; #最小压缩文件大小 gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0) gzip_comp_level 2; #压缩等级 gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。 gzip_vary on; #开启限制IP连接数的时候需要使用 #limit_zone crawler $binary_remote_addr 10m; #负载均衡配置 upstream piao.jd.com { #upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。 server 192.168.80.121:80 weight=3; server 192.168.80.122:80 weight=2; server 192.168.80.123:80 weight=3; #nginx的upstream目前支持4种方式的分配 #1、轮询(默认) #每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 #2、weight #指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 #例如: #upstream bakend { # server 192.168.0.14 weight=10; # server 192.168.0.15 weight=10; #} #2、ip_hash #每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 #例如: #upstream bakend { # ip_hash; # server 192.168.0.14:88; # server 192.168.0.15:80; #} #3、fair(第三方) #按后端服务器的响应时间来分配请求,响应时间短的优先分配。 #upstream backend { # server server1; # server server2; # fair; #} #4、url_hash(第三方) #按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 #例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法 #upstream backend { # server squid1:3128; # server squid2:3128; # hash $request_uri; # hash_method crc32; #} #tips: #upstream bakend{#定义负载均衡设备的Ip及设备状态}{ # ip_hash; # server 127.0.0.1:9090 down; # server 127.0.0.1:8080 weight=2; # server 127.0.0.1:6060; # server 127.0.0.1:7070 backup; #} #在需要使用负载均衡的server中增加 proxy_pass http://bakend/; #每个设备的状态设置为: #1.down表示单前的server暂时不参与负载 #2.weight为weight越大,负载的权重就越大。 #3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误 #4.fail_timeout:max_fails次失败后,暂停的时间。 #5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。 #nginx支持同时设置多组的负载均衡,用来给不用的server来使用。 #client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug #client_body_temp_path设置记录文件的目录 可以设置最多3层目录 #location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡 } #虚拟主机的配置 server { #监听端口 listen 80 ; #域名可以有多个,用空格隔开 server_name www.jd.comjd.com; index index.html index.htm index.php; root /data/www/jd; #对******进行负载均衡 location ~ .*.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } #图片缓存时间设置 location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ { expires 10d; } #JS和CSS缓存时间设置 location ~ .*.(js|css)?$ { expires 1h; } #日志格式设定 #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址; #$remote_user:用来记录客户端用户名称; #$time_local: 用来记录访问时间与时区; #$request: 用来记录请求的url与http协议; #$status: 用来记录请求状态;成功是200, #$body_bytes_sent :记录发送给客户端文件主体内容大小; #$http_referer:用来记录从那个页面链接访问过来的; #$http_user_agent:记录客户浏览器的相关信息; #通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。 log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for'; #定义本虚拟主机的访问日志 access_log /usr/local/nginx/logs/host.access.log main; access_log /usr/local/nginx/logs/host.access.404.log log404; #对 "/" 启用反向代理 location / { proxy_pass http://127.0.0.1:88; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #以下是一些反向代理的配置,可选。 proxy_set_header Host $host; #允许客户端请求的最大单文件字节数 client_max_body_size 10m; #缓冲区代理缓冲用户端请求的最大字节数, #如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。 #无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误 client_body_buffer_size 128k; #表示使nginx阻止HTTP应答代码为400或者更高的应答。 proxy_intercept_errors on; #后端服务器连接的超时时间_发起握手等候响应超时时间 #nginx跟后端服务器连接超时时间(代理连接超时) proxy_connect_timeout 90; #后端服务器数据回传时间(代理发送超时) #后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据 proxy_send_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) #连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间) proxy_read_timeout 90; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 #设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小 proxy_buffer_size 4k; #proxy_buffers缓冲区,网页平均在32k以下的设置 #设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k proxy_buffers 4 32k; #高负荷下缓冲大小(proxy_buffers*2) proxy_busy_buffers_size 64k; #设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长 #设定缓存文件夹大小,大于这个值,将从upstream服务器传 proxy_temp_file_write_size 64k; } #设定查看Nginx状态的地址 location /NginxStatus { stub_status on; access_log on; auth_basic "NginxStatus"; auth_basic_user_file confpasswd; #htpasswd文件的内容可以用apache提供的htpasswd工具来产生。 } #本地动静分离反向代理配置 #所有jsp的页面均交由tomcat或resin处理 location ~ .(jsp|jspx|do)?$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080; } #所有静态文件由nginx直接读取不经过应用服务器 location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt| pdf|xls|mp3|wma)$ { expires 15d; } location ~ .*.(js|css)?$ { expires 1h; } } } Nginx判断语句 http://www.cnblogs.com/songxingzhu/p/6382007.html Nginx中if语句中的判断条件 一、if语句中的判断条件(nginx) 1、正则表达式匹配: ==:等值比较; ~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写; ~*:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写; !~:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写; !~*:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写; 2、文件及目录匹配判断: -f, !-f:判断指定的路径是否为存在且为文件; -d, !-d:判断指定的路径是否为存在且为目录; -e, !-e:判断指定的路径是否存在,文件或目录均可; -x, !-x:判断指定路径的文件是否存在且可执行; 二、例子: 有些公司可能有这样的需求,如:我的网站或者网页游戏需要更新,所有的用户或者玩家访问到的是一个停服更新页面,而本公司的IP可以访问,甚至说本公司的某个内网IP可以访问,用于确认更新成功与否,针对这个问题写了如下的访问控制规则: Nginx多重条件判断(只是一个简单的例子,自己可以更改或者增加更多的判断条件),下面是两个例子和写法: 1、可以作为nginx的停服更新使用,仅允许222.222.222.222或者内网的两个IP访问,其他IP都rewrite到停服页面 Nginx.conf中加入在你项目的正确位置 set $my_ip ''; if ( $remote_addr = 222.222.222.222){set $my_ip 1;} #注意这里的$remote_addr如何用了负载均衡的话,这里应该是$http_x_forwarded_for if ( $remote_addr = 192.168.1.170 ){ set $my_ip 1;} if ( $remote_addr = 192.168.1.169 ){ set $my_ip 1;} if ( $my_ip != 1) {rewrite ^/design/(.*)\.php$ /tingfu.html?$1&;} #将*.php转到tingfu.html 2、访问某个php应用的时候我只想让内部的某个IP访问,其他的IP都转到另一个PHP上。如下: 访问test.php,且IP不等222.222.222.222的跳转到55555.php: set $test ''; if ( $request_uri ~* /img/test.php ) { set $test P; } if ( $http_x_forwarded_for !~* ^222\.222\.222\.222.* ) { set $test "${test}C"; } if ( $test = PC ) { #当条件符合 访问test.php并且 ip不是222.222.222.222的 转发到55555.php rewrite ^(.*)$ /img/55555.php permanent; } 关于 Nginx upstream keepalive 的说明 https://www.cnblogs.com/kabi/p/7123354.html celery 文档 http://docs.jinkan.org/docs/celery/ 安装celery pip install celery 何为任务队列? 任务队列是一种在线程或机器间分发任务的机制。 消息队列的输入是工作的一个单元,称为任务,独立的职程(Worker)进程持续监视队列中是否有需要处理的新任务。 Celery 用消息通信,通常使用中间人(Broker)在客户端和职程间斡旋。这个过程从客户端向队列添加消息开始,之后中间人把消息派送给职程。 Celery 系统可包含多个职程和中间人,以此获得高可用性和横向扩展能力。 Celery 是用 Python 编写的,但协议可以用任何语言实现。迄今,已有 Ruby 实现的 RCelery 、node.js 实现的 node-celery 以及一个 PHP 客户端 ,语言互通也可以通过 using webhooks 实现。 执行任务的返回值: aa =adds.delay(11, 44) print aa.ready() #当任务完成时是True ,否则FALSE print aa.result #立即返回结果,如果没有结果返回none print aa.get() #阻塞等待返回值 定时任务配置 #celery配置信息 BROKER_URL = 'redis://127.0.0.1:6379/0' CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1' CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区 from datetime import timedelta CELERYBEAT_SCHEDULE = { 'add-5-seconds': { #任务名称 'task': 'create_app.adds', #设置执行的任务 'schedule': timedelta(seconds=5), #设置间隔时间 'args': (30, 16) #设置参数 } } 启动worker, -B可以同时启动定时任务 $ celery worker -A celery_test_module -l info -c 3 -B 启动定时任务 (flak_test) pyvip@ubuntu:~/flask_test_001$ celery -A create_app.celery beat -l info <qiniu.auth.Auth object at 0xb5da338c> ---------------- celery beat v4.1.0 (latentcall) is starting. __ - ... __ - _ LocalTime -> 2017-11-16 15:19:09 Configuration -> . broker -> redis://127.0.0.1:6379/0 . loader -> celery.loaders.app.AppLoader . scheduler -> celery.beat.PersistentScheduler . db -> celerybeat-schedule . logfile -> [stderr]@%INFO . maxinterval -> 5.00 minutes (300s) [2017-11-16 15:19:09,570: INFO/MainProcess] beat: Starting... [2017-11-16 15:19:09,596: INFO/MainProcess] Scheduler: Sending due task add-5-seconds (create_app.adds) [2017-11-16 15:19:14,591: INFO/MainProcess] Scheduler: Sending due task add-5-seconds (create_app.adds) [2017-11-16 15:19:19,591: INFO/MainProcess] Scheduler: Sending due task add-5-seconds (create_app.adds) [2017-11-16 15:19:24,591: INFO/MainProcess] Scheduler: Sending due task add-5-seconds (create_app.adds) [2017-11-16 15:19:29,591: INFO/MainProcess] Scheduler: Sending due task add-5-seconds (create_app.adds) 启动worker (flak_test) pyvip@ubuntu:~/flask_test_001$ celery worker -A create_app.celery --loglevel=info --concurrency=5 -------------- celery@ubuntu v4.1.0 (latentcall) ---- **** ----- --- * *** * -- Linux-4.4.0-98-generic-i686-with-Ubuntu-16.04-xenial 2017-11-16 15:20:54 -- * - **** --- - ** ---------- [config] - ** ---------- .> app: create_app:0xb5d5690c - ** ---------- .> transport: redis://127.0.0.1:6379/0 - ** ---------- .> results: redis://127.0.0.1:6379/1 - *** --- * --- .> concurrency: 5 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . create_app.adds [2017-11-16 15:20:54,252: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0 [2017-11-16 15:20:54,260: INFO/MainProcess] mingle: searching for neighbors [2017-11-16 15:20:55,276: INFO/MainProcess] mingle: all alone [2017-11-16 15:20:55,293: INFO/MainProcess] celery@ubuntu ready. [2017-11-16 15:21:00,728: INFO/MainProcess] Received task: create_app.adds[b473380e-6dc2-495c-a065-da2ad477e9f0] [2017-11-16 15:21:00,730: WARNING/ForkPoolWorker-1] period task done: b473380e-6dc2-495c-a065-da2ad477e9f0 [2017-11-16 15:21:00,731: WARNING/ForkPoolWorker-1] aaaaaa [2017-11-16 15:21:00,733: INFO/ForkPoolWorker-1] Task create_app.adds[b473380e-6dc2-495c-a065-da2ad477e9f0] succeeded in 0.00327149399982s: 46 [2017-11-16 15:21:05,710: INFO/MainProcess] Received task: create_app.adds[5bc9046e-e83e-45bc-a610-061bb420703f] [2017-11-16 15:21:05,715: WARNING/ForkPoolWorker-5] period task done: 5bc9046e-e83e-45bc-a610-061bb420703f [2017-11-16 15:21:05,720: WARNING/ForkPoolWorker-5] aaaaaa [2017-11-16 15:21:05,726: INFO/ForkPoolWorker-5] Task create_app.adds[5bc9046e-e83e-45bc-a610-061bb420703f] succeeded in 0.0113880900003s: 46 同时启动beat 和worker (flak_test) pyvip@ubuntu:~/flask_test_001$ celery worker -A create_app.celery --beat --loglevel=info --concurrency=5 <qiniu.auth.Auth object at 0xb5d76e6c> ---------------- -------------- celery@ubuntu v4.1.0 (latentcall) ---- **** ----- --- * *** * -- Linux-4.4.0-98-generic-i686-with-Ubuntu-16.04-xenial 2017-11-16 16:11:49 -- * - **** --- - ** ---------- [config] - ** ---------- .> app: create_app:0xb5d8342c - ** ---------- .> transport: redis://127.0.0.1:6379/0 - ** ---------- .> results: redis://127.0.0.1:6379/1 - *** --- * --- .> concurrency: 5 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . create_app.adds [2017-11-16 16:11:49,477: INFO/Beat] beat: Starting... [2017-11-16 16:11:49,487: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0 [2017-11-16 16:11:49,503: INFO/MainProcess] mingle: searching for neighbors [2017-11-16 16:11:49,533: INFO/Beat] Scheduler: Sending due task adds-5-seconds (create_app.adds) [2017-11-16 16:11:50,534: INFO/MainProcess] mingle: all alone [2017-11-16 16:11:50,558: INFO/MainProcess] celery@ubuntu ready. [2017-11-16 16:11:50,681: INFO/MainProcess] Received task: create_app.adds[ae1326b3-f7b0-4e00-b572-397de04e9bfd] [2017-11-16 16:11:50,687: WARNING/ForkPoolWorker-2] period task done: ae1326b3-f7b0-4e00-b572-397de04e9bfd [2017-11-16 16:11:50,693: WARNING/ForkPoolWorker-2] aaaaaa [2017-11-16 16:11:52,700: INFO/ForkPoolWorker-2] Task create_app.adds[ae1326b3-f7b0-4e00-b572-397de04e9bfd] succeeded in 2.012950648s: 46 [2017-11-16 16:12:07,131: INFO/MainProcess] Received task: create_app.adds[1803249c-3d9c-49d4-be42-34b0995708eb] [2017-11-16 16:12:07,133: WARNING/ForkPoolWorker-5] period task done: 1803249c-3d9c-49d4-be42-34b0995708eb [2017-11-16 16:12:07,136: WARNING/ForkPoolWorker-5] aaaaaa [2017-11-16 16:12:07,525: INFO/MainProcess] Received task: create_app.adds[00434f68-2420-4664-9ee6-3279ea35dd1f] [2017-11-16 16:12:07,527: WARNING/ForkPoolWorker-4] period task done: 00434f68-2420-4664-9ee6-3279ea35dd1f [2017-11-16 16:12:07,529: WARNING/ForkPoolWorker-4] aaaaaa [2017-11-16 16:12:09,148: INFO/ForkPoolWorker-5] Task create_app.adds[1803249c-3d9c-49d4-be42-34b0995708eb] succeeded in 2.014733645s: 55 可以开两个窗口,分别启动worker可以集群方式执行任务