Django+Linux+Uwsgi+Nginx项目部署文档

WSGI

在生产环境中使用WSGI作为python web的服务器

WSGI:全拼为Python Web服务器网关接口,Python Web服务器网关接口,是项目默认会生成一个wsgi.py文件,确定了设置模块,uWSGI实现了WSGI的所有接口,是一个快速,自我修复,开发人员和系统管理员友好的服务器,C语言编写,效率高

Nginx

使用nginx的的作用主要包括负载均衡,反向代理

项目通过Django+Uwsgi+Nginx进行线上服务器部署

1、文件打包传服务器,通过xshell

文件 > 传输 > ZMODEM > 用ZMODEM发送 > 文件或压缩包

Linux下压缩包解压命令:

zip格式 : unzip 压缩包路径

tar.gz格式 : tar zxvf 压缩包路径

(rar格式压缩包解压较为复杂,尽量别传rar格式)

2、Xshell使用技巧

文件 > 新建,开启多终端

建议开多终端,这样对uwsgi、Nginx、项目代码进行调试修改时,可以避免在一个终端下来回切换目录,提高工作效率,具体开终端的个数根据实际需求来定,并且右击tab终端名重命名,更加方便知道哪个终端对应做哪些事情
未分类

3、修改配置文件问题

不管修改uwsgi的配置文件uwsgi.ini还是修改nginx配置文件nginx.conf,修改完都必须重启服务才能生效,并且启动服务要在指定的目录下面重启

4、Uwsgi的安装

方法1、pip install uwsgi(有网的情况下)

方法2、没网情况下去官网下载uwsgi压缩包,为tar.gz格式,传到服务器,进行解压,解压路径/lib/目录下面,然后切换到uwsgi文件目录,执行以下两个命令,即可完成安装,示意图如下(解压路径可以自定义,记下来,方便以后进行维护)

python setup.py  build

python setup.py  install

未分类

5、Django项目中配置uwsgi

1、项目目录(例如本例中DataBusines)下创建uwsgi.ini文件,配置如下

本地测试一般用:127.0.0.1即可,端口可以自定
未分类

线上的话用线上服务器IP,端口自定,该配置访问地址需要和nginx.conf中的配置一样
未分类
例如:这是后面的nginx.conf配置文件,两者地址和端口需要一致
未分类

6、Uwsgi的使用(启动、查看进程、关闭)

启动uwsgi.ini,需要切换到项目目录

启动uwsgi: uwsgi –ini uwsgi.ini

查看uwsgi进程:ps ajx|grep uwsgi

关闭uwsgi:

查阅相关资料文档,提到多种命令关闭方式,关闭命令的意义在于修改配置文件后,

一般需要重启uwsgi才会生效

1、uwsgi –stop uwsgi.pid(不好用,经常报pid找不到)

2、sudo pkill -f uwsgi -9(不好用,有可能报错,无效的-9)

3、killall -9 uwsgi(该命令最好用)
未分类

7、通过uwsgi网页访问

因为uwsgi本身就是web服务器,我们可以通过更改配置直接通过uwsgi进行访问网页

如下图:我们在服务器通过vi更改配置文件为http请求模式,更改后保存并重启uwsgi服务器,在我们自己的浏览器访问设置的IP和端口,成功显示页面,证明uwsgi配置成功

http模式: 直接用uwsgi时使用

socket模式: 使用Nginx时使用
未分类
未分类

8、Nginx的安装

方法1、pip install nginx(官方提供有该方法,但是之前在本地测试遇到坑,没有配好,建议通过方法二中压缩包方式安装)

方法2、没网情况下去官网下载nginx压缩包,为tar.gz格式,传到服务器,进行解压,解压路径/lib/目录下面,然后切换到nginx文件目录,执行以下三个命令,进行安装

./configure

make

sudo make install

未分类
执行完以上命令后,nginx被安装在了/usr/local/nginx/,安装成功
未分类

9、nginx的使用(启动、查看进程、关闭)

进入nginx安装目录:cd /usr/local/nginx/

启动nginx: sudo sbin/nginx

查看nginx进程: ps ajx|grep nginx

关闭uwsgi:

查阅相关资料文档,提到多种命令关闭方式,关闭命令的意义在于修改配置文件后,一般需要重启nginx才会生效

1、sudo sbin/nginx –s stop(不好用,报异常无效的-s)

2、sudo pkill -f uwsgi -9(不好用,报错,无效的-9)

3、killall -9 nginx(该命令最好用)

