请求中的 Flask 请求在生产 WSGI 环境中失败
Flask Request within request fails on production WSGI environment
我在一个请求中提出一个请求,以适应mod我的面向服务的设计。在本地,此代码有效。但是在使用 ubuntu libapache2-mod-wsgi-py3 的生产环境中,我的嵌套请求失败了。
关键是这两个服务都存在于服务器上的同一个 <Virtualhost>
中,所以我怀疑这是一个线程问题。
在 newitem()
中调用的第二个请求在我的 WSGI Ubuntu 框上失败并显示 ConnectionRefusedError(111, 'Connection refused')
即使 API 端点在我 POST 时按预期运行在此上下文之外(例如 curl POST 到确切的 url)。
另一个重要的一点是,当我在不同的端口上有两个单独的烧瓶应用程序 运行 时,请求设计中的这个请求在我的本地工作。在我 运行 带有 --threaded
标志的 API 服务器之前,我在本地遇到了这个确切的问题。
我的服务器配置如下:
app2.wsgi:
#!env/bin/python3
import sys, os
sys.path.append('/var/www/api_app')
from app import create_app
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
application = create_app(os.getenv('FLASK_CONFIG') or 'default')
if __name__ == "__main__":
manager.run()
apache2/sites-available/default.conf:
<VirtualHost *:80>
DocumentRoot /var/www/html
# ------ WSGI config ------
WSGIDaemonProcess app1 user=www-data group=www-data threads=5
WSGIDaemonProcess app2 user=www-data group=www-data threads=5
WSGIScriptAlias /front_end /var/www/front_end/app2.wsgi
WSGIScriptAlias /api_app /var/www/api_app/app2.wsgi
WSGIScriptReloading On
<Directory /var/www/api_app>
WSGIProcessGroup app2
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/front_end>
WSGIProcessGroup app1
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
当我使用 --threaded 标志启动 API 服务时,以下代码在我的本地环境中运行良好 它在 [=45 上的 WSGI Apache2 上失败=]() 行。
@plant_material.route('/plant_material/new', methods=['GET', 'POST'])
def newitem():
form = PlantMaterialForm()
if form.validate_on_submit():
api_uri = current_app.config['API_SERVER_URI']
url = api_uri + "api/plant_material/new"
headers = {'Content-Type': 'application/json'}
print(request.form)
r = requests.post(url, data=json.dumps(request.form), headers=headers)
if r.status_code == 200:
return redirect(url_for('plant_material.index'))
elif r.status_code == 401:
flash('Whiteboard API Unauthorized')
elif r.status_code == 403:
flash('Whiteboard API Forbidden')
elif r.status_code == 500:
flash('Internal Server Error')
return render_template('plant_material/new.html', form=form)
如何在生产服务器上的请求中发出请求?
Apache 和 mod_wsgi 在这里处理并发;从一个 WSGI 应用程序到同一服务器上的另一个应用程序的格式良好的请求没有理由在这里失败。
- 确保没有防火墙阻止从本地主机到服务器的请求。例如,使用
curl
从命令行测试相同的 URL。
- 仔细检查您的假设;在测试您的连接是否有效时使用
current_app.config['API_SERVER_URI']
的实时值,而不是您假设的值。
- 换掉 HTTP 方法;尝试通过
subprocess
调用 运行 curl
,或使用 urllib2
访问 API
我在一个请求中提出一个请求,以适应mod我的面向服务的设计。在本地,此代码有效。但是在使用 ubuntu libapache2-mod-wsgi-py3 的生产环境中,我的嵌套请求失败了。
关键是这两个服务都存在于服务器上的同一个 <Virtualhost>
中,所以我怀疑这是一个线程问题。
在 newitem()
中调用的第二个请求在我的 WSGI Ubuntu 框上失败并显示 ConnectionRefusedError(111, 'Connection refused')
即使 API 端点在我 POST 时按预期运行在此上下文之外(例如 curl POST 到确切的 url)。
另一个重要的一点是,当我在不同的端口上有两个单独的烧瓶应用程序 运行 时,请求设计中的这个请求在我的本地工作。在我 运行 带有 --threaded
标志的 API 服务器之前,我在本地遇到了这个确切的问题。
我的服务器配置如下:
app2.wsgi:
#!env/bin/python3
import sys, os
sys.path.append('/var/www/api_app')
from app import create_app
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
application = create_app(os.getenv('FLASK_CONFIG') or 'default')
if __name__ == "__main__":
manager.run()
apache2/sites-available/default.conf:
<VirtualHost *:80>
DocumentRoot /var/www/html
# ------ WSGI config ------
WSGIDaemonProcess app1 user=www-data group=www-data threads=5
WSGIDaemonProcess app2 user=www-data group=www-data threads=5
WSGIScriptAlias /front_end /var/www/front_end/app2.wsgi
WSGIScriptAlias /api_app /var/www/api_app/app2.wsgi
WSGIScriptReloading On
<Directory /var/www/api_app>
WSGIProcessGroup app2
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/front_end>
WSGIProcessGroup app1
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
当我使用 --threaded 标志启动 API 服务时,以下代码在我的本地环境中运行良好 它在 [=45 上的 WSGI Apache2 上失败=]() 行。
@plant_material.route('/plant_material/new', methods=['GET', 'POST'])
def newitem():
form = PlantMaterialForm()
if form.validate_on_submit():
api_uri = current_app.config['API_SERVER_URI']
url = api_uri + "api/plant_material/new"
headers = {'Content-Type': 'application/json'}
print(request.form)
r = requests.post(url, data=json.dumps(request.form), headers=headers)
if r.status_code == 200:
return redirect(url_for('plant_material.index'))
elif r.status_code == 401:
flash('Whiteboard API Unauthorized')
elif r.status_code == 403:
flash('Whiteboard API Forbidden')
elif r.status_code == 500:
flash('Internal Server Error')
return render_template('plant_material/new.html', form=form)
如何在生产服务器上的请求中发出请求?
Apache 和 mod_wsgi 在这里处理并发;从一个 WSGI 应用程序到同一服务器上的另一个应用程序的格式良好的请求没有理由在这里失败。
- 确保没有防火墙阻止从本地主机到服务器的请求。例如,使用
curl
从命令行测试相同的 URL。 - 仔细检查您的假设;在测试您的连接是否有效时使用
current_app.config['API_SERVER_URI']
的实时值,而不是您假设的值。 - 换掉 HTTP 方法;尝试通过
subprocess
调用 运行curl
,或使用urllib2
访问 API