WEB环境部署

一、环境搭建

1、测试环境部署

2、预发布系统

3、线上服务器部署架构图

# WEB环境部署与上线流程
1.环境搭建
    1.部署规范
        服务器部署规范
        软件部署规范
        测试
        上线
    2.服务器环境搭建
        Nginx
            Nginx管理
                Nginx介绍
                Nginx安装,启动
                Nginx相关目录及配置文件详解
                Nginx默认网站
                    访问控制
                    日志管理
                    防盗链
                Nginx虚拟主机
                反向代理
                URL重写
                Nginx下载限速        
            Nginx优化
                长连接
                压缩
                客户端缓存
                并发数
            Nginx负载均衡
                集群介绍
                使用Nginx分发器构建一个web集群
                Nginx分发算法
                    轮询
                    基于权重的轮询
                    基于开发语言
                    基于浏览器
                    基于源IP
                构建高可用Nginx集群
                RS故障检测机制    
            Nginx缓存
        Nginx+uwsgi+python+mysql+django
            python
            mysql的安装管理
            python业务集成部署,发布一个python开发的web
    3.业务环境快速升级部署
        saltstack
            saltstack介绍
            saltstack自动化部署
            业务环境更新案例
2.代码管理
    1.持续集成
        持续集成介绍
        认识devops
    2.持续交付-源码管理
        Git
            Git介绍
            Git安装与配置
            Git仓库初始化
            Git基础命令
            Git分支
            Git标签
        Gitlab
            Gitlab介绍
            Gitlab安装
            Gitlab服务于系统设置
            Gitlab仓库管理
            Gitlab备份与恢复
        GitHub
            GitHub的使用
    3.持续部署
        Jenkins介绍
        Jenkins安装与初始化
        Jenkins目录介绍
        Jenkins创建freestyle-job
        Jenkins获取Gitlab源码
        Jenkins部署HTML网站
        Jenkins部署脚本编写
        Jenkins配置Gitlab自动触发构建
        Jenkins配置Jenkins返回构建状态到Gitlab
        maven配置
        Jenkins创建maven job
        Jenkins Pipeline 介绍
        Jenkins Pipeline 示例


# 服务器逻辑
1.服务器选择
    物理服务器
        CPU
            核心数
            主频
        Memory
            容量
            频率
        Storage
            本地存储
                机械磁盘
                    容量
                    转速
                    缓存大小
                固态磁盘
                磁盘阵列    
            外挂存储
                移动硬盘
                OSS
        NIC
            网卡数量
            网卡速率            
    云服务器(同上)
2.操作系统
    系统选型
        厂商选择
            Redhad
        系统版本
            CENTOS
            RHEL
    系统安装
        初始化系统安装包
        初始化系统启动服务
    优化方案
        内核优化
            TCP/IP优化
            IO优化
            内存,CPU优化
            文件系统优化
        安全部署
            私有服务访问控制
                端口
                源地址
            防火墙
                拒绝所有允许个别
                允许所有拒绝个别
            selinux
                文件服务器                            
3.部署逻辑
    业务环境
        内侧服务器
            内侧
        预发布服务器
            公测
        线上业务服务器
            上线
    特点:业务环境一模一样
    功能:测试代码
    服务器部署架构图        



# 业务环境部署逻辑
1.服务器部署架构
    分发层部署
    前端系统
    后端系统
    数据库服务器部署
    缓存系统
    代码分发系统
    分布式存储系统
2.软件部署文档
    软件
        版本号
        获取方式
    软件安装步骤
    软件相关目录说明
    配置文件配置说明
    软件运行
    环境测试    
3.日常维护文档    


#测试
1.开发上传代码到源码系统
    svn
    git
2.上线-测试服务器(内侧)
    测试准备
        功能需求文档
        原型图
        效果图
        测试设备
    测试目的
        代码测试
        构建程序
        代码审核
        功能验证
    测试周期
    测试计划
    测试用例
    测试
        APP
        机器人
        人机
    记录提交测试BUG
    验证关闭bug
    测试报告
3.预发布测试(公测)
    预发布测试
        用户体验测试
        功能验证
        压力测试
    测试周期
    测试用例
    打包验证完毕后的最终代码
    测试报告                        


#上线
产品需求确认
产品研发确认
产品测试确认
上线流程文档
跟踪统计用户反馈情况



#上线流程
CI
1)开发代码

2)审核代码
    主干
    分支

3)Git本地合并分支 

4)本机环境测试代码

5)开发上线代码到GitHub

CD
一测   开发+测试


二测   测试+加内测用户     运维负责部署
	  测试提交测试报告  
	  主管确认签字   


上线   运维负责    
	  各部门主管在上线申请签字 
      运维负责上线




WEB环境部署与上线流程

二、Nginx

1、Nginx介绍与安装

##Nginx介绍与安装
Nginx(“engine x”)是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理理服务器。
• 轻量量级的web服务器
• 延伸版本tengine(淘宝)、openresrt(章亦春)等
• http://nginx.org 官网
• http://www.nginx.cn/doc/index.html 中文文档

## 源码安装三部曲
    配置--编译--安装
    • 配置 configure
        --prefix=path 安装路径
        --help 配置参数
    • 编译
        make
    • 安装
        make install

## 1、Nginx安装
    1.1)获得软件
        wget http://nginx.org/download/nginx-1.15.5.tar.gz -P /usr/src
    1.2)安装前准备
        cd /usr/src
        tar xf nginx-1.15.5.tar.gz
        cd nginx-1.15.5
        yum -y install gcc pcre-devel zlib zlib-devel
    1.3)配置
        1)检查环境 是否 满足安装条件 依赖解决
        2)指定安装方式 配置文件 命令文件 各种文件放哪里 开启模块功能【内置模块 三方模块】
        3)指定软件安装在那里
        ./configure --prefix=/usr/local/nginx
    1.4)编译 使用gcc将源码生成可执行程序
        make -j4
    1.5)安装
        make install
2、相关目录
    nginx path prefix: "/usr/local/nginx"
    nginx binary file: "/usr/local/nginx/sbin/nginx"
    nginx modules path: "/usr/local/nginx/modules"
    nginx configuration prefix: "/usr/local/nginx/conf"
    nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
    nginx pid file: "/usr/local/nginx/logs/nginx.pid"
    nginx error log file: "/usr/local/nginx/logs/error.log"
    nginx http access log file: "/usr/local/nginx/logs/access.log"
3、Nginx启动
    /usr/local/nginx/sbin/nginx
4、验证
    netstat –ntpl
    lsof -i :80
    du -h /usr/src/nginx-1.15.5.tar.gz  #查看包大小
5、浏览器测试
    elinks 文本界面浏览器
    elinks http://192.168.10.42  --dump  

## 查看命令的安装包
yum search killall
yum search elinks
yum search curl
yum search lynx

rpm -qf `which htpasswd`

##Nginx配置文件
• /usr/local/nginx/conf/nginx.conf
Nginx介绍与安装

2、Nginx配置文件

