首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >uWSGI作为进程工作,而不是作为守护进程工作。

uWSGI作为进程工作,而不是作为守护进程工作。
EN

Stack Overflow用户
提问于 2013-06-13 23:56:22
回答 3查看 23.8K关注 0票数 16

对于当前的烧瓶部署,我必须设置一个uwsgi服务器。我是这样创建uwsgi守护进程的:

sudo vim /etc/init/uwsgi.conf

代码语言:javascript
运行
复制
# 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

代码语言:javascript
运行
复制
uwsgi start/running, process 1286

并试图通过浏览器访问应用程序:

我得到了一个502坏网关

以及nginx error.log中的错误条目:

2013/06/13 23:47:28错误743#0:*296上游过早关闭连接,从上游读取响应头,客户端:xx.161.x.228,服务器: myproject.com,请求:"GET /show/2013/6 HTTP/1.1",上游:“uwsgi://unix://tmp/uwsgi.sock:”,主机:"myproject.com“

但是sock文件拥有它所需的权限:

代码语言:javascript
运行
复制
srw-rw-rw- 1 www-data www-data 0 Jun 13 23:46 /tmp/uwsgi.sock

如果我作为一个进程从上面的命令行中运行exec命令,它将非常好地工作。为什么守护进程不能正常工作?

btw Nginx以vim /etc/nginx/nginx.conf的形式运行。

代码语言:javascript
运行
复制
user www-data;

vim /etc/nginx/sites-available/default

代码语言:javascript
运行
复制
location / {
                uwsgi_pass   unix:///tmp/uwsgi.sock;
                include        uwsgi_params;
        }

它以sudo service nginx start的形式启动

我是在Ubuntu 12.04 LTS上运行这个的。

我希望我已经提供了所有必要的数据,希望有人能引导我走向正确的方向。谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-16 22:14:40

经过近两天的努力,我终于解决了这个问题。我希望这个解决方案能帮助其他遇到类似问题的烧瓶/uwsgi用户。

我有两个主要问题导致了这一切。

1)发现守护进程问题的最佳方法显然是日志文件和更干净的结构。

sudo vim /etc/init/uwsgi.conf

将守护进程脚本更改为:

代码语言:javascript
运行
复制
# 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

代码语言:javascript
运行
复制
[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中失败。-->

代码语言:javascript
运行
复制
sudo chown www-data:www-data -R /myproject/

重新启动uwsgi守护进程:

代码语言:javascript
运行
复制
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的错误导入。从这个意义上讲,我使用库的方式正在倒退到系统的地区来确定日期时间格式。

代码语言:javascript
运行
复制
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'

这就是我使用水瓶过滤器的方式:

代码语言:javascript
运行
复制
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))

最奇怪的是,这段代码在dev环境(!)中运行得非常好。当从命令行将uwsgi作为根进程运行时,它甚至可以很好地工作。但是,当由www-data守护进程运行时,它会失败。这一定与如何设置地区有关,瓶巴贝尔正试图回到这个环境中去。

当我像这样更改导入时,它最终都与守护进程一起工作了:

代码语言:javascript
运行
复制
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试图为代码中的类选择正确的命名空间时,要小心。它真的会变丑。

现在它作为一个在亚马逊Ec2 (Ubuntu12.04)上的uwsgi守护进程运行的非常好,已经有两天了。我希望这一经验能帮助其他python开发人员。

票数 21
EN

Stack Overflow用户

发布于 2014-03-06 02:05:08

我放弃了,没有生成uwsgi.log,而nginx只是不停地抱怨:

代码语言:javascript
运行
复制
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作为服务运行时,作为一个进程在任何用户下启动良好,才会发生这种情况。因此,这将从命令行(页面响应)起作用:

代码语言:javascript
运行
复制
$exec /var/web/the_gelatospot/mez_server.sh

这不是(/etc/init/site_service.conf):

代码语言:javascript
运行
复制
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都会抱怨关闭的连接。奇怪的是,我有同样的配置,对于使用相同的nginx版本和相同的uwsgi版本的其他两个应用程序来说都很好,而且这两个应用程序都是夹层CMS应用程序。我尝试了我能想到的每一件事,还有建议。最后,我换了一种很好的方法:

代码语言:javascript
运行
复制
#!/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抱怨过早关闭连接,没有应用程序日志数据通过)。

代码语言:javascript
运行
复制
#!/bin/bash

DJANGODIR=/var/web/the_gelatospot/                # Django project directory
cd $DJANGODIR
source ../mez_env/bin/activate
uwsgi --ini uwsgi.ini

uwsgi.ini:

代码语言:javascript
运行
复制
[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,到目前为止我对此没有异议,它看起来也比火鸟快一些。现在我在考虑坚持到底。它变得更好了,安装了更好的eventlet数字,而且更易于配置。

希望这个解决办法能帮上忙。我仍然想知道uWSGI和nginx的问题,但我很困惑。

更新:因此,使用允许我作为服务运行服务器,并且在玩夹层时遇到了以下错误: FileSystemEncodingChanged

为了解决这个问题,我在这里找到了解决方案:Y99zQw/9HrhNSKFyZsJ

我不得不修改它一点,因为我不使用supervisord,我只使用upstart和shell脚本。在执行mez_server.sh文件中的gunicorn之前,我添加了以下内容:

代码语言:javascript
运行
复制
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短得多)尝试了这个修复:

代码语言:javascript
运行
复制
export LANG=en_US.UTF-8, LC_ALL=en_US.UTF-8, LC_LANG=en_US.UTF-8
exec uwsgi --ini uwsgi.ini

我仍然坚持,因为它仍然有效的问题,并引导我朝着正确的方向来解决它。我非常失望的是,uWSGI在日志文件中没有提供任何输出,即使有这些参数,我只看到了服务器启动过程,仅此而已:

代码语言:javascript
运行
复制
daemonize = /var/log/nginx/uwsgi.log
logto = /var/log/nginx/uwsgi.logi

当nginx不断抛出断开错误时,uWSGI坐在那里,好像什么都没发生一样。

票数 0
EN

Stack Overflow用户

发布于 2016-01-05 12:25:09

作为使用守护进程运行的一行,真正的命令是

代码语言:javascript
运行
复制
gunicorn  app.wsgi:application -b 127.0.0.1:8000 --daemon

将您的应用程序绑定到127.0.0.1:8000,并且--deamon强制它作为守护进程运行

但是定义一个gunicorn_config.cfg文件并使用-c标志运行是一个很好的实践。

欲了解更多情况:

https://gunicorn-docs.readthedocs.org/en/develop/configure.html

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17099114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档