命令报错示意
未分类

10、nginx的配置文件nginx.conf配置

具体如图中所示,配置文件目录/usr/local/nginx/conf/nginx.conf,配置文件的修改需要通过vi进行修改
未分类
未分类

11、静态资源配置

配置静态资源目录是因为让静态资源通过nginx可以直接返回,不需要通过uwsgi,也就是让uwsgi只处理后端逻辑,不处理静态资源,优化性能

1、静态资源在nginx.conf中的配置,路径可以自定义
未分类
2、在服务器上创建如下目录

sudomkdir –vp /var/www/DataBusines/static/

3、修改目录权限

sudochmod 777 /var/www/DataBusiness/static/

4、项目代码中配置settings,加入该目录(本地演示在IDE中,线上可以用vi)
未分类

5、收集所有静态文件到static_root指定目录

服务器上切换到项目目录(DataBusines),执行如下命令收集

python  manage.py collectstatic

6、查看静态资源目录
未分类

12、更改uwsgi.ini配置

刚才在做uwsgi时候,用了http配置,现在nginx正式搭建起来,需要改成socket配置,修改完毕要重启uwsgi
未分类
Settings.py需要debug设置为不调试,允许访问的地址设置为服务器地址
未分类
以上步骤完成后,访问服务器主机地址和端口,如果nginx.conf中配置的为80端口,则地址栏不需要输入端口,因为浏览器请求端口也是默认为80端口,非80端口的需要自己在ip后面添加
未分类

Python3 Flask+nginx+Gunicorn部署(下)

继续上一篇文章,在上一篇文章中,我们已经把gunicorn和nginx运行并且安装好了,在这一篇,我们需要进行nginx与gunicorn端口进行绑定

上一篇,我们已经将gunicorn运行起来了

gunicorn -w 4 -b 127.0.0.1:8000 入口文件名:app

nginx操作目录:

/usr/local/nginx/sbin

在/usr/local/nginx/sbin目录下可以进行nginx的重启、重载、停止与启动。

在这里我们进行通过nginx反向代理网站域名与服务器,这里可能说得有些绕口,

通俗点:
就是别人访问我们的网站,是通过nginx反向代理再把访问请求发送到flask服务器上的。

首先我们设置一下nginx的配置文件

cd /usr/local/nginx/conf
vi nginx.conf

然后打开配置文件:

    #gzip  on;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    server {
        listen       80;
        server_name  www.00reso.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
           # root   html;
           # index  index.html index.htm;
            proxy_pass http://127.0.0.1:8000;
            access_log /home/admin/api_access.log;
            proxy_read_timeout 60;
            error_log  /home/admin/api_error.log;
        }

主要动的地方:

#gzip  on;
# 1代理的设置吧,这个都是这样设置的
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# 2绑定的域名
server_name  www.00reso.com;

# 3 监听本服务器的端口,设置log,请求时间等
proxy_pass http://127.0.0.1:8000;
            access_log /home/admin/api_access.log;
            proxy_read_timeout 60;
            error_log  /home/admin/api_error.log;

然后进行保存。

接下来重载一下nginx文件,在/usr/local/nginx/sbin/nginx下
使用命令:

sudo nginx -t

如果看到

1 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2 nginx: configuration file /etc/nginx/nginx.conf test is successful

就是代表成功了。

重新启动下nginx

sudo service nginx restart

这里重启nginx的命令可能会行不通,这时候,你用
ps -e aux|grep nginx 把nginx的进程杀掉,

然后在 /usr/local/nginx/sbin目录下再次启动nginx

nginx

如果看到:

[admin@izbp11722iq94py8qx691sz conf]$ ps -e aux|grep nginx
root      2657  0.0  0.0  24952   784 ?        Ss   Jun25   0:00 nginx: master process nginx
nobody    2658  0.0  0.1  25388  1752 ?        S    Jun25   0:00 nginx: worker process
admin    13814  0.0  0.0 112664   968 pts/2    S+   20:59   0:00 grep --color=auto nginx

这个情况,就是启动nginx成功了,

验证

1 使用本地ping

curl localhost:80

如果出现flask index页面的内容,就表示nginx与gunicorn配置成功,
2 远程直接输入www.00reso.com 看是否能进行访问,如果没有出现失败的页面,则访问成功,如果出现失败的页面,则大多是防火墙或80端口关闭了,这里我们需要把防火墙打开。

编辑防火墙白名单

