美文网首页
Flask部署知识(Nginx+uWSGI+HTTPS)

Flask部署知识(Nginx+uWSGI+HTTPS)

作者: SMEB_ | 来源:发表于2019-08-15 17:44 被阅读0次

名词解析

WSGI

封装了处理HTTP响应、TCP连接等操作的接口。用户不需要自己实现接受HTTP请求、解析HTTP请求、发送HTTP响应等操作,不需要专注于HTTP规范等,可以专心编写Web业务。

werkzeug

flask自带WSGI工具包,可以搭建WSGI服务。但只用于开发,实际生产需要用更专业高效的Web服务器。

werkzeug无法作为生产服务器的原因:

  • 高并发:flask本身不支持并发,需要uwsgi+flask开启多个worker
  • 性能:使用这种模式,将解析http协议放到了nginx,由于nginx这样用C/C++高性能实现的服务器,比起Python脚本语言解析HTTP协议,效率要高。
uWSGI

Web服务器。它实现了WSGI协议、uwsgi、http等协议,是一个全站式的托管服务,支持多种编程语言。

Nginx

高效的Web服务器和反向代理服务器,可以用于负载均衡。也支持uWSGI的uwsgi协议,所以可以将Nginx与uWSGI结合起来。

  • 相较于Apache,Nginx支持高并发,部署简单,内存消耗少。但是Apache发展更久,模块更丰富,社区更大。

Nginx 以其高性能、稳定性、丰富的功能、简单的配置、低资源消耗而闻名。

Nginx 是一个可以为你的 Web 应用处理 HTTP 请求的服务器。对于典型的 Web 应用,Nginx 可以配置为 HTTP 请求进行以下操作:

  • 将请求 反向代理 至上游服务器(例如 Gunicorn、uWsgi、Apache 等)。
  • 为静态资源(Javascript 文件、CSS 文件、图像、文档、静态 HTML 文件)提供服务。
uWSGI与nginx的区别

uWSGI与Nginx同是Web服务器,但是Nginx对于处理静态文件更有优势、性能更好。表现在Nginx能进行负载均衡、HTTP缓存、高效处理高并发请求等等。所以把这两者结合起来使用,能够使服务器更稳定、高效。

在我们的模型中:

  • nginx是对外的服务器,外部浏览器通过url访问nginx,uwsgi是对内的服务器,主要用来处理动态请求。
  • nginx接收到浏览器发送过来的http请求,将包进行解析,分析url,
a.如果是静态文件请求就直接访问用户给nginx配置的静态文件目录,直接返回用户请求的静态文件, 

b.如果不是静态文件,而是一个动态的请求,那么nginx就将请求转发给uWSGI。

所以抽象出来
    
    用户 →  nginx   →   uWSGI
image

图片取自https://www.jianshu.com/p/85692a94e99b

uwsgi

uwsgi是一种线路协议而不是通信协议。uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型。


依赖安装

  • python
  • nginx
  • uwsgi
  • gcc(由于uwsgi是用c编写的所以依赖c编译器)

安装比较简单,不赘述。

工具主要使用Xshell和Xftp,均有官方免费版。


部署流程

  • 开发:windows10 + pycharm + Flask
  • 服务器:虚拟环境python3.6(conda管理) + centos7

1、项目文件上传至服务器

比较简单,提供三种做法

  1. git管理(推荐)
  2. Xftp工具上传至服务器
  3. scp命令(较少用在win和linux之间)
常用:
    scp /cloud/data/test.txt root@10.21.156.6:/cloud/data/

uwsgi

如果是简单项目、参数较少或者是测试 可以直接在命令行传递参数,启动项目

uwsgi --wsgi-file app.py --processes 4 --threads 2

当然,正常项目都是使用配置文件,可以更方便的修改、管理众多的参数。所以在项目目录下创建一个uwsgi.ini文件进行配置。

接下来记录一下主要使用到的一些参数以及参数配置时要注意的问题

    # 如果是使用虚拟环境运行的,要配置虚拟环境地址    
    home = /ENV

    # 项目根目录
    chdir = /项目地址
    # app所在的启动文件
    wsgi-file = /项目地址/app.py
    # flask特需的参数,指明app对象名称
    callable = hello
​    
​    
    # 最大进程数,推荐匹配cpu数
    processes = 4
    # 每个进程开启的线程数
    threads = 2
    
    # socket方式与nginx连接,此参数需要对应nginx参数。即同步连接通道。
    socket = 127.0.0.1:5001
    # 为socket操作文件赋予权限
    chmod-socket = 666

​    
    # 环境退出时自动清理,包含pid、sock和status文件
    vacuum = true
    # 日志路径
    logto = /tmp/uwsgi/uwsgi.log

让supervisor管理uwsgi,可以在uwsgi发生意外的情况下,会自动的重启。本次没有使用,先做下记录。

操作
uwsgi --ini /etc/uwsgi_config.ini       #初始化uwsgi服务
uwsgi --stop /etc/uwsgi_config.ini      #停止uwsgi服务
uwsgi --reload /etc/uwsgi_config.ini    #重新加载uwsgi服务

##重启命令可能无效,请尝试先杀死相关进程然后再重启
killall -9 nginx                        #kill所有 nginx相关进程
killall -9 uwsgi                        #kill所有 uwsgi 相关进程

nginx

nginx常见操作

