Nginx
像 Gunicorn 这类 WSGI 服务器内置了 Web 服务器,所以我们不需要 Web 服务器也可以与客户端交换数据,处理请求和响应。但内置的 Web 服务器不够强健,虽然程序已经可以运行,但是更流行的部署方式是使用一个常规的 Web 服务器运行在前端,为 WSGI 服务器提供反向代理。
流行的开源 Web 服务器有 Nginx(http://nginx.org/ )、Apache(https://www.apache.org/ )等,因为我们上面使用了 Gunicorn ,所以这里选择使用和 Gunicorn 集成良好的 Nginx 。首先使用下面的命令安装 Nginx :
sudo apt install nginx
设置反向代理
在这种模式下,Nginx 作为代理服务器,监听来自外部的 80 端口的请求;而 Gunicorn 负责监听本地机 8000 端口的请求。Nginx 会把来自外部的请求转发给 Gunicorn 处理,接收到响应后再返回给客户端。这样做有下面这些好处:
- 提高处理静态文件的效率。Nginx 处理静态文件的速度非常快,而且可以对静态文件设置缓存。
- 提高安全系数。使用它可以避免直接暴露 WSGI 服务器,而且可以作为防火墙来防御网络攻击。
- 提高程序处理能力。设置反向代理可以缓冲请求,对请求进行预处理,交给 WSGI 服务器一个完整的 HTTP 请求。还可以设置负载均衡,优化请求处理效率。
当使用反向代理服务器后,Gunicorn 不需要再监听外部请求,而是直接监听本地机的某个端口。我们可以使用默认值,即本地机的 8000 端口。不过现在还不用着急运行,我们需要先来配置Nginx。
当我们安装了 Nginx 后,它会自动运行,现在本地访问远程主机的 IP 地址,会看到 Nginx 提供的测试页面。
Nginx测试页面
我们可以在 Nginx
的默认配置文件(/etc/nginx/nginx.conf
)中写入程序配置,但通常情况下,为了便于组织,我们可以在 /etc/nginx/sites-enabled/
或是 /etc/nginx/conf.d/
目录下为我们的 Flask
程序创建单独的 Nginx
配置文件。这个目录下的 default
文件存储了上面提到的测试页面的配置,也是作为一个配置文件示例,你可以修改它来作为程序配置,但为了更直观这里我们将直接删除它,然后使用 nano
为我们的程序创建一个新的配置文件(编写 etc/
下的配置文件需要超级用户权限,因此要添加 sudo
):
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo vi /etc/nginx/sites-enabled/qdbbs
Nginx
使用指令来组织配置。直接写在配置文件中的是全局指令,定义了 Nginx
的一些通用设置。其他的指令通常写在使用块指令定义的块中,块使用花括号包围。
Nginx配置的常用指令
提示
其他的语法规则包括:块通过花括号“{}”指定;每一行指令以“;”结尾;以“#”开头的是注释。
在 /etc/nginx/sites-enabled
目录下的配置文件可以直接定义 server
块,而不必添加 http
父块,因为这个文件的内容会被自动插入到全局配置文件(/etc/nginx/nginx.conf
)的 http
块中。
/etc/nginx/sites-enabled/qdbbs:Nginx配置
server {
listen 80 default_server;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:5000; # 转发的地址,即Gunicorn运行的地址
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
在这个 server
块中,listen
指令设置监听 80 端口,然后使用 server_name
设置被转发请求的 IP
或域名,这里使用_作为通配符(catch-all
)。如果你注册了域名并设置了域名解析,可以这样写前两行:
server {
listen 80;
server_name example.com;
...
}
在 server 块中我们创建两个 location 块。
第一个 location
块为 HTTP
规则 “/”
设置转发,proxy_pass
指定设置转发的目标位置,即本地机的 8000
端口,我们待会将要让 Gunicorn
服务器监听这个地址;proxy_set_header
指令用来重写一些请求首部,以便让程序正常工作;
第二个 location
块用来将发往 /static
路径下的请求发给 Nginx
处理,并使用 alias
指令设置这个 URL
对应文件系统中的具体路径。expires 30d
设置缓存时间为 30 天。当客户端发来静态文件的请求时会由 Nginx
直接从静态文件目录获取,这要比使用 Flask
获取快得多。
注意
这时需要考虑到扩展提供的静态文件问题,因为扩展内置的静态文件目录在虚拟环境的扩展包目录下,我们需要匹配到正确的路径,这也是为什么我不推荐使用扩展内置资源的原因之一。
Nginx 还有很多可用的配置选项。比如,你还可以使用它来设置Gzip压缩,这里的配置只是一个简单的示例,更多设置请访问文档(http://nginx.org/en/docs/ )了解。
更新配置文件后,我们可以通过下面的命令来测试语法正确性:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
如果一切正常,那么现在可以重启Nginx让配置生效:
sudo service nginx restart
当使用反向代理服务器后,Gunicorn 不需要再监听外部请求,而是直接监听本地机的某个端口。我们可以使用默认值,即本地机的 8000 端口。不过现在还不用着急运行,我们需要先来配置Nginx。
最后,我们使用下面的命令运行 Gunicorn ,这会默认监听本地机的 8000 端口,即我们在 Nginx 设置的转发目标地址:
gunicorn -w 4 wsgi:app
现在打开浏览器直接访问服务器域名就可以看到你的程序主页。如果你没有设置域名,那么可以通过服务器公网 IP 访问,比如 http://106.52.167.142/ 。