#启动子进程程序默认用户
#user  nobody;
#一个主进程和多个工作进程。工作进程是单进程的,且不需要特殊授权即可运行;这里定义的是工作进程数量
worker_processes  1;

#全局错误日志的位置及日志格式
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    #每个工作进程最大的并发数
    worker_connections  1024;
}


#http服务器设置
http {
    #设定mime类型,类型由mime.type文件定义
    include       mime.types;
    
    #
    default_type  application/octet-stream;

    #日志格式
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
    #$remote_user:用来记录客户端用户名称;
    #$time_local: 用来记录访问时间与时区;
    #$request: 用来记录请求的url与http协议;
    #$status: 用来记录请求状态;成功是200,
    #$body_bytes_sent :记录发送给客户端文件主体内容大小;
    #$http_referer:用来记录从那个页面链接访问过来的;
    #$http_user_agent:记录客户浏览器的相关信息;

    #全局访问日志路径 
    #access_log  logs/access.log  main;
    #sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
    sendfile        on;
    
    #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
    #tcp_nopush     on;

    #长连接超时时间
    #keepalive_timeout  0;
    keepalive_timeout  65;

    #开启压缩
    #gzip  on;

    #配置虚拟主机
    server {
        #虚拟主机使用的端口
        listen       80;
        #虚拟主机域名
        server_name  localhost;

        #虚拟主机支持的字符集
        #charset koi8-r;

        #虚拟主机的访问日志路径
        #access_log  logs/host.access.log  main;

        #定义web根路径
        location / {
            #根目录路径
            root   html;
            #索引页
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #

        #根据错误码 返回对应的页面
        error_page   500 502 503 504  /50x.html;

        #定义页面路径
        location = /50x.html {
            root   html;
        }

        #定义反向代理服务器 数据服务器是lamp模型
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}


        #定义PHP为本机服务的模型  
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #拒绝apache DR目录及子目录下的.htaccess文件访问
        #location ~ /.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    #https的配置方案
    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}
/usr/local/nginx/conf/nginx.conf

3、Nginx默认网站

##Nginx默认网站
01.Nginx 默认网站
当Nginx配置文件中有且只有一个Server的时候,该Server就被Nginx认为是默认网站,所有发给Nginx服务器80端口的数据都会默认给该Server.
    server {
        listen 80;
        server_name localhost;
        location / {
        root html;
        index index.html index.htm;
        }
        error_page 500 502. 503. 504. /50x.html;
        location = /50x.html {
        root html;
        }
    }
02.Nginx目录访问控制
    location /a {
        allow 192.168.1.0/24;
        deny all;
        #return 404.;
        return http://www.jd.com;
    }

03.Nginx目录验证
    • auth_basic
    语法: auth_basic string | off;
    默认值: auth_basic off;
    • auth_basic_user_file file;

    location /b {
    auth_basic "登陆验证";
    auth_basic_user_file /etc/nginx/htpasswd;
    }

04.Nginx日志管理
    Nginx访问日志主要有两个参数控制
    1) log_format #用来定义记录日志的格式(可以定义多种日志格式,取不不同名字即可)
    log_format log_name string
    2) access_log #用来指定日至文件的路径及使用的何种日志格式记录日志
    access_log logs/access.log main;

    log_format格式变量:
        $remote_addr #记录访问网站的客户端地址
        $remote_user #远程客户端用户名
        $time_local #记录访问时间与时区
        $request #用户的http请求起始⾏行行信息
        $status #http状态码,记录请求返回的状态码,例例如:200301.、404.等
        $body_bytes_sent #服务器发送给客户端的响应body字节数
        $http_referer #记录此次请求是从哪个连接访问过来的,可以根据该参数进⾏行行防盗链设置。
        $http_user_agent #记录客户端访问信息,例例如:浏览器、⼿手机客户端等
        $http_x_forwarded_for #当前端有代理理服务器时,设置web节点记录客户端地址的配置,此参数⽣生效的前提是代理理服务器也要进⾏行行相关的x_forwarded_for设置

    自定义日志格式为json:
        log_format main_json '{"@timestamp":"$time_local",'
        '"client_ip": "$remote_addr",'
        '"request": "$request",'
        '"status": "$status",'
        '"bytes": "$body_bytes_sent",'
        '"x_forwarded": "$http_x_forwarded_for",'
        '"referer": "$http_referer"'
        '}’;
        access_log logs/access_json.log main_json;

05.Nginx防盗链  请求头中的referer
    location /images/ {
    alias /data/images/;
    valid_referers none blocked *.ayitula.com;
    if ($invalid_referer) {
    return 403;
    }
    }

06.日志截断
    mv access.log access.log.0
    killall -USR1 `cat master.nginx.pid`
    sleep 1
    gzip access.log.0


## 生成账号密码
yum -y install httpd-tools
htpasswd -m  /etc/nginx/htpasswd bubu

openssl

## 修改配置文件后给nginx发信号
killall -s HUP nginx  

##检测配置文件是否有问题
../sbin/nginx -g ../conf/nginx.conf
Nginx默认网站
user  www;
worker_processes  4;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #
    
   log_format baism_01 ‘[$time_local] $remote_addr "$request" $status’;

#04.Nginx日志管理 自定义日志格式为json
   log_format main_json '{"@timestamp":"$time_local",'
'"client_ip": "$remote_addr",'
'"request": "$request",'
'"status": "$status",'
'"bytes": "$body_bytes_sent",'
'"x_forwarded": "$http_x_forwarded_for",'
'"referer": "$http_referer",'
'}';


    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

#01.Nginx 默认网站
server {
    listen       80;
    server_name  localhost;
    charset utf-8;
    access_log  logs/host.access.log  main_json;

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

    # 02.Nginx目录访问控制 只允许本机访问a目录  其他机器拒绝访问
    location /a {
        allow 127.0.0.1;
        allow 192.168.10.42;
        deny all;
        
        #return 502;
        return http://www.jd.com;
    }    

    #03.Nginx目录验证:  任何人都可以访问,但是需要凭用户密码才能访问   
    location /b {
    auth_basic "登陆验证";
    auth_basic_user_file /etc/nginx/htpasswd;

    }
    #05.Nginx防盗链  请求头中的referer
    location /c {
     location ~* .(png|gif|bmp)$ {
     valid_referers none blocked *.ayitula.com;
     if ($invalid_referer) {
        return 403;
      }
     }
    }
    
    #error_page  404              /404.html;
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
    
}
nginx.conf

4、Nginx虚拟主机

##Nginx虚拟主机
01.虚拟主机介绍
    一个web服务器软件默认情况下只能发布一个web,因为一个web分享出去需要三个条件(IP、Port、Domain name)
    一个web服务器软件如何发布多个web呢?
    虚拟主机:就是把一台物理服务器划分成多个“虚拟”的服务器,每一个虚拟主机都可以有独立的域名和独立的目录

    同时发布两个网站:
    DocumentRoot /usr/local/nginx/html/web1
    DocumentRoot /usr/local/nginx/html/web2

