【问题标题】:serving flask app using gunicorn + nginx showing 404 [ec2]使用 gunicorn + nginx 服务烧瓶应用程序显示 404 [ec2]
【发布时间】:2017-05-03 17:13:55
【问题描述】:

我正在尝试通过关注digitalocean tutorial 来提供一个简单的 API。

为了测试,我之前通过 gunicorn 为 API 提供服务,方法是

$ gunicorn --bind 0.0.0.0:5000 trumporate.wsgi:app

并且卷曲 API 端点在 ec2 框内工作

$ curl -X GET http://0.0.0.0:5000/api/v1/trump/rant/
{
  "foo": "bar"
}

现在我通过创建 systemd 服务将这个 gunicorn 进程转移到启动时运行

# /etc/systemd/system/trumporate.service

[Unit]
Description=Gunicorn instance for trumporate
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/var/opt/trumporate
ExecStart=/usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunicorn-error.log trumporate.wsgi:app

[Install]
WantedBy=multi-user.target

我已经创建了文件

  • /var/log/trumporate/gunicorn-error.log
  • /var/log/trumporate/gunicorn-access.log

并将所有权和组更改为ubuntu

启用服务并重新启动后,我检查了状态

$ sudo systemctl status trumporate.service
● trumporate.service - Gunicorn instance for trumporate
   Loaded: loaded (/etc/systemd/system/trumporate.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2017-05-03 06:30:26 UTC; 1h 2min ago
 Main PID: 1122 (gunicorn)
    Tasks: 4
   Memory: 92.2M
      CPU: 1.390s
   CGroup: /system.slice/trumporate.service
           ├─1122 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic
           ├─1264 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic
           ├─1266 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic
           └─1267 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic

May 03 06:30:26 ip-172-31-25-173 systemd[1]: Started Gunicorn instance for trumporate.

按照 DO 教程,我尝试将 nginx 配置为代理端口 80 上的传入请求

$ cat /etc/nginx/sites-available/trumporate
server {
    listen 80;
    server_name private_ip_address;

    location / {
        include proxy_params;
        proxy_pass http://unix:/var/opt/trumporate/trumporate.sock;
    }
}

然后做了一个

$ ln -s /etc/nginx/sites-available/trumporate /etc/nginx/sites-enabled

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

现在,如果我尝试从 ec2 框外向 API 端点发出 GET 请求

$ curl -X GET http://public_ip/api/v1/trump/rant
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.0 (Ubuntu)</center>
</body>
</html>

当我也尝试从 ec2 容器内部执行此操作时,情况相同

$ curl -X GET http://localhost:80/api/v1/trump/rant/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.0 (Ubuntu)</center>
</body>
</html>

日志文件

# /var/log/nginx/access.log
dev_box_ip - - [03/May/2017:05:50:45 +0000] "GET /api/v1/trump/rant/ HTTP/1.1" 404 580 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"
127.0.0.1 - - [03/May/2017:06:13:26 +0000] "GET /api/v1/trump/rant/ HTTP/1.1" 404 178 "-" "curl/7.47.0"
dev_box_ip - - [03/May/2017:07:42:42 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"

/var/log/nginx$ cat error.log
/var/log/nginx$

/var/log/trumporate$ cat gunicorn-access.log
/var/log/trumporate$

$ cat gunicorn-error.log
[2017-05-03 06:28:41 +0000] [1884] [INFO] Starting gunicorn 19.7.1
[2017-05-03 06:28:41 +0000] [1884] [INFO] Listening at: unix:trumporate.sock (1884)
[2017-05-03 06:28:41 +0000] [1884] [INFO] Using worker: sync
[2017-05-03 06:28:41 +0000] [1889] [INFO] Booting worker with pid: 1889
[2017-05-03 06:28:41 +0000] [1890] [INFO] Booting worker with pid: 1890
[2017-05-03 06:28:41 +0000] [1891] [INFO] Booting worker with pid: 1891
[2017-05-03 06:29:48 +0000] [1884] [INFO] Handling signal: term
[2017-05-03 06:29:48 +0000] [1889] [INFO] Worker exiting (pid: 1889)
[2017-05-03 06:29:48 +0000] [1890] [INFO] Worker exiting (pid: 1890)
[2017-05-03 06:29:48 +0000] [1891] [INFO] Worker exiting (pid: 1891)
[2017-05-03 06:29:49 +0000] [1884] [INFO] Shutting down: Master
[2017-05-03 06:30:27 +0000] [1122] [INFO] Starting gunicorn 19.7.1
[2017-05-03 06:30:27 +0000] [1122] [INFO] Listening at: unix:trumporate.sock (1122)
[2017-05-03 06:30:27 +0000] [1122] [INFO] Using worker: sync
[2017-05-03 06:30:27 +0000] [1264] [INFO] Booting worker with pid: 1264
[2017-05-03 06:30:27 +0000] [1266] [INFO] Booting worker with pid: 1266
[2017-05-03 06:30:28 +0000] [1267] [INFO] Booting worker with pid: 1267
/var/log/trumporate$

编辑

烧瓶应用的相关部分

@app.route('/api/v1/trump/rant/')
def return_rant():
    foo = # logic
    return jsonify(rant=foo)

【问题讨论】:

    标签: python-3.x amazon-web-services ubuntu nginx gunicorn


    【解决方案1】:

    你做了nginx -s reload &amp;&amp; systemctl restart nginx吗?

    您可以尝试的另一件事是在 http 端口而不是套接字上进行绑定:

    --bind 127.0.0.1:6767 #in systemd config
    

    并按如下方式更改 nginx 配置:

    location / {
        include proxy_params;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:6767;
    }
    

    还有为什么你在 nginx 配置中有 private_ip?

    server_name private_ip_address;
    

    改成

    server_name "_";
    # OR
    server_name PUBLIC_IP;
    

    并从/etc/nginx/site-enabled 中删除所有默认配置


    1) 使用 server_name private_ip_address;?

    Nginx 使用 server_name 来检查传入请求的主机头,这不是私有地址。 (您通常使用域名或 URL 栏中的公共地址访问)

    2) 我删除了 /etc/nginx/site-enabled/default 目录以使事情开始工作。

    如果你的 server_name 设置不正确,nginx 会使用默认文件或包含default_server 的服务器块来处理请求。因此,我要求您删除该文件,以防万一您的服务器名称出现问题^_^

    另外,如果我将 API 绑定到端口而不是博客文章中建议的套接字文件,它会对 API 的性能产生什么影响?

    这通常是过早的优化,与烧瓶/python 尤其是数据库连接引起的瓶颈相比,您获得的任何差异都将完全在误差范围内。尽管请谨慎对待,因为我没有任何可靠的来源可以引用此内容。

    【讨论】:

    • 绑定到特定端口已成功。不确定为什么在这种特殊情况下无法绑定到套接字。一些快速问题,您可以将其添加到您的答案中,1) 使用 server_name private_ip_address;? 2)我删除了/etc/nginx/site-enabled/default dir 以使事情开始工作。你的cmets?
    • 另外,如果我按照博文的建议将 API 绑定到端口而不是套接字文件,它会对 API 的性能产生什么影响?
    猜你喜欢
    • 2012-11-19
    • 2023-03-25
    • 1970-01-01
    • 2017-11-01
    • 2021-01-24
    • 2017-06-06
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多