[root@localhost ~]# vim /etc/sysconfig/iptables
增加下面一行代码
-A INPUT -p tcp -m state -- state NEW -m tcp --dport 80 -j ACCEPT
保存退出,重启防火墙
[root@localhost ~]# service iptables restart

未分类

这样就可以进行访问了

目前自己还在探索中,现在在快马加鞭的优化中,

因为flask+nginx+gunicorn部署自己踩过了很多坑,但是从坑中踩过来,差不多就都懂了。还好没放弃~~

Python3 Flask+nginx+Gunicorn部署(上)

这次主要是记录flask在python3 环境结合nginx +gunicorn在服务器上进行项目的部署

(一)运行环境

  • 虚拟机centos7
  • python3 环境
  • nginx
  • gunicorn
  • virtualenv

难点:nginx gunicorn的安装配置

(二)nginx、gunicorn简介

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等

gunicorn是一个python Wsgi http server,只支持在Unix系统上运行,来源于Ruby的unicorn项目。Gunicorn使用prefork master-worker模型(在gunicorn中,master被称为arbiter),能够与各种wsgi web框架协作。

(三)软件安装

(1)首先安装gunicorn

直接使用命令:pip install gunicorn

(2) 将gunicorn 加入到app.run()中,

这里我在路径为:/home/flaskproject/flaskweb 下新建一个myweb.py 作为入口函数
代码为:

from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
    return 'hello world'