如果不知道nginx启动文件在哪可以使用 whereis nginx

    # 启动
    /usr/local/nginx/sbin/nginx
    
    cd /usr/local/nginx/sbin
    
    # 判断配置文件是否正确
    ./nginx -t
    
    # 关闭
    ./nginx -s quit         # 完成已接受的连接请求,正常停止
    ./nginx -s stop         # 直接关闭,快速停止
    # 当然也可以杀死进程
    ps -ef | grep nginx
    kill -quit 进程id
    
    # 当配置文件错乱是 可-c指定该文件作为配置文件
    nginx -c ./nginx.conf
    
    # 平滑重启 不停止nginx的情况下,重新加载配置文件
    ./nginx -s reload


​    
    # 当端口重复占用时,可能是nginx服务卡死,可以先杀死,再重启
    # 查看正在监听的端口
    netstat -ntpl
    kill xx
普通配置
备份原有的nginx文件(备份是一个良好的习惯,再修改配置文件的时候最好都要备份一下)

cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

Nginx的顶层配置是nginx.conf。Nginx接受多层级的配置文件,这也使得用户可以针对自己的应用进行弹性的配置。


在Nginx中,由配置块来组织各个配置参数。

  • Main – 定义于 nginx.conf(所有不属于配置块的参数均属 Main 块)
  • Events – 定义于 nginx.conf
  • Http – 定义于 nginx.conf
  • Server – 定义于 application_name.conf

nginx默认安装的配置文件在/etc/nginx/nginx.conf

以下基础配置(缺省了一些不常用、默认参数)

# Nginx服务器的拥有者以及运行用户
user root;
# 进程数,推荐匹配服务器cpu核数
worker_processes  1;
# 错误日志
error_log /tmp/nginx/nginx.log;
# 定义pid的文件 默认
pid /run/nginx.pid;

# 定义了处理连接相关的参数
events {
    
    # 最大并发连接数
    worker_connections  1024;
}

http {      
    # 添加此文件下.conf的配置文件
    include /etc/nginx/conf.d/*.conf;
    # 默认返回给用户的文件类型。
    # 对于我们Flask应用来说,应该是动态生成的HTML文件 text/html;
    default_type  application/octet-stream;
    
    # 关于日志的参数保持默认
    
    # 开启高效传输模式
    sendfile            on;
    # 减少网络报文段的数量
    tcp_nopush          on;
    tcp_nodelay         on;
    # 保持连接的时间
    keepalive_timeout   65;
    # 最大块
    types_hash_max_size 2048;

    server {
        listen 80;                                          # 监听ipv4
        listen       [::]:80 ipv6only=on default_server;    # 监听ipv6
        # listen [::]:80    可同时监听ipv4、ipv6 若出错则采用上述方法
        server_name xxx.com;                                 # 可写域名或者ip地址
        
        # 定义了在请求未指定页面时所得到的默认页面。
        # 这里我们是使用FlaskWeb应用生成,因此注释掉
        # index index.html;
        
        # /指访问路径,可加前缀 例:/test 则在此location下url都需要添加前缀
        location / {                                        
            include uwsgi_params;
            # 关键!当uwsgi和nginx使用socket连接时,连接通道。必须和uwsgi文件里的socke参数一致
            uwsgi_pass 127.0.0.1:5001;​                
            # 访问静态资源时。在flask中可以将静态资源(如图片)放至staic供前端调用显示
            root /项目地址;
            # alias /项目地址
            # root和alias是对应的 都是指定当url请求时查找服务器资源的路径
            # alias 会将location的访问路径缺省再搜索服务器
            
        }
}

每行配置记得加 ; python写习惯了容易忘

当监听多个端口时则多加一个server。不能在同一个服务里监听多个端口。

另一个server使用443,配置https服务

https配置

此处只将相关配置,SSL证书、域名等获取方法请走百度

https可以通过uwsgi配置,也可以通过nginx配置。

按我们的模型逻辑,我们在nginx配置。首先申请SSL证书,然后下载相关文件获取到公钥密钥。_XXX.com_bundle.crt/2_XXX.com.key文件。上传至服务器(scp、xftp等方法都行),最好限制一下文件的读写权限。

以下至列举出不同于http的配置参数。

server_name  www.example.com;
server {
    # https默认是443端口
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
    
    # 公钥
    ssl_certificate /etc/nginx/1_xx.cn_bundle.crt;
    # 私钥
    ssl_certificate_key /etc/nginx/2_xx.cn.key;​        
    # 会话缓存,并使缓存可以在机器间共享。1m大概包含4000个会话
    # 简化握手阶段
    ssl_session_cache shared:SSL:1m;
    # 客户端可以重用会话缓存中ssl参数的过期时间。可以按需要增长。min
    # 可减少多次握手运算占用CPU资源
    ssl_session_timeout  10m;
    
    # 指定SSL服务器端支持的协议版本
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;     
    # 加密套件
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    # 有限服务器的加密套件
    ssl_prefer_server_ciphers on;

补一下私钥文件的相关信息

CSR:Cerificate Signing Request,证书签署请求文件,里面包含申请者的 DN(Distinguished Name,标识名)和公钥信息,在第三方证书颁发机构签署证书的时候需要提供。
证书颁发机构拿到 CSR 后使用其根证书私钥对证书进行加密并生成 CRT 证书文件,里面包含证书加密信息以及申请者的 DN 及公钥信息。

Key:证书申请者私钥文件,和证书里面的公钥配对使用,在 HTTPS 『握手』通讯过程需要使用私钥去解密客戶端发來的经过证书公钥加密的随机数信息,是 HTTPS 加密通讯过程非常重要的文件,在配置 HTTPS 的時候要用到

相关文章

网友评论

      本文标题:Flask部署知识(Nginx+uWSGI+HTTPS)

      本文链接:https://www.haomeiwen.com/subject/adctsctx.html