02.基于IP的虚拟主机
    实现条件
        1)两个IP
        2)DocumentRoot存在
        3)索引页 index.html

        #每个网站都需要一个IP
        #缺点 需要多个IP 如果是公网IP 每个IP都需要付费
        server {
        listen 192.168.10.42:80;
        location / {
        root html/web1;
        index index.html index.htm index.php;
        }
        }
        server {
        listen 192.168.10.52:80;
        location / {
        root html/web2;
        index index.html index.htm;
        }
        }


03.基于端口的虚拟主机
    #只需要一个IP
    #缺点 端口你是无法告诉公网用户 无法适用于公网客户 适合内部用户
    基于端口
    server {
    listen 80;
    #server_name www.abc.com;
    location / {
    root html/web1;
    index index.html index.htm index.php;
    }
    }
    server {
    listen 8080;
    #server_name www.abc.com;
    location / {
    root html/web2;
    index index.html index.htm;
    }
    }


04.基于域名的虚拟主机
    一个网站必然有一个域名
    server {
    listen 80;
    server_name www.abc.com;
    location / {
    root html/web1;
    index index.html index.htm index.php;
    }
    }
    server {
    listen 80;
    server_name www.cbd.com;
    location / {
    root html/web2;
    index index.html index.htm;
    }
    }
Nginx虚拟主机

5、Nginx反向代理

##Nginx反向代理
01.反向代理介绍
    代理服务器,客户机在发送请求时,不不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬盘中,再发送给客户机。
02.应用场景
    • 堡垒机场景
    • 内网服务器发布场景
    • 缓存场景
03.反向代理原理
    • 1) 客户端通过浏览器 发起请求 代理服务器
    • 2)代理服务器 接受请求
    • 3) 代理服务器 发起请求 业务服务器
    • 4)业务服务器 接受请求
    • 5)业务服务器 处理请求
    • 6) 业务服务器 响应请求 代理服务器
    • 7)代理服务器 响应请求 客户端
    • 8)客户端通过浏览器渲染请求并展示给用户
04.反向代理实现
    location / {
    index index.php index.html index.htm; #定义首页索引文件的名称
    proxy_pass http://mysvr ;#请求转向mysvr 定义的服务器列列表
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 10m; #允许客户端请求的最大单文件字节数
    client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
    proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
    proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
    proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
    proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
    proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
    proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
    proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
    }


client mac http://192.168.10.42
反代 Nginx 42
业务机器 book.ayitula.com http://118.190.209.153:4000/
Nginx反向代理
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
        proxy_pass http://118.190.209.153:4000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        client_max_body_size 10m;
        client_body_buffer_size 128k;
        proxy_connect_timeout 90;
            proxy_send_timeout 90;
            proxy_read_timeout 90;
            proxy_buffer_size 4k;
            proxy_buffers 4 32k;
            proxy_busy_buffers_size 64k;
            proxy_temp_file_write_size 64k;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}
nginx.conf

6、Nginx限速

##Nginx限速
01.限速介绍
• 限流(rate limiting)是NGINX众多特性中最有用的,也是经常容易被误解和错误配置的,特性之一。
• 限速该特性可以限制某个用户在一个给定时间段内能够产生的HTTP请求数。请求可以简单到就是一个对于主页的GET请求或者一个登陆表格的POST请求。
• 限速也可以用于安全目的上,比如暴暴力力密码破解攻击。通过限制进来的请求速率,并且(结合日志)标记出目标URLs来帮助防范DDoS攻击。一般地说,限流是用在保护上游应用服务器不不被在同一时刻的大量量用户请求湮没。
02.应用场景
. DDOS防护
. 下载场景保护IO
03.限速原理
算法思想是:
    水(请求)从上方倒入水桶,从水桶下方流出(被处理);
    来不不及流出的水存在水桶中(缓冲),以固定速率流出;
    水桶满后水溢出(丢弃)。
    这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
    相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。
04.限速实现    
    Nginx官方版本限制IP的连接和并发分别有两个模块:
    limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法"leaky bucket"。
    limit_req_conn 用来限制同一时间连接数,即并发限制。

limit_req_zone 参数配置
    Syntax: limit_req zone=name [burst=number] [nodelay];
    Default: —
    Context: http, server, location
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;


限速案例例一!
    基于IP对下载速率做限制 限制每秒处理1次请求,对突发超过5个以后的请求放入缓存区
    http {
    limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s;
    server {
    location /search/ {
    limit_req zone=baism burst=5 nodelay;
    }
    }
    limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s;
    第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量量,是限制同一客户端ip地址。
    第二个参数:zone=baism:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。
    第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里里限制的是每秒1次,还可以有比如30r/m的。
    limit_req zone=baism burst=5 nodelay;
    第一个参数:zone=baism 设置使用哪个配置区域来做限制,与上面limit_req_zone 里里的name对应。
    第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量量请求(爆发)过来时,超过了了访问频次限制的请
    求可以先放到这个缓冲区内。
    第三个参数:nodelay,如果设置,超过访问频次⽽而且缓冲区也满了了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。


限速案例例二!
    基于IP做连接限制 限制同一IP并发为1 下载速度为100K
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
    listen 80;
    server_name localhost;
    location / {
    root html;
    index index.html index.htm;
    }
    location /abc {
    limit_conn addr 1;
    limit_rate 100k;
    }
    }

综合案例例!
    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    基于IP做连接限制 限制同一IP并发为1 下载速度为100K
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    基于IP对下载速率做限制 限制每秒处理1次请求,对突发超过5个以后的请求放入缓存区
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
    listen 80;
    server_name localhost;
    location / {
    root html;
    index index.html index.htm;
    }
    location /abc {
    limit_req zone=one burst=5 nodelay;
    limit_conn addr 1;
    limit_rate 100k;
    }
    }
Nginx限速
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

     location /abc {
            limit_req zone=baism burst=5 nodelay;
        limit_conn addr 1;
        limit_rate 100k;
        limit_rate_after 250m;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   html;
        #}

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}
nginx.conf

7、NginxURL重写

##NginxURL重写
01.URL 重写介绍
    • rewrite模块(ngx_http_rewrite_module)
    • Rewrite功功能是Nginx服务器提供的一个重要功能。几乎是所有的web产品必备技能,用于实现URL重写。URL重写是非常有用的功能,比如它可以在我们在改变网站结构后,不不需要客户端修改原来的书签,也不不需要其他网站修改对我们网站的友情链接,还可以在一定程度上提高网站的安全性,能够让我们的网站显得更专业。
    • Nginx服务器Rewrite功能的实现是依赖于PCRE(Perl Compatible Regular Expression。Perl兼容的正则表达式)的⽀支持,所以在编译安装Ngin之前,需要安装PCRE库。
02.应用场景
    • 域名变更 (京东)
    • 用户跳转 (从某个连接跳到另一个连接)
    • 伪静态场景 (便于CDN缓存动态页面数据)
