知其所以然:flask + uwsgi不要nginx,应该怎么写配置文件?
如果你在Google或者百度或者某些技术社区上面搜索 uwsgi+Flask
,你会发现大量的文章,是教你如何使用 uwsgi+flask+Nginx
搭建网站。如下图所示:
怪现状
而且这些文章,全部都像是约定俗成一样,一定会首先用命令行启动uwsgi,测试uwsgi与Flask运行是否正常,然后写uwsgi的配置文件。然后使用 Unix套接字
沟通uwsgi与Nginx。所以uwsgi的配置文件里面一定会写成类似于下面这样:
socket = /xxx/yyy/zzz.sock
Nginx的配置一定有类似于下面这一段:
location / { include uwsgi_params; uwsgi_pass unix:///xxx/yyy/zzz.sock; }
他们为什么要这样写?因为他们看的别的博客上就是这样写的!他们知其然,但是不知其所以然。
有什么问题?
这种写法本身没有问题,甚至Flask的官方文档里面也是这样写的,如下图所示:
但是他们这样写,有一个基本前提——就是Flask程序、uwsgi、Nginx三个东西运行在同一个服务器上。如果用Docker,那么这三个东西甚至需要运行到一个容器里面。
如果是一个小网站,服务器资源足够,那么这样写没有问题,Unix套接字安全性高,速度也快。
那么如果你同一个服务器上有三个Docker容器,每一个容器都有一个不同的网站,是不是每个容器里面都需要安装一个Nginx?
对于大一些的网站,Nginx需要做负载均衡,如果把Nginx和网站放在同一台服务器上,无论是Nginx拖垮了服务器,还是网站拖垮了服务器,都会导致很严重的问题。
能不能实现,一个服务器上直接安装Nginx,然后服务器上的三个网站分别在三个Docker容器里面,每个容器里面只有Flask和uwsgi,没有Nginx?
如果你的网站大一些,你在A服务器安装Nginx,在B、C、D、E、F服务器上不安装Nginx,只安装uwsgi + Flask,又怎么做?
所以进入我们今天的主题, 安装uwsgi+Flask(或者Django),但是不安装Nginx(DeployFlaskwithuwsgi but withoutNginx)
不使用Unix套接字的uwsgi
Unix套接字,本质上是一个文件(Unix/Linux哲学:一切皆文件),Nginx和uwsgi通过这个文件来进行通信。所以需要Nginx与uwsgi放在同一个机器上。
但实际上,uwsgi本身就是一个服务器,A服务器上的Nginx与B服务器上的uwsgi之间是可以通过http进行通信的。
要让uwsgi使用http进行通信,我们可以修改uwsgi的配置文件xxx.ini:
[uwsgi]module = wsgi:appmaster = trueprocess = 5threads = 100gevent = 100async = 100http-socket = 0.0.0.0:5001virtualenv = /Users/kingname/.local/share/virtualenvs/ActiveScoreApi-Ax_h-Y5w
其他参数的意义不是本文的重点,我们要关心的是 http-socket=0.0.0.0:5001
。它的作用把网站部署在本机的5001端口,并允许外网通过http访问。
写了这个配置文件以后,通过以下命令来启动uwsgi:
uwsgi --ini xxx.ini
然后你使用 IP:5001
就可以访问你的网站了。此时,如果你有Nginx,那么只需要在Nginx上设置反向代理,把80端口的请求代理到5001端口即可。
同理,把uwsgi和网站放在Docker镜像里面,容器开放5001端口。宿主机或者其他机器上的Nginx直接通过IP:端口 就可以访问容器里面的uwsgi,不再需要设置Unix套接字了。
另外,如果你阅读过uwsgi的官方文档,你还会发现,除了 http-socket=0.0.0.0:5001
外,你也可以把它改成 http=0.0.0.0:5001
。那么这两种写法是否一样呢?
在官方文档里面特别区分了它们的使用场景:
The http and http-socket options are entirely different beasts. The first one spawns an additional process forwarding requests to a series of workers (think about it as a form of shield, at the same level of apache or nginx), while the second one sets workers to natively speak the http protocol. TL/DR: if you plan to expose uWSGI directly to the public, use --http, if you want to proxy it behind a webserver speaking http with backends, use --http-socket.
简言之,如果你直接把uwsgi作为服务器,uwsgi启动以后,直接就把IP:端口拿给别人访问,那么你就可以使用 http
;如果你的uwsgi前面还挡了一个Nginx,那么你就使用 http-socket
。
- ASP.NET Web API标准的“管道式”设计
- ASP.NET Web API路由系统:Web Host下的URL路由
- ASP.NET Web API路由系统:路由系统的几个核心类型
- [ASP.NET] 如果将缓存“滑动过期时间”设置为1秒会怎样?
- [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证
- [CORS:跨域资源共享] 同源策略与JSONP
- [CORS:跨域资源共享] W3C的CORS Specification
- 通过扩展让ASP.NET Web API支持JSONP
- ASP.NET Web API自身对CORS的支持:从实例开始
- Generator:化异步为同步
- 超详细的大数据学习资源推荐(下)
- 中国大数据行业发展现状及趋势预测
- 【腾讯云的1001种玩法】十分钟轻松搞定云架构 · 负载均衡的几种类型
- 常用的Hadoop 文件查看工具
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据结构与算法(一)——学习工具的推荐
- sparc v8架构的异常处理
- 设计模式(五)-工厂方法模式
- html 的div或其他元素监听 resize事件不生效的解决办法
- 基于docker部署skywalking实现全链路监控
- 数据结构与算法(二)——十大排序算法
- VUE项目使用.env文件配置全局环境变量
- 设计模式学习(六)-抽象工厂模式
- 彻底完美解决安卓苹果手机点击输入框网页页面自动放大缩小
- 第22天:NLP实战(六)——基于PaddleHub的疫情期间网民情绪识别
- Echarts大数据可视化物流航向省份流向迁徙动态图,开发全解+完美参数注释
- Linux 常用操作以及概念
- GCD梳理与总结——封装
- 原生JS在网页上复制的所有文字后面自动加上一段版权声明
- 使用宝塔docker安装为知笔记私有部署