对于我目前的烧瓶部署,我必须设置一个uwsgi服务器。 这就是我创建uwsgi守护进程的方法:
sudo vim /etc/init/uwsgi.conf
# file: /etc/init/uwsgi.conf
description "uWSGI server"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /myproject/myproject-env/bin/uwsgi --uid www-data --gid www-data --home /myproject/myproject-env/site/F11/Engineering/ --socket /tmp/uwsgi.sock --chmod-socket --module F11 --callable app --pythonpath /myproject/myproject-env/site/F11/Engineering/ -H /myproject/myproject-env
但成功运行后:sudo start uwsgi
uwsgi start/running, process 1286
尝试通过浏览器访问该应用程序:
我收到 502 Bad Gateway
和nginx中的错误条目error.log:
2013/06/13 23:47:28 [错误] 743#0:* 296上游过早关闭 从上游,客户端读取响应头时连接: xx.161.xx.228,服务器:myproject.com,请求:“GET / show_records / 2013/6 HTTP / 1.1”,上游: “uwsgi:// unix:///tmp/uwsgi.sock:”,主持人:“myproject.com”
但是sock文件具有所需的权限:
srw-rw-rw- 1 www-data www-data 0 Jun 13 23:46 /tmp/uwsgi.sock
如果我在命令行中从上面运行exec
命令作为一个进程,它可以正常工作。为什么守护程序不能正常工作?
btw Nginx正在运行
vim /etc/nginx/nginx.conf
user www-data;
和vim /etc/nginx/sites-available/default
location / {
uwsgi_pass unix:///tmp/uwsgi.sock;
include uwsgi_params;
}
,它以sudo service nginx start
我在Ubuntu 12.04 LTS
上运行此功能。
我希望我提供了所有必要的数据,希望有人能引导我走向正确的方向。感谢。
答案 0 :(得分:19)
最后我在工作了近2天后解决了这个问题。我希望这个解决方案能够帮助遇到类似问题的其他flask / uwsgi用户。
我遇到了两个主要问题。
1)查找守护进程问题的最佳方法显然是日志文件和更清晰的结构。
sudo vim /etc/init/uwsgi.conf
将守护程序脚本更改为以下内容:
# file: /etc/init/uwsgi.conf
description "uWSGI server"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /home/ubuntu/uwsgi-1.9.12/uwsgi -c /myproject/uwsgi.ini
vim /myproject/uwsgi.ini
[uwsgi]
socket = /tmp/uwsgi.sock
master = true
enable-threads = true
processes = 5
chdir= /myproject/F11/Engineering
module=F11:app
virtualenv = /myproject/myproject-env/
uid = www-data
gid = www-data
logto = /myproject/error.log
这是设置守护程序的更简洁方法。另请注意最后一行如何设置日志文件。最初我将日志文件设置为/var/log/uwsgi/error.log
。经过大量的汗水和泪水后,我意识到守护进程正在以www-data
运行,因此无法访问/var/log/uwsgi/error.log
,因为error.log归root:root
所有。这使得uwsgi无声地失败。
我发现只需将日志文件指向我自己的/myproject
就更有效了,守护进程保证了www-data
的访问权限。并且不要忘记让www-data
可以访问整个项目,否则守护程序将失败并显示Internal Server error message
。 - >
sudo chown www-data:www-data -R /myproject/
重启uwsgi守护程序:
sudo service uwsgi restart
2)现在您有三个要查找的日志文件:
tail -f /var/log/upstart/uwsgi.log
- >启动时显示守护程序的问题
tail -f /var/log/nginx/error.log
- >拒绝wsgi访问时显示权限问题,通常是因为/tmp/uwsgi.sock
文件归root
而非www-data
所有。在这种情况下,只需删除sock文件sudo rm /tmp/uwsgi.sock
tail -f /myproject/error.log
- >显示uwsgi在您的应用程序中引发的错误
这个日志文件的组合帮助我弄清楚我在Flask应用程序中使用Flask-Babel导入错误。在这个意义上说,我使用库的方式是回到系统的语言环境以确定日期时间格式。
File "/myproject/F11/Engineering/f11_app/templates/show_records.html", line 25, in block "body"
<td>{{ record.record_date|format_date }}</td>
File "./f11_app/filters.py", line 7, in format_date
day = babel_dates.format_date(value, "EE")
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 459, in format_date
return pattern.apply(date, locale)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 702, in apply
return self % DateTimeFormat(datetime, locale)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 699, in __mod__
return self.format % other
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 734, in __getitem__
return self.format_weekday(char, num)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 821, in format_weekday
return get_day_names(width, context, self.locale)[weekday]
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 69, in get_day_names
return Locale.parse(locale).days[context][width]
AttributeError: 'NoneType' object has no attribute 'days'
这就是我使用Flask过滤器的方式:
import babel.dates as babel_dates
@app.template_filter('format_date')
def format_date(value):
day = babel_dates.format_date(value, "EE")
return '{0} {1}'.format(day.upper(), affix(value.day))
最奇怪的是,这段代码在开发环境中运行得非常好(!)。从命令行运行uwsgi作为根进程时,它甚至可以正常工作。但是当由www-data守护进程运行时它失败了。这必须与设置语言环境的方式有关,Flask-Babel正试图回归。
当我像这样更改导入时,它最终都与守护进程一起工作:
from flask.ext.babel import format_date
@app.template_filter('format_date1')
def format_date1(value):
day = format_date(value, "EE")
return '{0} {1}'.format(day.upper(), affix(value.day))
因此在使用Eclipse / Aptana Studio时要小心,它试图在代码中为类选择正确的命名空间。它真的可以变得难看。
从2天开始,它现在在Amazon Ec2(Ubuntu 12.04)上作为uwsgi守护程序工作得非常好。我希望这种经验可以帮助python开发人员。
答案 1 :(得分:0)
我放弃了,没有生成uwsgi.log,nginx一直在抱怨:
2014/03/06 01:06:28 [error] 23175#0: *22 upstream prematurely closed connection while reading response header from upstream, client: client.IP, server: my.server.IP, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/var/web/the_gelatospot/uwsgi.sock:", host: "host.ip"
每个请求。只有在将uwsgi作为服务运行时才会发生这种情况,因为它在任何用户下都可以正常运行。所以这可以从命令行(页面响应):
$exec /var/web/the_gelatospot/mez_server.sh
这不是(/etc/init/site_service.conf):
description "mez sites virtualenv and uwsgi_django" start on runlevel
[2345] stop on runlevel [06] respawn respawn limit 10 5 exec
/var/web/the_gelatospot/mez_server.sh
该过程将开始,但在每个请求中,nginx会抱怨已关闭的连接。奇怪的是,我有这个相同的配置工作正常2其他应用程序使用相同的nginx版本和相同的uwsgi版本以及这两个应用程序是夹层CMS应用程序。我尝试了我能想到的一切以及建议的内容。最后我转向了gunicorn工作正常:
#!/bin/bash
NAME="the_gelatospot" # Name of the application
DJANGODIR=/var/web/the_gelatospot # Django project directory
SOCKFILE=/var/web/the_gelatospot/gunicorn.sock # we will communicte using this unix socket
USER=ec2-user
GROUP=ec2-user # the user to run as, the group to run as
NUM_WORKERS=3 # how many worker processes should Gunicorn spawn
DJANGO_SETTINGS_MODULE=settings
#DJANGO_SETTINGS_MODULE=the_gelatospot.settings # which settings file should Django use
#DJANGO_WSGI_MODULE=the_gelatospot.wsgi # WSGI module name
DJANGO_WSGI_MODULE=wsgi
echo "Starting $NAME as `the_gelatospot`"
# Activate the virtual environment
cd $DJANGODIR
source ../mez_env/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
cd ..
# Start your Django GUnicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec gunicorn -k eventlet ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--log-level=debug \
--bind=unix:$SOCKFILE
这是一个不能作为服务工作的服务(nginx抱怨过早关闭的连接,没有应用程序日志数据通过)。
#!/bin/bash
DJANGODIR=/var/web/the_gelatospot/ # Django project directory
cd $DJANGODIR
source ../mez_env/bin/activate
uwsgi --ini uwsgi.ini
和uwsgi.ini:
[uwsgi]
uid = 222
gid = 500
socket = /var/web/the_gelatospot/uwsgi.sock
virtualenv = /var/web/mez_env
chdir = /var/web/the_gelatospot/
wsgi-file = /var/web/the_gelatospot/wsgi.py
pythonpath = ..
env = DJANGO_SETTINGS_MODULE=the_gelatospot.settings
die-on-term = true
master = true
chmod-socket = 666
;experiment using uwsgitop
worker = 1
;gevent = 100
processes = 1
daemonize = /var/log/nginx/uwsgi.log
logto = /var/log/nginx/uwsgi.logi
log-maxsize = 10000000
enable-threads = true
我去年从枪炮到uWSGI,直到现在我都没有问题,它似乎比枪炮快一点。现在我正在考虑坚持使用gunicorn。它越来越好,在安装了eventlet的情况下提供了更好的数字,并且更容易配置。
希望这种解决方法有所帮助。我仍然想知道uWSGI和nginx的问题,但我很难过。
<强>更新强> 因此,使用gunicorn允许我将服务器作为服务运行,同时在夹层中玩弄我遇到了这个错误:FileSystemEncodingChanged
为了解决这个问题,我在这里找到了解决方案: https://groups.google.com/forum/#!msg/mezzanine-users/bdln_Y99zQw/9HrhNSKFyZsJ
我不得不修改它,因为我不使用supervisord,我只使用upstart和shell脚本。我在mez_server.sh文件中执行gunicorn之前将其添加到了正确的位置:
export LANG=en_US.UTF-8, LC_ALL=en_US.UTF-8, LC_LANG=en_US.UTF-8
exec gunicorn -k eventlet ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--log-level=debug \
--bind=unix:$SOCKFILE
我也尝试使用uWSGI这样修复(因为使用uwsgi.ini后要短得多):
export LANG=en_US.UTF-8, LC_ALL=en_US.UTF-8, LC_LANG=en_US.UTF-8
exec uwsgi --ini uwsgi.ini
我仍然坚持使用gunicorn,因为它仍然处理问题,并引导我朝着正确的方向解决它。我很失望uWSGI在日志文件中没有提供输出,即使有这些参数,我只看到服务器启动过程就是这样:
daemonize = /var/log/nginx/uwsgi.log
logto = /var/log/nginx/uwsgi.logi
虽然nginx继续抛出断开连接错误,但uWSGI坐在那里就像没有发生任何事情一样。
答案 2 :(得分:-1)
使用daemon true命令运行的单行是
var updateTime = function() {
for (var i = 0; i < $scope.model.painel.length; i++) {
if ($scope.model.painel[i].status.id === 'E' && $scope.model.painel[i].restante.segundos > 0) {
var segundos = $scope.model.painel[i].restante.segundos - 1;
$scope.model.painel[i].restante.horaMinutoSegundo = getHoraMinutoSegundo(segundos);
}
}
$scope.apply();
};
将您的应用绑定到127.0.0.1:8000并且--deamon强制它以守护进程的形式运行
但是定义一个gunicorn_config.cfg文件并使用-c标志运行是一种很好的做法
了解更多信息:
https://gunicorn-docs.readthedocs.org/en/develop/configure.html