03.URL 重写原理
    URL rewrite实现
    1) set设置变量量
    2) if负责语句句中的判断
    3) return返回返回值或URL
    4) break终止后续的rewrite规则
    5) rewrite重定向URL

    Rewrite规则相关指令 !
    set指令 自定义变量量
    Syntax:
    set $variable value;
    Default:—
    Context:
    server, location, if
    • 将http://www.ayitula.com 重写为 http://www.ayitula.com/baism
    location / {
    set $name baism;
    rewrite ^(.*)$ http://www.ayitula.com/$name;
    }


    if 指令 负责判断
    Syntax:
    if (condition) { ... }
    Default:—
    Context:
    server, location
    location / {
    root html;
    index index.html index.htm;
    if ($http_user_agent ~* 'Chrome') {
    return 403;
    #return http://www.jd.com;
    }
    }

    #模糊匹配 ~匹配 !~不匹配 ~* 不区分大小写的匹配
    #精确匹配 = !=

    return 指令 定义返回数据
    Syntax:
    return code [text];
    return code URL;
    return URL;
    Default:—
    Context:
    server, location, if
    location / {
    root html;
    index index.html index.htm;
    if ($http_user_agent ~* 'Chrome') {
    return 403;
    #return http://www.jd.com;
    }
    }

    break 指令 停止执⾏行行当前虚拟主机的后续rewrite指令集
    Syntax: break;
    Default:—
    Context:server, location, if
    location / {
    root html;
    index index.html index.htm;
    if ($http_user_agent ~* 'Chrome') {
    break;
    return 403;
    }
    }


    URL rewrite 语法!
    rewrite <regex> <replacement> [flag];
    关键字 正则 替代内容 flag标记
    flag:
    last #本条规则匹配完成后,继续向下匹配新的location URI规则
    break #本条规则匹配完成即终止,不不再匹配后面的任何规则
    redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
    permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

04.URL 重写实现
    URL rewrite 案例例!
    域名跳转
    www.ayitula.com 重写为 www.jd.com
    server {
    listen 80;
    server_name www.ayitula.com;
    location / {
    rewrite ^/$ http://www.jd.com permanent ;
    }
    }
    注意:
    重定向就是将网页自动转向重定向
    301永久性重定向:新网址完全继承旧网址,旧网址的排名等完全清零
    301重定向是网页更改地址后对搜索引擎友好的最好方法,只要不不是暂时搬移的情况,都建议使用301来做转址。
    302临时性重定向:对旧网址没有影响,但新网址不不会有排名
    搜索引擎会抓取新的内容⽽而保留留旧的网址

    break
    本条规则匹配完成即终止,不不再匹配后面的任何规则
    类似临时重定向,返回客户端302

    根据用户浏览器重写访问目录
    如果是chrome浏览器 就将 http://192.168.10.42/$URI 重写为 http://192.168.10.42/chrome/$URI


    实现 步骤
    1)URL重写
    2)请求转给本机location

    location / {
    .....
    if ($http_user_agent ~* 'chrome'){
    rewrite ^(.*)$ /chrome/$1 last;
    }
    location /chrome {
    root html ;
    index index.html;
    }
    }
    #^ 以什什么开头 ^a
    #$ 以什什么结尾 c$
    #. 除了了回⻋车以外的任意一个字符
    #* 前面的字符可以出现多次或者不不出现
    # 更多内容看正则表达式 re

url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变last 一般出现在server或if中
数据包走向 client-->nginx nginx告诉客户端让服务器的新地址(真实服务器),客户端收到后再去找服务器 client--->server
NginxURL重写
user  root;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  www.ayitula.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

        #  set 
        #set $name baism;
        #rewrite ^(.*)$ http://www.ayitula.com/$name; 

        #if
    #模糊匹配   ~匹配  !~不匹配    ~* 不区分大小写的匹配
    #精确匹配  =  !=         

       
          #rerurn  and break 
           # if ($http_user_agent ~* 'chrome') {
           #         
       #        break;
           #            return 403;
                    #return http://www.jd.com;
    #}
    #
    #

    #rewrite
    
    #rewrite ^/$ http://www.jd.com permanent;
    #rewrite ^/$ http://www.jd.com redirect;
    #rewrite ^/$ http://www.jd.com break;
    #
    #

       if ($http_user_agent ~* 'chrome'){
            rewrite ^(.*)$ /chrome/$1 last;
           }
        
       #http://192.168.10.42/chrome/$uri
        location /chrome {
      root html;
          index index.html;
        }



}

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}
nginx.conf

8、Nginx优化

##Nginx优化
01.优化思路
    标准情况下,软件默认的参数都是对安装软件的硬件标准来设置的,目前我们服务器的硬件资源远远大于要求的标准,所以为了了让服务器性能更加出众,充分利利用服务器的硬件资源,我们一般需要优化APP的并发数来提升服务器的性能。
02.工作进程优化(并发优化)
    Nginx是主进程+工作进程模型:
        worker_processes 4;  # 工作进程数量量 按CPU的总核心调整
        worker_cpu_affinity 0001 0010 0100 1000; #CPU的亲和力力
        events {
        worker_connections 1024;  # 一个工作进程的并发数
        }
03.长连接
    http协议属于TCP协议
    优化目标:减少三次握手和四次断开的次数
    keepalive_timeout 0; 0代表关闭
    keepalive_timeout 5; 长连接时间
    keepalive_requests 8192; 每个长连接接受最大请求数
04.压缩优化
    gzip on; (启用 gzip 压缩功能)
    gzip_proxied any; (nginx 做前端代理时启用该选项,表示无论后端服务器的headers头返回什什么信息,都无条件启用压缩)
    gzip_min_length 1k; (最小压缩的页面,如果页面过于小,可能会越压越大,这里规定大于1K的页面才启用压缩)
    gzip_buffers 4 8k; (设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流 按照原始数据大小以8K为单位申请4倍内存空间)
    gzip_comp_level 3; (压缩级别,1压缩比最小处理速度最快,9压缩比最大但处理最慢,同时也最消耗CPU,一般设置为3就可以了了)
    gzip_types text/plain text/css application/x-javascript application/javascript application/xml; (什什么类型的页面或文档启用压缩)
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;

    
    gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,建议开启
    gzip_disable "MSIE [1-6]."; # 禁用IE 6 gzip
    gzip_buffers 32 4k;  # 设置压缩所需要的缓冲区大小
    gzip_http_version 1.0; # 设置gzip压缩针对的HTTP协议版本
    find /usr/share/ -type f -size +1M #找大文件

05.客户端缓存优化
    语法: expires [time|epoch|max|off]
    默认值: expires off
    作用域: http, server, location
    location ~.*.(js|css)?$
    {
    expires 1h;
    }


    location ~* .(png|gif)$ {
    expires 1h;
    }

测试 浏览器刷新 以Chrome为例 ctrl+f5 清空本地缓存从服务器拿数据
F5或者 点击 浏览器的刷新图标 优先从本地找 然后 去找服务器核对信息
是否一致 一致 返回304 从本地那数据
回车 从本地缓存拿数据
视频中刷新方式是点击图标,所以会拿不到数据 因为去服务器核实数据的时候已经没有数据了
Nginx优化
#user  nobody;
worker_processes  4;
worker_cpu_affinity   0001 0010 0100 1000;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  10240;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

   keepalive_timeout  5;
   keepalive_requests 8192;
    #keepalive_timeout  65;