if __name__ == '__main__':
    from werkzeug.contrib.fixers import ProxyFix
    app.wsgi_app = ProxyFix(app.wsgi_app)
    app.run(

未分类

(3)用命令启动gunicorn

在myweb.py路径下,一定要记住是当前路径下!!
方式一:

gunicorn myweb:app

未分类

python 虚拟环境的安装:

pip install virtualenv 

然后一顿骚操作:

mkdir flaskproject

cd flaskproject

virtualenv flaskprojectenv

然后进行激活:

source flaskprojectenv/bin/activate

正如下图一样的骚操作,之前我也是很少用虚拟环境的,现在感觉虚拟环境并没有那么神秘,因为以前是很拒绝,不会用,不过这次是会用了,

退出虚拟环境的命令是:deactivate(这里我只是说一下)

未分类

这时候我们本地服务器看一下是否运行起来(已经有hello world):

[root@localhost flaskproject]# curl http://127.0.0.1:8000
hello world[root@localhost flaskproject]# 

ctrl + c 停掉当前环境,我们使用第二种方式试一下
专门为处理高并发则要开多个进程和修改监听端口方式:

gunicorn -w 4 -b 127.0.0.1:8000 入口文件名:app

如下代码:

(flaskprojectenv) [admin@localhost flaskweb]$ gunicorn -w 4 -b 127.0.0.1:8000 myweb:app
[2018-05-28 10:57:11 -0400] [1813] [INFO] Starting gunicorn 19.8.1
[2018-05-28 10:57:11 -0400] [1813] [INFO] Listening at: http://127.0.0.1:8000 (1813)
[2018-05-28 10:57:11 -0400] [1813] [INFO] Using worker: sync
[2018-05-28 10:57:11 -0400] [1816] [INFO] Booting worker with pid: 1816
[2018-05-28 10:57:11 -0400] [1817] [INFO] Booting worker with pid: 1817
[2018-05-28 10:57:11 -0400] [1819] [INFO] Booting worker with pid: 1819
[2018-05-28 10:57:11 -0400] [1821] [INFO] Booting worker with pid: 1821

本地服务器已经运行了,但是我们远程并不能进行访问(win10访问虚拟机)

未分类

说明端口号没有打开,这时候我们需要把防火墙,端口号什么的都进行设置一下,可以看一下这篇博客:linux下nginx首次安装远程无法访问

主要是两个命令:

[root@localhost nginx-1.12.1] systemctl stop firewalld
[root@localhost nginx-1.12.1] systemctl stop iptalbes

接下来:我们进行nginx的配置安装与gunicorn的相结合并进行部署。

Python Web 腾讯云部署:flask+fabric+gunicorn+nginx+supervisor

最近看了《Flask Web开发–基于Python的Web应用开发实战》,还有廖雪峰老师的Python教程,前者是基于Web框架flask进行开发,后者是自己搭建了一个Web框架。Web框架致力于如何生成HTML代码,而Web服务器用于处理和响应HTTP请求。Web框架和Web服务器之间的通信,需要一套双方都遵守的接口协议。WSGI协议就是用来统一这两者的接口的。

为了部署一个完整的环境,本文将使用flask作为Web框架,Gunicorn作为WSGI容器,Nginx作为Web服务器,同时使用Supervisor进行进程管理,并使用Fabric实现自动化部署。

前期准备

申请一个腾讯云服务器Ubuntu Server 16.04.1 LTS 64位:

账户:ubuntu
密码:**********
内网ip:172.16.0.17
外网ip:139.199.184.183

使用《Flask Web开发》源码:

$ mkdir web
$ cd web
~/web$ git clone https://github.com/miguelgrinberg/flasky.git

设置并进入虚拟环境:

~/web$ cd flasky
~/web/flasky$ virtualenv venv
~/web/flasky$ source venv/bin/activate

安装对应的库:

(venv) ~/web/flasky$ cd requirements
(venv) ~/flasky/requirements$ pip3 install -r common.txt
(venv) ~/flasky/requirements$ pip3 install -r dev.txt
(venv) ~/flasky/requirements$ pip3 install -r heroku.txt
(venv) ~/flasky/requirements$ pip3 install -r prod.txt

创建数据库:

(venv) ~/flasky/requirements$ cd ..
(venv) ~/flasky/$ python3 manage.py deploy

Fabric

Fabric入门看这里https://www.jianshu.com/p/0be28f6c4607

新开一个终端,远程登陆服务器:

$ ssh [email protected]

在服务器端定义好部署结构:

ubuntu@VM $ mkdir web
ubuntu@VM $ mkdir web/flasky
ubuntu@VM $ mkdir web/log

即:

  • web/    Web App根目录
    • flasky/  存放python文件
    • log/    存放日志文件

我们使用Fabric将代码上传到服务器,首先,安装Fabric:

(venv) ~/web$ sudo apt-get install fabric

在web目录下创建fabfile.py(必须这个名字),写入:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os, re
from datetime import datetime

# 导入Fabric API:
from fabric.api import *

# 服务器登录用户名:
env.user = 'ubuntu'
# sudo用户为root:
env.sudo_user = 'root'
# 服务器地址,可以有多个,依次部署:
env.hosts = ['139.199.184.183']

_TAR_FILE = 'dist-flasky.tar.gz'

def build():
    includes = ['app', 'migrations', 'requirements', 'tests', 'venv', *.py', '*.sqlite']
    excludes = ['.*', '*.pyc', '*.pyo']
    local('rm -f dist/%s' % _TAR_FILE)
    with lcd(os.path.join(os.path.abspath('.'), 'flasky')):
        cmd = ['tar', '--dereference', '-czvf', '../dist/%s' % _TAR_FILE]
        cmd.extend(['--exclude='%s'' % ex for ex in excludes])
        cmd.extend(includes)
        local(' '.join(cmd))


_REMOTE_TMP_TAR = '/tmp/%s' % _TAR_FILE
_REMOTE_BASE_DIR = '/home/ubuntu/web/flasky'

def deploy():
    newdir = 'flask-%s' % datetime.now().strftime('%y-%m-%d_%H.%M.%S')
    # 删除已有的tar文件:
    run('rm -f %s' % _REMOTE_TMP_TAR)
    # 上传新的tar文件:
    put('dist/%s' % _TAR_FILE, _REMOTE_TMP_TAR)
    # 创建新目录:
    with cd(_REMOTE_BASE_DIR):
        sudo('mkdir %s' % newdir)
    # 解压到新目录:
    with cd('%s/%s' % (_REMOTE_BASE_DIR, newdir)):
        sudo('tar -xzvf %s' % _REMOTE_TMP_TAR)
    # 重置软链接:
    with cd(_REMOTE_BASE_DIR):
        sudo('rm -f flask')
        sudo('ln -s %s flask' % newdir)
        sudo('chown ubuntu:ubuntu flask')
        sudo('chown -R ubuntu:ubuntu %s' % newdir)
    # 重启Python服务和nginx服务器:
    #with settings(warn_only=True):
    #    sudo('supervisorctl stop flask')
    #    sudo('supervisorctl start flask')
    #    sudo('/etc/init.d/nginx reload')

使用fab命令将代码打包:

(venv) ~/web$ mkdir dist
(venv) ~/web$ fab build

将代码传上服务器:

(venv) ~/web$ fab deploy

Gunicorn部署

gunicorn入门看这里https://www.jianshu.com/p/260f18aa5462

代码上传给服务器后,可以直接运行manage.py文件,就可以访问网站了。可是实际情景中需要处理高并发访问的情况,我们使用Gunicorn来解决这个问题。

在服务器上进入flask所在目录,激活虚拟环境,并安装gunicorn:

ubuntu@VM ~/web/flasky/flask$ source venv/bin/activate
(venv) ubuntu@VM ~/web/flasky/flask$  sudo apt-get install gunicorn

使用gunicorn运行web应用(支持4个并发请求):

(venv) ubuntu@VM ~/web/flasky/flask$ gunicorn -w 4 -b 172.16.0.17:5000 manage:app

其中172.16.0.17是服务器内网ip,这样设置后就可以通过外网ip访问网站了。在浏览器地址栏中输入139.199.184.183:5000,就可以看到网站了。

Nginx

Nginx入门看这里

使用gunicorn的话,需要将端口暴露给外界,这不利于服务器的安全问题。Nginx是一个高性能的HTTP和反向代理服务器,通过配置一个代理服务器,可以实现反向代理的功能。所谓反向代理,是指一个请求,从互联网过来,先进入代理服务器,再由代理服务器转发给局域网的目标服务器。

先安装nginx:

(venv) ubuntu@VM ~$ sudo apt-get install nginx

设置反向代理服务器:在服务器,进入目录/etc/nginx/sites-available/,在目录下的default文件写入一个server。

首先,先备份default文件:

$ cd /etc/nginx/sites-available/
$ sudo cp default default-backup

在default文件中写入server:

server {
    listen 80;
    root /home/ubuntu/web/flasky/flask/;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    }
}

配置完成后,重启nginx:

$ sudo nginx -s reload

此时,该反向代理服务器就开始监听80端口。80端口是为HTTP开放的端口,浏览网页服务默认的端口号都是80 (8080端口跟80端口一样)。只要访问服务器,代理服务器就会将请求转发到127.0.0.1:5000.

回到目录/home/ubuntu/web/flasky/flask/下,再次使用gunicorn运行web app:

(venv) ubuntu@VM ~/web/flasky/flask$ gunicorn -w 4 -b 127.0.0.1:5000 manage:app

用的ip地址是127.0.0.1

而外界要访问网站只需要在浏览器地址栏输入139.199.184.183,使用默认端口80。这样web app实际使用的5000就不用暴露了。

Supervisor

supervisor入门看这里https://www.jianshu.com/p/0226b7c59ae2

如果你需要进程一直执行,若该进程因各种原因中断,也会自动重启的话,supervisor是一个很好的选择。

supervisor管理进程,是通过fork/exec的方式将这些被管理的进程当作supervisor的子进程来启动,所以我们只需要将要管理进程的可执行文件的路径添加到supervisor的配置文件中就好了。此时被管理进程被视为supervisor的子进程,若该子进程异常终端,则父进程可以准确的获取子进程异常终端的信息,通过在配置文件中设置autostart=true,可以实现对异常中断的子进程的自动重启。

安装supervisor:

(venv) ubuntu@VM ~$ sudo apt-get install supervisor

在目录/etc/supervisor/conf.d/下创建flask.conf,并加入:

;/etc/supervisor/conf.d/flask.conf

[program:flask]

command     = /home/ubuntu/.local/bin/gunicorn -w 4 -b 127.0.0.1:5000 manage:app
;这里/home/ubuntu/.local/bin/是我服务器上gunicorn的安装目录
directory   = /home/ubuntu/web/flasky/flask
user        = ubuntu
startsecs   = 3
autostart   = true

redirect_stderr         = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups  = 10
stdout_logfile          = /home/ubuntu/web/flasky/log/app.log

配置完后,进入目录/home/ubuntu/web/flasky/, 创建log目录:

(venv) ubuntu@VM ~/web/flasky$ mkdir log

启动supervisor:

(venv) ubuntu@VM /etc/supervisor$ sudo supervisord -c supervisor.conf                 

执行服务(运行app.py):

(venv) ubuntu@VM $ sudo supervisorctl start flask

此时,进程flask运行,执行command后边的语句,即/home/ubuntu/.local/bin/gunicorn -w 4 -b 127.0.0.1:5000 manage:app。

在浏览器地址栏输入139.199.184.183,使用默认端口80,即可访问网站。

如果supervisor遇到错误,可以在/var/log/supervisor/supervisord.log中查看日志;
如果app运行出现问题,可以在 /home/ubuntu/web/flasky/log/app.log中查看日志。

自动化部署

为了实现自动化部署,将上边fabfile.py文件的最后四个语句的注释取消,就能在将修改后的代码传上服务器后,用supervisor自动重载配置并重启flask进程。之后便可以直接访问网站。
因此,每次更改代码后,只需要执行以下两个语句,无需登陆服务器,便可以启动网站:

$ fab build
$ fab deploy

gunicorn配置文件

gunicorn的配置除了可以在命令行中设置,也可以使用配置文件实现更复杂的配置:

$ gunicorn -c gunicorn.py manage:app

gunicorn.py文件如下:

# gunicorn.py
import logging
import logging.handlers
from logging.handlers import WatchedFileHandler
import os
import multiprocessing
bind = '127.0.0.1:5000'       #绑定ip和端口号
backlog = 512                 #监听队列
chdir = '/home/test/server/bin'   #gunicorn要切换到的目的工作目录
timeout = 30      #超时
worker_class = 'gevent' #使用gevent模式,还可以使用sync 模式,默认的是sync模式
workers = multiprocessing.cpu_count() * 2 + 1    #进程数

threads = 2 #指定每个进程开启的线程数

loglevel = 'info' #日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'     #设置gunicorn访问日志格式,错误日志无法设置
"""
其每个选项的含义如下
        h           remote address
        l           '-'
        u           currently '-', may be user name in future releases
        t           date of the request
        r           status line (e.g. ``GET / HTTP/1.1``)
        s           status
        b           response length or '-'
        f           referer
        a           user agent
        T           request time in seconds
        D           request time in microseconds
        L           request time in decimal seconds
        p           process ID
        {Header}i   request header
        {Header}o   response header
"""
accesslog = "/home/ubutnu/web/flasky/log/gunicorn_access.log"      #访问日志文件
errorlog = "/home/ubutnu/web/flasky/log/gunicorn_error.log"        #错误日志文件

在本地将gunicorn.py放在/home/ubutnu/web/flasky/flask/目录下,在服务器端将/etc/supervisor/conf.d/flask.conf中的command改为:

command     = /home/ubuntu/.local/bin/gunicorn -c /home/ubutnu/web/flasky/flask/gunicorn.py manage:app

然后,在本地执行:

$ fab build
$ fab deploy

便可以访问网站了。

未分类

NGINX 如何实现读写限流的方法

这篇文章主要介绍了nginx 如何实现读写限流的方法的相关资料,这里提供实例代码及如何配置,需要的朋友可以参考下.

nginx 读写限流,万能的nginx,几行配置搞定。

先定义好规则,需要写在server外面

limit_req_zone $binary_remote_addr $uri zone=api_write:20m rate=10r/s; # 写
limit_req_zone $binary_remote_addr $uri zone=api_read:20m rate=50r/s; # 读

把需要限速的接口应用上上面的规则

写10/秒

location = /api/v1/trade {
limit_req zone=api_write burst=10;
proxy_pass http://api_server;
}

查询50/秒

location /api/v1/query {
limit_req zone=api_read burst=50;
proxy_pass http://api_server;
}

Nginx请求限制

连接频率限制:limit_conn_module
请求频率限制:limit_req_module

HTTP协议的连接与请求:

未分类

HTTP请求建立在一次TCP连接基础上

一次TCP请求至少产生一次HTTP请求,也可以产生多次。

1. 连接限制

Syntax: limit_conn_zone key zone=name:size;
Default: ——
Context: http
  • limit_conn_zone :开辟一块空间
  • key:以什么作为key存储,比如可以用ip作为限制,则ip为key
  • zone=name:size:name为申请空间的名字,方便后面其他调用,size表示大小
Syntax: limit_conn zone number;
Default: ——
Context: http,server,location
  • zone:表示空间名字
  • number:表示同一时间运行的并发个数

2. 请求限制

Syntax: limit_req_zone key zone=name:size rate=rate;
Default: ——
Context:http

前面部分的语法和前面类似,rate表示的是请求的速率。

Syntax: limit_req zone=name [burst=number][nodelay];
Default:——
Context:http,server,location

3. 测试

测试一:

# 设置空间名为req_zone 大小为1m,速率为每秒1个,地址的二进制的客户端地址用于节省空间
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
    location / {
        root /opt/app/code;
        limit_req zone=req_zone; 
        index  index.html index.htm;
    }

未分类

测试二:

# 设置空间名为req_zone 大小为1m,速率为每秒1个,地址的二进制的客户端地址用于节省空间
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
    location / {
        root /opt/app/code;
        limit_req zone=req_zone burst=3 nodelay; 
        index  index.html index.htm;
    }

burst为3表示有三个延迟响应,起到缓冲作用,其他直接返回。

未分类

测试三:

    limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
    location / {
        root /opt/app/code;
        limit_conn conn_zone 1;
        index  index.html index.htm;
    }

未分类

nginx配置https的部署实践

http以明文的形式在浏览器和服务器之间交换数据,没有任何数据加密,攻击者可以在截取之间的信息并读懂,这明显不安全,所以现在浏览器浏览器都要求网站域名配置SSL域名证书,以https协议传输内容。

那问题来了:

未分类

HTTP与HTTPS

  • HTTP:超文本传输协议
  • HTTPS:超文本传输安全协议

简单来说,可以用这个公式:HTTPS = HTTP + SSL

  • SSL:安全套接层,一种安全协议

也就是说:

为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

未分类


未分类

申请ssl域名证书

登录腾讯云之后,找到SSL证书管理栏目,购买或者申请域名证书。

注意:

  • 免费证书有效期是一年,一年后手动重新申请即可
  • 域名需要备案

未分类

申请完了之后,就可以下载证书啦~

未分类

如图下载的域名证书,可以配置到Apache、Nginx、Tomcat等服务器上面。

未分类

nginx配置https步骤

好,接下来我们进入正题,给nginx配置域名证书嘿~

解压下载下来的域名证书,获取Nginx里面的两个文件。

未分类

  • crt文件是以PEM格式存在的证书,可以用于不同的程序和设备
  • key文件是授权文件

第一步

把crt和key文件上传到nginx的conf目录下。

未分类

第二步

nginx.conf或自定义配置文件上配置SSL证书。

未分类

HTTPS的默认端口是443,就像HTTP的默认端口80一样,从图中可以看到,这个服务最后代理的是8080端口的tomcat。

第三步

配置完了第二步已经完成一大半了,只要用户输入https://www.java-mindmap.com就可以访问我的社区网站,但是一般用户都懒得输入https://,而不输入的话默认就是发起http链接,所以,需要还需要配置http强制转换成https的链接。

未分类

这样,当用户访问http链接时候,强制转成了https的服务了。

未分类

至此,HTTPS配置成功~

未分类

部署 Django 项目背后的原理:为什么需要 Nginx 和 Gunicron这些东西?

相信用过 Django 的同学一定会被 “Very easy to setup” 惊艳到。只要一行命令,就可以在 admin 界面看到一个完整的登陆注册。但是到了部署的时候,你一定会被网上复杂的部署教程搞的头晕,为啥本地开发这么简单,到了服务器却需要又是 Nginx,又是 uWSGI 这种东西呢?

未分类
摘自The Full Stack Python Guide to Deployments 一书

本文试图解释这些程序在一个 Web 服务中扮演的角色,为什么部署 Python web程序需要它们。本文不介绍如何部署 Django 应用等,这一类教程网上有很多,读者可自行搜索。其中 Nginx 和 Apache 算是一类的,可以替换。Gunicorn 和 uWSGI 的角色是类似的。同理最后端的 Web 框架是一类的,比如 Django 和 Flask。本文的内容替换以上任意一个应该也适用。

如果你读了网上任意一篇教程,你应该知道一个完整的部署应该类似这样:

HTTP Server <-----> WSGI <-----> App

最后后面的 App 我们知道,只要 runserver 就可以访问了,但是 Django 的文档明确说明:

DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that’s how it’s gonna stay. We’re in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.)

