我正在尝试在 dotcloud 上的 nginx (v 1.3.14) 后面部署 gunicorn + gevent。我有几个问题。我的目标是改编python-on-dotcloud示例。到目前为止,我还不能让 websockets 部分使用这个设置。换句话说,我必须手动刷新我的页面以获取更新,而不是通过 socket.io。这对我来说都是全新的,所以这可能是一个完全的菜鸟错误。这是一个相关的问题。
以下是我对 python-on-dotcloud 示例所做的更改。
显然nginx(从 1.3.13 版开始)支持 web sockets。我更新了 python-on-dotcloud 示例中的构建器脚本以指向此开发版本:
nginx_download_url="http://nginx.org/download/nginx-1.3.14.tar.gz"
我将 gunicorn 设置为绑定到 unix 套接字,然后从 nginx.conf 设置 proxy_pass 以将流量上游发送到
proxy_pass http://appserver;
我定义了 appserver 的 gunicorn。我正在运行一个带有 gevent-socket.io 的 django 应用程序,它可以在没有运行 nginx 的情况下正常工作。(我只是将 gunicorn 绑定到 dotcloud.yml 中的 0.0.0.0:$PORT_WWW)
我的问题是这些。
我是否试图解决一个非问题?
一个。我已经阅读了大量建议将 gunicorn 放在 nginx 后面的内容。在 dotcloud 的负载均衡器在一线的背景下,这仍然是真的吗?
湾。如果我不希望我会受到 DoS 攻击,那么将 gunicorn 放在 nginx 后面仍然很重要吗?
是否可以像我尝试设置的那样通过 unix 套接字运行 websockets?
unix 套接字会破坏 dotcloud 上的缩放吗?
如果我需要改用端口,如何设置?我不认为我可以在同一个应用程序中分配两个 http 端口。如果我将它分成两个应用程序,那么我不确定如何将 PORT_WWW 环境变量从 gunicorn 应用程序传递到 nginx 应用程序,以便它最终可用于 nginx 安装后脚本,从而在生成的 nginx.conf 中可用。
关于为什么这不能按原样工作的任何想法?
我在下面包含了三个配置文件。让我知道其他人是否会提供帮助。谢谢!
点云.yml
www:
type: custom
buildscript: python/builder
systempackages:
# needed for the Nginx rewrite module
- libpcre3-dev
# needed to support python versions 2.7, 3.1, 3.2.
- python3-all
ports:
www: http
processes:
nginx: nginx
app: /home/dotcloud/env/bin/gunicorn -c /home/dotcloud/gunicorn.conf -b unix:/tmp/gunicorn.sock wsgi:application
#app: /home/dotcloud/env/bin/gunicorn -c /home/dotcloud/gunicorn.conf -b 0.0.0.0:$PORT_WWW wsgi:application
config:
# python_version can have one of the following values (2.6, 2.7, 3.1, 3.2). 2.6 is the default if no value is entered.
python_version: 2.7
data:
type: redis
db:
type: postgresql
nginx.conf.in(与常规的 nginx.conf 相同,只有 PORT_WWW 等待交换真实端口号)
# template for nginx.conf file.
# the file will be processed by the postinstall script
# it will insert the correct value for PORT_WWW and then put this
# file in /home/dotcloud/nginx/conf/nginx.conf when done.
# nginx will be managed by supervisord when it starts so we don't need daemon mode
daemon off;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
log_format combined-realip '$remote_addr ($http_x_real_ip) - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
access_log /var/log/supervisor/nginx_access.log combined-realip;
error_log /var/log/supervisor/nginx_error.log error;
gzip on;
upstream appserver {
server unix:/tmp/gunicorn.sock;
# For a TCP configuration:
# server 192.168.0.7:8000 fail_timeout=0;
}
server {
# PORT_WWW value is added via postinstall script.
listen @PORT_WWW@ default;
server_name localhost;
root /home/dotcloud/current/;
location / {
if ( -f /home/dotcloud/current/maintenance) {
return 503;
}
proxy_pass http://appserver;
proxy_http_version 1.1;
proxy_set_header upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
error_page 404 @404;
error_page 500 @500;
error_page 502 @502;
error_page 503 @503;
error_page 504 @504;
location @404 {
rewrite ^ /static/404.html;
}
location @500 {
rewrite ^ /static/500.html;
}
location @502 {
rewrite ^ /static/502.html;
}
location @503 {
rewrite ^ /static/503.html;
}
location @504 {
rewrite ^ /static/504.html;
}
location /static {
alias /home/dotcloud/current/static;
}
location /robots.txt {
alias /home/dotcloud/current/static/robots.txt;
}
location /favicon.ico {
alias /home/dotcloud/current/static/favicon.ico;
}
}
}
gunicorn.conf
workers = 1
worker_class = 'socketio.sgunicorn.GeventSocketIOWorker'
pidfile = '/tmp/gunicorn.pid'
debug = True
loglevel = 'debug'
errorlog = '/var/log/supervisor/gunicorn.log'
django_settings='/home/dotcloud/settings.py'
def post_fork(server, worker):
from psycogreen.gevent import patch_psycopg
patch_psycopg()
# MySQL
#def post_fork(server, worker):
# import pymysql
# pymysql.install_as_MySQLdb()