gzip  on;
gzip_proxied any;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_comp_level 6;
gzip_types text/plain text/css application/x-javascript application/javascript application/xml;



    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

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

        location ~*  .(png|gif)$ {
              expires 1h;
         }


        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}
nginx.conf

9、Nginx集群

# Nginx集群
01. 集群介绍
    完成一次请求的步骤
    1)用户发起请求
    2)服务器接受请求
    3)服务器处理请求(压力最大)
    4)服务器响应请求
    缺点:单点故障
    单台服务器资源有限
    单台服务器处理耗时长

单点故障解决方案!1) 部署一台备份服务器,宕机直接切换
    • 2) 部署多台服务器,根据DNS的轮询解析机制去实现用户分发
    问题:
    1方案:服务器利利用率低,成本高,切换不不及时,服务器压力依然大
    2方案: 优势是用户处理速度得到了了提升,但是当其中一台故障,就会有一部分用户访问不不了了网站

    并行行处理解决方案!1) 上述的DNS轮询解析方案
    • 2)多机阵列列---集群模式


集群!
    • 将多个物理机器组成一个逻辑计算机,实现负载均衡和容错
    • 计算机集群简称集群,是一种计算机系统, 它通过一组松散集成的计算机软件或硬件连接起来高度紧密地协作完成计算
    工作。在某种意义上,他们可以被看作是一台计算机。 (百度解释)
    • 组成要素
    1)VIP:
        一个IP地址
    2)分发器:
        nginx
    3)数据服务器:
        Web服务器

02. Nginx集群原理
    • 在该集群中Nginx扮演的角色是: 分发器
    • 任务:接受请求、分发请求、响应请求
    • 功能模块:
    1)ngx_http_upstream_module 基于应用层分发模块
    2)ngx_stream_core_module 基于传输层分发模块 (1.9开始提供)


• Nginx集群其实是:虚拟主机+反向代理+upstream分发模块组成的
    虚拟主机:接受和响应请求
    反向代理: 带用户去数据服务器拿数据
    upstream: 告诉Nginx去哪个数据服务器拿数据
• 数据走向
    1)虚拟主机接受用户请求
    2)虚拟主机去找反向代理
    3)反向代理让去找upstream
    4)upstream 告诉 一个数据服务器IP
    5)Nginx去找数据服务器 并发起用户的请求
    6)数据服务器接受请求并处理请求
    7)数据服务器响应请求给Nginx
    8)Nginx响应请求给用户


03. 实现基于Nginx分发器的web集群
配置一个web集群!
    1) Nginx 安装
    2) 配置业务服务器页面
    3) 配置Nginx分发器
    4) 测试分发


配置web业务机器!
    #web02
    [root@web02 ~]# sh nginx_install
    [root@web02 ~]# echo web02 > /usr/local/nginx/html/index.html
    [root@web02 ~]# yum -y install elinks &>/dev/null
    [root@web02 ~]# /usr/local/nginx/sbin/nginx
    [root@web02 ~]# elinks http://localhost -dump
    web02

配置分发器!
    Syntax:
    upstream name { ... }
    Default:
    —
    Context:
    http
    #upstream 模块
    upstream web {
    server 192.168.10.42;
    server 192.168.10.43;
    }
    server {
    listen 80;
    server_name localhost;
    location / {
    proxy_pass http://web;
    }
    error_page 500 502. 503. 504. /50x.html;
    location = /50x.html {
    root html;
    }
    }
    }

04.测试
    集群分发测试!
    [root@web02. ~]# elinks http://192.168.10.40 -dump
    web01
    [root@web02. ~]# elinks http://192.168.10.40 -dump
    web02
    [root@web02. ~]# elinks http://192.168.10.40 -dump
    web01
    [root@web02. ~]# elinks http://192.168.10.40 -dump
    web02
集群
# 实现一个基本Nginx集群
1.web业务服务器设置
    #web01
    [root@web01 ~]# sh nginx_install
    [root@web01 ~]# echo web01 > /usr/local/nginx/html/index.html
    [root@web01 ~]# /usr/local/nginx/sbin/nginx
    [root@web01 ~]# elinks http://localhost -dump
    web01
    #web02
    [root@web02 ~]# sh nginx_install
    [root@web02 ~]# echo web02 > /usr/local/nginx/html/index.html
    [root@web02 ~]# yum -y install elinks &>/dev/null
    [root@web02 ~]# /usr/local/nginx/sbin/nginx
    [root@web02 ~]# elinks http://localhost -dump
    web02
2.nginx 分发器
    [root@Master ~]# sh nginx_install
    [root@Master ~]# sed -i '/#/d' /usr/local/nginx/conf/nginx.conf
    [root@Master ~]# sed -i '/^$/d' /usr/local/nginx/conf/nginx.conf
    [root@Master ~]# cat /usr/local/nginx/conf/nginx.conf
    worker_processes 1;
    events {
    worker_connections 1024;
    }
    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    #upstream 模块
    upstream web {
    server 192.168.10.42;
    server 192.168.10.43;
    }
    server {
    listen 80;
    server_name localhost;
    location / {
    proxy_pass http://web;
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }
    }
    }
    [root@Master ~]# /usr/local/nginx/sbin/nginx

3.测试
    [root@web02 ~]# elinks http://192.168.10.40 -dump
    web01
    [root@web02 ~]# elinks http://192.168.10.40 -dump
    web02
    [root@web02 ~]# elinks http://192.168.10.40 -dump
    web01
    [root@web02 ~]# elinks http://192.168.10.40 -dump
    web02
实现一个基本Nginx集群

10、Nginx集群算法

# Nginx集群算法
01.分发算法介绍
    • 分发算法
    如何将用户请求按照一定的规律律分发给业务服务器
    • 思考
    假如你有1000块钱,你怎么分配给身边的3个好朋友呢?
02. 常用分发算法
    Nginx集群默认算法!
    upstream module
    nginx的upstream目前支持4种方式的分配
    1、轮询(默认)
    每个请求按时间顺序逐一分配到不不同的后端服务器,如果后端服务器down掉,能自动剔除。
    2、weight
    指定轮询几率,weight和访问比率成正比,用于后端服务器性能不不均的情况。
    3、ip_hash
    每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
    4、fair(第三方)
    按后端服务器的响应时间来分配请求,响应时间短的优先分配。
    5、url_hash(第三方)
    按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。


Nginx业务服务器状态!
    每个设备的状态设置为:
    1.down 表示单前的server暂时不不参与负载
    2.weight 默认为1.weight越大,负载的权重就越大。
    3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
    4.fail_timeout: 失败超时时间,在连接Server时,如果在超时时间之内超过max_fails指定的失败次数,会认为在fail_timeout时间内Server不不可用。默认为10s。
    5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。


基于请求头的分发!
    1)基于host分发
    2)基于开发语言分发
    3)基于浏览器的分发
    4) 基于源ip