即 Django 做的事情只是一个框架,不会去关心一些安全问题、HTTP 的性能问题等。所以我们需要一个专业的 HTTP 服务器。这就出现了 Nginx 或 Apache。那么如何将 HTTP 服务器和我们的应用连接起来呢?动态网站问世的时候,就出现了 CGI 协议。注意这是一个协议,定义了HTTP 服务器如何通过后端的应用获取动态内容。可以简单的理解成 HTTP 服务器通过CGI 协议调用后端应用吧!WSGI 可以理解成 Python 的 CGI。uWSGI 和 Gunicorn 是这种 WSGI 的一些实现。这样,就出现了上面提到的三层的部署。

但是,为什么我们还需要 Nginx 呢?这些 WSGI 程序本身不是也提供访问吗?

uWSGI 和 Gunicorn 本身就是一个便携的 web 服务器了,Nginx 作为一个经过更长时间验证的 HTTP 服务器来说,它有很多 uWSGI 没有支持的 feature。比如:

  1. 处理静态资源更加优秀,E-Tag 的设置,Gzip 压缩等
  2. 处理网络连接,降低网络负载。例如 reuqest_buffering ,加入部署一个 uWSGI 程序,如果有慢的请求存在,uWSGI 必须等待整个 HTTP 请求发过来之后才开始处理请求。但是如果前置 Nginx,那么 Nginx 会帮你收到整个 HTTP 请求之后才交给 uWSGI 处理,也就是说,uWSGI获得的永远会是完整的 HTTP 请求,不会占用一个线程在等待。
  3. 甚至缓存动态的内容,例如将博客的首页缓存 5 分钟
  4. 作为一个负载均衡的前置,这样每一层的实例数量可以横向扩展
  5. Nginx 本身是作为一个服务存在的,几乎在任何 Linux 版本上安装之后都可以用 initd 启动,就像 MySQL 那样。uWSGI 一般是需要自己将其配置成服务的。(虽然前置了 Nginx 依然是需要配置 uWSGI)
  6. ……

