現在のflaskデプロイメントでは、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を取得します
およびnginxerror.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
コマンドを実行すると、完全に正常に機能します。デーモンが正しく機能しないのはなぜですか?
ところで、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
で実行しています。
必要なデータをすべて提供したことを願っています。誰かが私を正しい方向に導いてくれることを願っています。ありがとう。
ついに私はこの問題に2日近く取り組んだ後、この問題を解決しました。このソリューションが、同様の問題を経験している他のフラスコ/ uwsgiユーザーに役立つことを願っています。
これを引き起こした2つの大きな問題がありました。
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
として実行されているため、error.logが/var/log/uwsgi/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)これで、注意すべき3つのログファイルができました。
tail -f /var/log/upstart/uwsgi.log
->起動時にデーモンの問題を表示します
tail -f /var/log/nginx/error.log
-> /tmp/uwsgi.sock
ファイルがwww-data
ではなくroot
によって所有されていることが多いため、wsgiアクセスが拒否されたときにアクセス許可の問題を示します。その場合は、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/AptanaStudioを使用する場合は注意が必要です。それは本当に醜くなる可能性があります。
2日間から、Amazon Ec2(Ubuntu 12.04)のuwsgiデーモンとして完全に正常に動作しています。この経験が仲間のpython開発者に役立つことを願っています。
私はあきらめました、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は閉じられた接続について文句を言います。不思議なことに、同じnginxバージョンと同じuwsgiバージョンを使用する他の2つのアプリで、この同じ構成が正常に機能しています。両方のアプリはメザニン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
昨年、gunicornからuWSGIに移行しましたが、今まで問題はありませんでした。また、gunicornよりも少し速いようでした。今、私はgunicornに固執することを考えています。それは良くなり、イベントレットがインストールされているとはるかに良い数字を出し、設定が簡単になります。
この回避策がお役に立てば幸いです。 uWSGIとnginxの問題を知りたいのですが、困惑しています。
更新:したがって、gunicornを使用すると、サーバーをサービスとして実行でき、メザニンをいじっているときに、次のエラーが発生しました:FileSystemEncodingChanged
これを修正するために、私はここで解決策を見つけました: https://groups.google.com/forum/#!msg/mezzanine-users/bdln_Y99zQw/9HrhNSKFyZsJ
また、supervisordを使用せず、upstartとシェルスクリプトのみを使用するため、少し変更する必要がありました。 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は何も起こらないようにそこに座っていました。