03.算法实现测试
    nginx 分发器设置
    默认采用RR算法,如果想采用其他算法,如ip_hash类似于LVS sh,例子

ip_hash!
    upstream web {
    ip_hash;
    server 192.168.10.42;
    server 192.168.10.43;
    }
    server {
    listen 80;
    server_name localhost;
    location / {
    proxy_pass http://web;
    }
    }
    ip_hash算法能够保证来自同样源地址的请求,都分发到同一台主机

轮询分发!
    upstream web {
    server 192.168.10.42;
    server 192.168.10.43;
    }
    server {
    listen 80;
    server_name localhost;
    location / {
    proxy_pass http://web;
    }
    }    

基于权重的分发!
    upstream web {
    server 192.168.10.42 weight=1;
    server 192.168.10.43 weight=2;
    }
    server {
    listen 80;
    server_name localhost;
    location / {
    proxy_pass http://web;
    }
    }


基于http协议主机头host分发!
    http {
        upstream web1 {
        server 192.168.10.42;
        }
        upstream web2 {
        server 192.168.10.43;
        }
        server {
        listen 80;
        server_name www.web1.com;
        location / {
        proxy_pass http://web1;
        }
        }
        server {
        listen 80;
        server_name www.web2.com;
        location / {
        proxy_pass http://web2;
        }
        }
    }

基于开发语言分发!
要求各位完成php,html分发的基础上实现负载均衡
    http {
    upstream php {
    server 192.168.10.42;
    }
    upstream html {
    server 192.168.10.43;
    }
    server {
    location ~* .php$ {
    proxy_pass http://php;
    }
    }
    location ~* .html$ {
    proxy_pass http://html;
    }
    }

基于浏览器分发!
    upstream elinks { server 192.168.10.42; }
    upstream chrome { server 192.168.10.43; }
    upstream any { server 192.168.10.42:81; }
    server {
    listen 80;
    server_name www.web1.com;
    location / {
    proxy_pass http://any;
    if ( $http_user_agent ~* Elinks ) {
    proxy_pass http://elinks;
    }
    if ( $http_user_agent ~* chrome ) {
    proxy_pass http://chrome;
    }
    }
    }

基于源ip分发!(类似于ACL DNS)
    编译
    ./configure --with-http_geoip_module
    upstream bj.server {
    server 192.168.10.42;
    }
    upstream sh.server {
    server 192.168.10.43;
    }
    upstream default.server {
    server 192.168.10.42:81;
    }
    geo $geo {
    default default;
    192.168.10.241/32 bj;
    192.168.10.242/32 sh;
    }
    location / {
    proxy_pass http://$geo.server$request_uri;
    }
Nginx集群算法

11、Nginx构建高可用集群

keepalived安装管理
keepalvied!
Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不不需要人工干涉,需要人工做的只是修复故障的服务器。

一个监控+自愈的软件

运行行协议 vrrp
主分发器的KP 会向网络中发组播 宣告自己还活着 224.0.0.18
安装在哪里:分发器上
分发器:Nginx+keepalvied
配置高可用

Keepalived获得!
http://www.keepalived.org/download.html
wget http://www.keepalived.org/software/keepalived-2.0.8.tar.gz


Keepalived 安装!
```bash
#cat keepalived_install.sh
#!/bin/bash
pkg=keepalived-2.0.8.tar.gz
tar xf $pkg
yum -y install kernel-devel
ln -s /usr/src/kernels/3.10.0-862.14.4.el7.x86_64/ /usr/src/linux
cd keepalived-2.0.8/
yum install openssl-* -y
./configure --prefix=/usr/local/keepalived
make
make install
mkdir -pv /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/

# 配置主Nginx分发器keepalived!! master.ayitula.com
#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id NGINX_DEVEL
}
vrrp_script check_nginx {
script "/etc/keepalived/nginx_pid.sh"
interval 2
fall 1
}
vrrp_instance nginx {
state MASTER
interface ens33
mcast_src_ip 192.168.10.40
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_nginx
}
virtual_ipaddress {
192.168.10.213/24
}
}

#chmod 755 /etc/keepalived/nginx_pid.sh

#cat /etc/keepalived/nginx_pid.sh
#!/bin/bash
nginx_kp_check () {
nginxpid=`ps -C nginx --no-header |wc -l`
if [ $nginxpid -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 1
nginxpid=`ps -C nginx --no-header |wc -l`
if [ $nginxpid -eq 0 ];then
systemctl stop keepalived
fi
fi
}
nginx_kp_check
#配置备份Nginx分发器keepalived!! backup.ayitula.com
#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id NGINX_DEVEL
}
vrrp_script check_nginx {
script "/etc/keepalived/nginx_pid.sh"
interval 2
fall 1
}
vrrp_instance nginx {
state BACKUP
interface ens33
mcast_src_ip 192.168.10.41
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_nginx
}
virtual_ipaddress {
192.168.10.213/24
}
}
```

启动keepalived!
    systemctl start keepalived
keepalived安装配置
# Nginx构建高可用集群
01.高可用介绍
    • 分发器宕机怎么办
    • 数据服务器宕机怎么办

02.keepalived安装
    运行行协议 vrrp
    主分发器的KP 会向网络中发组播 宣告自己还活着 224.0.0.18
    安装在哪里:分发器上
    分发器:Nginx+keepalvied
    配置高可用

03.构建高可用集群

部署步骤!
    软件环境部署
    1)分发器 nginx+keepalived
    2)数据服务器 Nginx
    3)配置Nginx分发器
    4)配置数据服务器页面(web01 web02)
    5)配置keepalived.conf (主,备份) (/etc/keepalived/keepalived.conf)
    6)chmod 755 /etc/keepalived/nginx_pid.sh
    7)关联脚本 /etc/keepalived/nginx_pid.sh
    8)测试

04.故障测试
模拟故障!
    数据服务器宕机测试
    分发器宕机测试


一、构建高可用集群
1.web业务服务器设置
    #web01
    [root@web01 ~]# sh nginx_install
    [root@web01 ~]# echo web01 > /usr/local/nginx/html/index.html
    [root@web01 ~]# /usr/local/nginx/sbin/nginx
    [root@web01 ~]# elinks http://localhost -dump
    web01

    #web02
    [root@web02 ~]# sh nginx_install
    [root@web02 ~]# echo web02 > /usr/local/nginx/html/index.html
    [root@web02 ~]# yum -y install elinks &>/dev/null
    [root@web02 ~]# /usr/local/nginx/sbin/nginx
    [root@web02 ~]# elinks http://localhost -dump
    web02