此外,这样分开的好处还是得,到达 uWSGI 和 Gunicorn 的请求的情况变得简单了很多,Nginx 处理了一层,将过滤和处理之后的请求交给 uWSGI 或 Gunicorn。这使得这些 WSGI 程序的实现简单了一些,简化了开发的工作。专业的事情交给专业的人去做。

当然,并不是所有的项目都需要这么复杂的部署,有一个可选的是将 WSGI 程序嫁接到 HTTP 服务器上,比如 Apache httpd + mod_wsgi, Nginx + mod_uwsgi 等。

Nginx状态统计模块

前面简单介绍了Nginx的手动编译安装过程,详细过程请参见Nginx服务搭建;
而Nginx内置了状态统计模块,用来反馈当前的web访问情况,那么该如何开启Nginx内置状态统计模块呢?且我们该如何通过客户端进入状态统计页面?

编译安装Nginx

cd /opt/nginx-1.6.0/       //这里我将Nginx源码包解压在/opt目录下

 ./configure 
--prefix=/usr/local/nginx 
--user=nginx 
--group=nginx 
--with-http_stub_status_module    //开启stub_status状态统计模块,切记要将状态统计模块编译
make && make install 
/usr/local/nginx/sbin/nginx -V //查看Nginx是否安装状态统计模块成功

