【问题标题】:Flask Request within request fails on production WSGI environment请求中的 Flask 请求在生产 WSGI 环境中失败
【发布时间】:2015-09-26 00:42:07
【问题描述】:

我在请求中提出请求,以适应我的面向服务的设计。在本地,此代码有效。但是在使用 ubuntu libapache2-mod-wsgi-py3 进行生产时,我的嵌套请求失败了。

关键点是这两个服务都存在于服务器上的同一个<Virtualhost> 中,所以我怀疑这是一个线程问题。

newitem() 中调用的第二个请求在我的 WSGI Ubuntu 机器上失败并出现ConnectionRefusedError(111, 'Connection refused'),即使当我在此上下文之外向其发布时 API 端点按预期运行(例如 curl POST 到确切的 url)。

另一个重要的一点是,当我有两个单独的烧瓶应用程序在不同的端口上运行时,reqest 设计中的这个请求在我的本地工作。在我使用 --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 服务时,以下代码在我的本地环境中运行良好它在 requests.post() 行上的 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)

如何在生产服务器上的请求中发出请求?

【问题讨论】:

  • 您是否检查过服务器防火墙是否允许从您的服务器连接到API_SERVER_URI?换句话说,你可以从同一台机器连接到服务器吗?
  • 我 ssh'd 进入服务器然后我从它工作的服务器 CURL: curl -v -L -G -d "q=&o=0&l=10&m=variety" 10.11.12.103/front_end/api/inventory ...产生 JSON 响应
  • 至少是这样。你有 110% 的把握,request.post() 会指向同一个 URL,对吧?只是检查。
  • 是的。我可以用硬编码的 URL 重现这个错误,但它以同样的方式失败。
  • 我已将我的 cmets 总结为一个对未来的访问者也应该有帮助的答案。

标签: apache python-3.x flask python-requests wsgi


【解决方案1】:

Apache 和 mod_wsgi 在这里处理并发;从一个 WSGI 应用到同一服务器上的另一个应用的格式良好的请求没有理由在这里失败。

  • 确保没有防火墙阻止从本地主机到服务器的请求。例如,使用 curl 从命令行测试相同的 URL。
  • 三重检查您的假设;在测试您的连接是否正常工作时使用current_app.config['API_SERVER_URI'] 的实时值,而不是您假设的值。
  • 更换 HTTP 方法;尝试从subprocess 调用运行curl,或使用urllib2 访问API

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2019-04-24
    • 2023-04-01
    • 1970-01-01
    • 2020-10-17
    • 2020-08-28
    • 2021-06-10
    相关资源
    最近更新 更多