2.配置Nginx集群!
    upstream web {
    server 192.168.10.42 max_fails=2 fail_timeout=3;
    server 192.168.10.43 max_fails=2 fail_timeout=3;
    server {
    listen 80;
    server_name localhost;
    location / {
    proxy_pass http://web;
    }
    }

3.关联脚本 (/etc/keepalived/nginx_pid.sh)
    #chmod 755 /etc/keepalived/nginx_pid.sh
    #cat /etc/keepalived/nginx_pid.sh
    #!/bin/bash
    nginx_kp_check () {
    nginxpid=`ps -C nginx --no-header |wc -l`
    if [ $nginxpid -eq 0 ];then
    /usr/local/nginx/sbin/nginx
    sleep 1
    nginxpid=`ps -C nginx --no-header |wc -l`
    if [ $nginxpid -eq 0 ];then
    systemctl stop keepalived
    fi
    fi
    }

4.配置keepalived! (/etc/keepalived/keepalived.conf)

配置MASTER   keepalived! (/etc/keepalived/keepalived.conf)
    #cat /etc/keepalived/keepalived.conf
    ! Configuration File for keepalived
    global_defs {
    router_id NGINX_DEVEL
    }
    vrrp_script check_nginx {
    script "/etc/keepalived/nginx_pid.sh"
    interval 2
    fall 1
    }
    vrrp_instance nginx {
    state MASTER
    interface ens33
    mcast_src_ip 192.168.10.40
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    track_script {
    check_nginx
    }
    virtual_ipaddress {
    192.168.10.213/24
    }
    }


配置备份(backup) keepalived! (/etc/keepalived/keepalived.conf)
    #cat /etc/keepalived/keepalived.conf
    ! Configuration File for keepalived
    global_defs {
    router_id NGINX_DEVEL
    }
    vrrp_script check_nginx {
    script "/etc/keepalived/nginx_pid.sh"
    interval 2
    fall 1
    }
    vrrp_instance nginx {
    state BACKUP   #######
    interface ens33
    mcast_src_ip 192.168.10.41  #######
    virtual_router_id 51
    priority 90  #######
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    track_script {
    check_nginx
    }
    virtual_ipaddress {
    192.168.10.213/24
    }
    }

启动keepalived!
    systemctl start keepalived

#####
ip add show #查看ip
tcpdump -nn -vvv -i ens33 vrrp #抓包工具查看网卡ens33的情况
#####

#用虚IP测试 
[root@web02 ~]# elinks http://192.168.10.213 -dump
web01
[root@web02 ~]# elinks http://192.168.10.213 -dump
web02
[root@web02 ~]# elinks http://192.168.10.213 -dump
web01
[root@web02 ~]# elinks http://192.168.10.213 -dump
web02
Nginx构建高可用集群

12、Nginx部署python语言的web环境

Cnetos7.5+Nginx+python+Django+uwsgi+mysql

实验部署流程

1) 安装Nginx

2) 安装python

3) 安装mysql

4) 部署发布平台

5) 测试

# mysql安装
Mysql介绍!
    一个关系型数据库,由瑞典的AB公司开发,后来卖给了了oracle公司,目前分为商业版和社区版
    目前有量量大版本 mysql5 和 mysql8
    目前建议大家先使用5.7最新版本即可。官方提供了了RPM和源码两种格式

Mysql安装步骤!  https://dev.mysql.com/downloads/mysql/5.7.html#downloads
    1) 安装依赖包
    2) 升级cmake工具
    3) 升级boost库文件
    4) 安装mysql
    5) 启动测试

cmake 安装!
    1)获得软件 2.8以上
    https://cmake.org/download/
    2)安装软件
    yum -y install ncurses-devel gcc-* bzip2-* bison
    tar xf cmake-3.6.0-rc1.tar
    cd cmake-3.6.0-rc1
    ./configure
    make
    make install
    3)测试
    cmake --version

boost 安装! (库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一)
    1)获得软件
    https://www.boost.org/
    2)安装软件 (解压到指定目录即可)
    tar xf boost_1_59_0.tar.bz2
    mv boost_1_59_0  /usr/local/boost

mysql 安装!
    useradd -s /sbin/nologin -r mysql
    mkdir -pv /usr/local/mysql/data
    tar xf mysql-5.7.24.tar.gz
    cd mysql-5.7.24

    cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/
    usr/local/mysql/data/ -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock
    -DDOWNLOAD_BOOST=0 -DWITH_INNODBBASE_STORAGE_ENGINE=1 -
    DENABLE_LOCAL_INFILE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -
    DDEFAULT_COLLATION=utf8_general_ci -DMYSQL_USER=mysql -DWITH_DEBUG=0
    -DWITH_EMBEDED_SERVER=0 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost

    make
    make install

    #如果需要重新cmake 就把CMakeCache.txt文件删除后再cmake