修改配置文件

要使用Nginx的状态统计功能,除了编译模块以外,还需要修改Nginx的主配置文件制定访问位置并添加stub_status配置代码。

vim /usr/local/nginx/conf/nginx.conf
server {
        listen       80;
        server_name  localhost;
        charset utf-8;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location ~ /status {     //访问位置/status
        stub_status   on;        //开启状态统计功能
        access_log off;          //关闭此模块的日志
        }                       //在"server"这里插入的这4行

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

       }
    }

重启Nginx服务即可,详细服务启动配置脚本请参见:
Nginx服务搭建。

查看状态统计页面

由于本机采用内网IP形式提供服务,且IP地址为192.168.100.111,故在客户端访问:192.168.100.111/status即可进入状态统计页面。为了试验效果,每次刷新页面即可看到状态统计页面的情况:

未分类

未分类

未分类

Nginx与Apache环境防盗链设置方法

说明:很多人的VPS流量是有限的,而一般情况下我们放在网站上的媒体文件都是可以被别人引用的,我们的文件也就成了别人的免费外链,可想而知流量会消耗的有多快,这时候设置一下防盗链还是很有必要的。

根据我们搭建的系统环境不同,我们在Nginx和Apache中设置防盗链的方法也是不同的。

Nginx防盗链方法

location ~ .*.(gif|jpg|jpeg|png|bmp|swf|mp3|wav|zip|rar)$ {
    valid_referers none blocked xirik.cn *.xirik.cn;
    if ($invalid_referer){
        return 403;
    }
    expires 30d;
}

在网站所在的配置文件*.conf中添加以上代码,添加后重启nginx就可以生效,网址记得替换成自己的。

Apache防盗链方法

首先我们需要保证开启了Apache的伪静态模块

然后把下面代码中的网址替换成自己的,复制到网站根目录下的伪静态文件.htaccess中即可生效。

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://xirik.cn/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://xirik.cn$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.xirik.cn/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.xirik.cn$ [NC]
RewriteRule .*.(gif|jpg|jpeg|png|bmp|swf|mp3|wav|zip|rar)$ http://xirik.cn/404.html [R,NC]