安装后操作!
    cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
    chmod 755 /etc/init.d/mysql
    chown mysql.mysql /usr/local/mysql/ -R
    ln -sf /usr/local/mysql/bin/* /usr/bin/
    ln -sf /usr/local/mysql/lib/* /usr/lib/
    ln -sf /usr/local/mysql/libexec/* /usr/local/libexec
    ln -sf /usr/local/mysql/share/man/man1/* /usr/share/man/man1
    ln -sf /usr/local/mysql/share/man/man8/* /usr/share/man/man8


修改配置文件修,确保路径正确!
    vim /etc/my.cnf
    确保所有参数的路径正确
    [root@web01. ~]# egrep -v "^#|^$" /etc/my.cnf
    [mysqld]
    basedir=/usr/local/mysql
    datadir=/usr/local/mysql/data
    socket=/usr/local/mysql/mysql.sock
    symbolic-links=0
    [mysqld_safe]
    log-error=/var/log/mysql.log
    pid-file=/var/run/mysql.pid
    !includedir /etc/my.cnf.d

初始化数据库!
/usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/

注意保存临时密码:初始化之后有[Note] A temporary password is gennerated for root@localhost: /q%Zpaoio5i1


启动mysql
    /etc/init.d/mysql start
密码修改
    mysql_secure_installation
测试
    mysql -u root -pabc123    


cmake 参数分解!
    -DCMAKE_INSTALL_PREFIX 指定安装路径
    -DMYSQL_DATADIR 指定存放数据文件的目录位置
    -DMYSQL_UNIX_ADDR 指定mysql.sock的路径
    -DDOWNLOAD_BOOST=0 不下载boost库文件
    -DWITH_INNODBBASE_STORAGE_ENGINE=1 指定默认存储引擎
    -DENABLE_LOCAL_INFILE=1 允许客户端使用local data local 导入本地数据文件
    -DEXTRA_CHARSETS=all 支持所有字符集
    -DDEFAULT_CHARSET=utf8 默认字符集是UTF-8
    -DDEFAULT_COLLATION=utf8_general_ci 数据库校对规则
    -DMYSQL_USER=mysql 管理用户是mysql
    -DWITH_DEBUG=0 关闭debug
    -DWITH_EMBEDED_SERVER=0 生成一个libmysqld.a(.so)的库,这个库同时集成了了mysql服务与客户端API
    -DWITH_BOOST=/usr/local/boost 指定boost的路径
mysql安装
# Python安装

解释器:CPython。
    CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器。
    CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行。
    用 Python 的语法混合编写 Python 和 C/C++ 代码,提升 Python 速度
    调用 C/C++ 代码

软件获得!
    wget https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tar.xz

    #默认安装路径:/usr/local/lib/python3.7
    [root@web01 ~]# tar xf Python-3.7.1.tar.xz
    [root@web01 ~]# cd Python-3.7.1
    [root@web01 Python-3.7.1]# yum -y install gcc-* openssl-* libffi-devel sqlite-devel
    [root@web01 Python-3.7.1]# ./configure --enable-optimizations --with-openssl=/usr/bin/openssl
    [root@web01 Python-3.7.1]# make -j4
    [root@web01 Python-3.7.1]# make install


安装测试!
    [root@web01. Python-3.7.1]# python3
    Python 3.7.1 (default, Oct 27 201.8, 22:51:15)
    [GCC 4.8.5 201.50623 (Red Hat 4.8.5-28)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    >>> exit();
    当我们从Python官方网站下载并安装好Python 3.5后,我们就直接获得了一个官方版本的解释器:CPython。


    ##########pip 配置需要TLS/SSL的位置,但是Python中的SSL模块不可用
    pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

    [root@web01 Python-3.7.1]# vim Modules/Setup  把下边这段话的#去掉
    211   SSL=/usr/local/ssl
    212   _ssl _ssl.c 
    213   -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl 
    214   -L$(SSL)/lib -lssl -lcrypto
    [root@web01. Python-3.7.1]# make
    [root@web01. Python-3.7.1]# make install
    ##########

升级pip!
    Pip: pip 是 Python 包管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能。
    [root@web01 ~]# pip3 install --upgrade pip


安装python虚拟环境!
    virtualenv 是一个创建隔绝的Python环境的工具。virtualenv创建一个包含所有必要的可执行文件的文件夹,用来使用Python工程所需的包。
    [root@web01 ~]# pip3 install virtualenv


使用虚拟环境!
    [root@web01 ~]# virtualenv web01
    [root@web01 ~]# source web01/bin/activate
    (web01) [root@web01 ~]# pip3 install django
    (web01) [root@web01 ~]# pip3 install django==1.9.8
    (web01) [root@web01 ~]# django-admin.py startproject myweb
    (web01) [root@web01 ~]# cd myweb
    (web01) [root@web01 ~]# python3 manage.py runserver 192.168.10.42:8000
    (web01) [root@web01 ~]# vim myweb/settings.py
    ALLOWED_HOSTS = ['*']
    deactivate 退出虚拟环境

安装Django!
    [root@web01 ~]# pip3 install django

安装uwsgi!
    wget https://files.pythonhosted.org/packages/e7/1e/3dcca007f974fe4eb369bf1b8629d5e342bb3055e2001b2e5340aaefae7a/uwsgi-2.0.18.tar.gz
    uwsgi是服务器和服务端应用程序的通信协议,规定了怎么把请求转发给应用程序和返回
    uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
    nginx 和 uWSGI交互就必须使用同一个协议,而上面说了uwsgi支持fastcgi,uwsgi,http协议,这些都是nginx支持的协议,只要大家沟通好使用哪个协议,就可以正常运行了。
    [root@web01 ~]# pip3 install uwsgi


创建uwsgi配置文件!
    [root@web01 ~]# mkdir /etc/uwsgi
    [root@web01 ~]# vim /etc/uwsgi/uwsgi.ini
    [uwsgi]
    uid = root
    gid = root
    socket = 127.0.0.1:9090
    master = true //启动主进程
    vhost = true //多站模式
    no-site = true //多站模式时不不设置入口模块和文件
    workers = 2 //子进程数
    reload-mercy = 10 //平滑的重启
    vacuum = true //退出、重启时清理文件
    max-requests = 1000 //开启10000个进程后, 自动respawn下
    limit-as = 512 // 将进程的总内存量量控制在512M
    buffer-size = 30000
    pidfile = /var/run/uwsgi9090.pid //pid文件,用于下面的脚本启动、停止该进程
    daemonize = /var/log/uwsgi9090.log
    
    pythonpath = /root/web/lib/python3.7/site-packages  //找到django的安装路径 ####

启动uwsgi:(麻烦用脚本启动)
    uwsgi --ini /etc/uwsgi/uwsgi.ini
查看: netstat -ntpl


脚本启动uwsgi:/etc/init.d/uwsgi  start
脚本关闭uwsgi:/etc/init.d/uwsgi  stop
查看状态uwsgi:/etc/init.d/uwsgi  status

脚本文件:  /etc/init.d/uwsgi
    [root@web01 ~]# cat /etc/init.d/uwsgi
        #!/bin/sh
        DESC="uwsgi daemon"
        NAME=uwsgi
        DAEMON=/usr/local/bin/uwsgi           ### which uwsgi 可以看到
        CONFIGFILE=/etc/uwsgi/$NAME.ini
        PIDFILE=/var/run/${NAME}9090.pid        ### 注意和配置文件中的一致
        SCRIPTNAME=/etc/init.d/$NAME
        FIFOFILE=/tmp/uwsgififo
        set -e
        [ -x "$DAEMON" ] || exit 0
        do_start() {
        if [ ! -f $PIDFILE ];then
        $DAEMON $CONFIGFILE || echo -n "uwsgi running"
        else
        echo "The PID is exist..."
        fi
        }
        do_stop() {
        if [ -f $PIDFILE ];then
        $DAEMON --stop $PIDFILE || echo -n "uwsgi not running"
        rm -f $PIDFILE
        echo "$DAEMON STOPED."
        else
        echo "The $PIDFILE doesn't found"
        fi
        }
        do_reload() {
        if [ -p $FIFOFILE ];then
        echo w > $FIFOFILE
        else
        $DAEMON --touch-workers-reload $PIDFILE || echo -n "uwsgi
        can't reload"
        fi
        }
        do_status() {
        ps aux|grep $DAEMON
        }
        case "$1" in
        status)
        echo -en "Status $NAME: 
"
        do_status
        ;;
        start)
        echo -en "Starting $NAME: 
"
        do_start
        ;;
        stop)
        echo -en "Stopping $NAME: 
"
        do_stop
        ;;
        reload|graceful)
        echo -en "Reloading $NAME: 
"
        do_reload
        ;;
        *)
        echo "Usage: $SCRIPTNAME {start|stop|reload}" >&2
        exit 3
        ;;
        esac
        exit 0


    [root@web01 ~]# chmod 755 /etc/init.d/uwsgi
    [root@web01 ~]# mv myweb /usr/local/nginx/html/

Nginx发布:
    server {
    listen 80;
    server_name localhost;
    #access_log logs/abc.log main;
    location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:9090;
    uwsgi_param UWSGI_SCRIPT myweb.wsgi;        ###
    uwsgi_param UWSGI_CHDIR /usr/local/nginx/html/myweb;  ###
    index index.html index.htm;
    client_max_body_size 35m;
    #uwsgi_cache_valid 1m;
    #uwsgi_temp_file_write_size 64k;
    #uwsgi_busy_buffers_size 64k;
    #uwsgi_buffers 8 64k;
    #uwsgi_buffer_size 64k;
    #uwsgi_read_timeout 300;
    #uwsgi_send_timeout 300;
    #uwsgi_connect_timeout 300;
    }
    }
Python安装

原文地址:https://www.cnblogs.com/bubu99/p/12920058.html