zoukankan      html  css  js  c++  java
  • nginx + uwsgi +sqlite3 + linux

    部署方式:

    1.升级python 

    CentOS 7 中默认安装了 Python,版本比较低(2.7.5),为了使用新版 3.x,需要对旧版本进行升级。

    由于很多基本的命令、软件包都依赖旧版本,比如:yum。所以,在更新 Python 时,建议不要删除旧版本(新旧版本可以共存)

    查看 Python 版本号

    当 Linux 上安装 Python 后(默认安装),只需要输入简单的命令,就可以查看 Python 的版本号:

    # python -V
    Python 2.7.5

     使用 wget 将安装包都下载到 /Downloads/

    [root@localhost Downloads]# ll
    总用量 40932
    drwxr-x---. 18 root  root      4096 9月  26 12:22 Python-2.7
    -rw-r--r--.  1 root  root  14026384 9月  26 12:22 Python-2.7.tgz
    drwxr-xr-x. 19 root  root      4096 9月  26 14:13 Python-3.7.0
    -rw-r--r--.  1 root  root  22745726 9月  26 12:21 Python-3.7.0.tgz
    -rw-r--r--.  1 root  root     41313 9月  26 12:22 python-iniparse-0.4-18-omv4002.noarch.rpm
    -rw-r--r--.  1 root  root     39780 9月  26 12:22 python-sqlite-1.1.7-1.2.0.99_4.el4.at.x86_64.rpm
    drwxr-xr-x.  5  1000  1000     4096 9月  26 14:56 sqlite-autoconf-3300100
    -rw-r--r--.  1 root  root   2848951 9月  26 12:22 sqlite-autoconf-3300100.tar.gz
    drwxrwxr-x. 20 30001 30001     4096 6月  20 2020 uwsgi-2.0.19.1
    -rw-r--r--.  1 root  root    811149 9月  26 12:22 uwsgi-2.0.19.1.tar.gz
    -rw-r--r--.  1 root  root   1298856 9月  26 12:22 yum-3.4.3-168.el7.centos.noarch.rpm
    -rw-r--r--.  1 root  root     28348 9月  26 12:22 yum-metadata-parser-1.1.4-10.el7.x86_64.rpm
    -rw-r--r--.  1 root  root     35216 9月  26 12:22 yum-plugin-fastestmirror-1.1.31-54.el7_8.noarch.rpm
    [root@localhost Downloads]# 

    1、环境准备:先安装准备环境

    yum install gcc gcc-c++ automake pcre pcre-devel zlip zlib-devel openssl openssl-devel 

     解压

    # tar -zxvf Python-3.7.0.tgz

    安装配置

    进入解压缩后的目录,安装配置:

    # cd Python-3.7.0/
    # ./configure  make && make install

    验证

    安装成功以后,就可以查看 Python 的版本了:

    # python -V
    Python 2.7.5
    # python3 -V
    Python 3.7.0

    一个是旧版本 2.x,另外一个是新版本 3.x。

    注意:在 /usr/local/bin/ 下有一个 python3 的链接,指向 bin 目录下的 python 3.7。

    设置 3.x 为默认版本

    查看 Python 的路径,在 /usr/bin 下面。可以看到 python 链接的是 python 2.7,所以,执行 python 就相当于执行 python 2.7。

     

    将原来 python 的软链接重命名:

    # mv /usr/bin/python /usr/bin/python.bak

    将 python 链接至 python3:

    # ln -s /usr/local/bin/python3 /usr/bin/python

    这时,再查看 Python 的版本:

    # python -V
    Python 3.7.0

     输出的是 3.x,说明已经使用的是 python3了。

     

    配置 yum

    升级 Python 之后,由于将默认的 python 指向了 python3,yum 不能正常使用,需要编辑 yum 的配置文件:

    # vi /usr/bin/yum

    同时修改:

    # vi /usr/libexec/urlgrabber-ext-down
    将 #!/usr/bin/python 改为 #!/usr/bin/python2.7,保存退出即可。

    2.升级 sqlite3 解决Django.core.exceptions.ImproperlyConfigured: SQLite 3.9.0 or later is required (found 3.7.17)。

    CentOS 自带 3.7.17 Django,不支持。它必须高于 3.9.0。如果你想用SQLite3作为数据库,是没有办法升级的。如果是我,我不会用SQLite3,而是用mysql

    
    

    升级很简单:

    
    

    1.下载SQLite3最新包

    https://www.sqlite.org/download.html
    
    wget https://www.sqlite.org/2021/sqlite-autoconf-3350500.tar.gz
    2.编译安装
    
    tar xf https://www.sqlite.org/2021/sqlite-autoconf-3350500.tar.gz
    cd sqlite-autoconf-3350500
    ./configure --prefix=/usr/local/ && make && make install 

     

    3.改变原来的SQLite3命令

    首先检查SQLite3在哪个目录中有可执行文件

    [root@localhost Downloads]# whereis sqlite3
    sqlite3: /usr/bin/sqlite3 /usr/local/bin/sqlite3 /usr/share/man/man1/sqlite3.1.gz
    [root@localhost Downloads]# sqlite3 -V

     

    发现/usr/bin/SQLite3是旧的,3.7.17。如果您不确定,请执行它

    /usr/bin/sqlite3 –version

    然后替换旧版本

    mv /usr/bin/sqlite3 /usr/bin/sqlite3_3.7.17
     ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3

     

    4.更改库路径

    很多小伙伴去上面测试了一下。他们发现在执行python manage.py runserver 8080时还是报同样的错误,原因是django读取了旧库,可以自行验证

    (python36) [root@george servermonitor]# python 
    Python 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 
    (Red Hat 4.8.5-44)] on linux Type "help", "copyright", "credits" or "license" for more information.
     >>> import sqlite3
     > >>> sqlite3.sqlite_version 
     > '3.7.17'      
    >>> .exit

     

    修改库变量

    export LD_LIBRARY_PATH="/usr/local/lib/"

     永久修改

    修改~/.bashrc或~/.bash_profile或系统级别的/etc/profile
             1. 在其中添加例如
          export LD_LIBRARY_PATH="/usr/local/lib/"
    2. source .bashrc (Source命令也称为“点命令”,也就是一个点符号(.)。source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录)

     测试 

    python manage.py runserver 8080

     3.安装 uwsgi

    Django的主要部署平台是WSGI,它也是Python的标准web服务器和应用。

    uWSGI是实现了WSGI协议的WSGI服务器。

    uWSGI 是一个快速的、自我驱动的、对开发者和系统管理员友好的应用容器服务器,完全由 C 编写。

    uWSGI的官网地址:https://uwsgi-docs.readthedocs.io/en/latest/index.html

    根据血和泪的经验教训,请确保安装的是最新版本的uwsgi,否则可能出现各种坑。

    所以不建议使用:pip3 install uwsgi(不一定是最新版)

    不建议使用:pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz(也不一定是最新版)

    而是建议到https://uwsgi-docs.readthedocs.io/en/latest/Download.html页面,下载Stable/LTS版本的源文件。

    为什么要最新版?因为现在的官方教程和相关技术文章全是以新版编写的,很多参数名,用法有较大改变。用旧版,你可能连跑都跑不起来。

    这里使用进行安装

    pip3 install uwsgi

    安装完毕后,尝试运行一下uwsgi:

    root@kube mylab]# uwsgi
    *** Starting uWSGI 2.0.19.1 (64bit) on [Fri Jan 15 15:14:13 2021] ***
    compiled with version: 4.8.5 20150623 (Red Hat 4.8.5-39) on 13 January 2021 07:53:36
    os: Linux-3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019
    nodename: kube.master
    machine: x86_64
    ....
    uwsgi --python -version

    测试 uwsgi

    在项目目录执行
    uwsgi --http 192.168.2.2:8000 --file network/wsgi.py --static-map=/static=/opt/project_network/network/network/static

    配置uwsgi

    在项目目录下 mkdir script 文件

    [root@localhost script]# pwd
    /opt/project_network/script
    [root@localhost script]# cat uwsgi.ini 
    [uwsgi]
    #项目根目录
    chdir = /opt/project_network/network/
    #  指定wsgi模块下的application对象,就是调用 mylab.wsgi 文件中的 application 对象
    module = network.wsgi:application     
    #wsgi-file = /opt/project_network/network/network/wsgi.py
    #//对本机8000端口提供服务
    #http-socket = 192.168.2.2:8888         
    socket = /opt/project_network/script/network.sock
    #//主进程
    master = true                   
    
    
    # 以上4个是核心配置项
    
    #vhost = true          //多站模式
    #no-site = true        //多站模式时不设置入口模块和文件
    #workers = 2           //子进程数
    #reload-mercy = 10
    #vacuum = true         //退出、重启时清理文件
    max-requests = 1000
    limit-as = 512
    buffer-size = 30000
    pidfile = /opt/project_network/script/uwsgi9090.pid   
    # //pid文件,用于下脚本启动、停止该进程
    
    
    #日志文件
    daemonize = /opt/project_network/script/uwsgi.log 
    #不记录正常信息,只记录错误信息
    #disable-logging = true  
    [root@localhost script]# 

    相关命令:

    [root@localhost script]# uwsgi --ini uwsgi.ini   #启动
    [uWSGI] getting INI configuration from uwsgi.ini
    [root@localhost script]# uwsgi --stop uwsgi9090.pid    #停止
    [root@localhost script]# 

    相关问题: 出现了 getway 502 报错 ,最终原因是 一定要确认前面的 python3 sqlite3 成功替换,nginx 调用出问题,可以根据uwsgi.log 排查

     4.安装 nginx 

    下载 nginx repo 文件

    [root@localhost script]# cat /etc/yum.repos.d/nginx.repo 
    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    [root@localhost script]# 
    yum update
    yum install nginx -y
    [root@localhost script]# cat /etc/nginx/conf.d/network.conf 
    server {
            #如果要使用  https 请参考nginx 添加证书的博客
            listen 80;   #区别于 uwsgi  端口,不然会造成端口冲突
            #listen [::]:8090;    #监听 ipv6 端口
        error_log /opt/project_network/script/nginx_error.log;
        access_log /opt/project_network/script/nginx_access.log main;
        charset utf-8;
        gzip on;
            server_name 192.168.2.2;    #当访问此名称时 ,nginx 会进行server_name 进行匹配
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
    
            location / {      #匹配  / 目录
                include uwsgi_params;    #导入 uwsgi_params 文件
                uwsgi_pass unix:/opt/project_network/script/network.sock;   #使用 uwsgi_pass 参数将数据传递给 uwagi 应用服务器,使用 uwsgi.ini 中定义的 sock 文件
            
            
            }
            location /static/ {         #匹配static 静态文件的 ,进行别名处理
            
                alias /opt/project_network/network/network/static_all/;
            index index.html index.htm;
            
            }
    
    
    }
    [root@localhost script]# 

     查看 sock 

    [root@localhost script]# netstat -ap --unix |grep uwsgi #netstat -ap --unix #显示处于监控状态的unix socket,-a显示所有state状态的链接,因为默认不显示处于listening状态的。-p显示与socket有关的pid/programe name
    unix  2      [ ACC ]     STREAM     LISTENING     18516    1158/uwsgi           /opt/project_network/script/network.sock
    unix  3      [ ]         STREAM     CONNECTED     18532    1158/uwsgi           
    unix  3      [ ]         STREAM     CONNECTED     18529    1158/uwsgi           
    unix  3      [ ]         STREAM     CONNECTED     18530    1158/uwsgi           
    unix  3      [ ]         STREAM     CONNECTED     18531    1158/uwsgi           
    [root@localhost script]# 

    重要生产操作:

    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/3.2/howto/static-files/
    
    #静态资源的访问
    # STATIC_URL 引用位于 STATIC_ROOT 中的静态文件时要使用的 URL。
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR,'static_all')
    
    #这个配置定义了静态文件应用在启用 FileSystemFinder 查找器时将穿越的额外位置,例如,如果你使用 collectstatic 或 findstatic 管理命令或使用静态文件服务视图。
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'static')
        ]
    [root@localhost network]# python manage.py collectstatic   #会将 admin 文件  和 STATICFILES_DIRS 定义的目录合并为 static_all 中 , 因此 nginx 中的
    alias /opt/project_network/network/network/static_all/;   这里不是  static 结尾
     

    collectstatic

    django-admin collectstatic

    将静止文件收集到STATIC_ROOT中。

    项目目录结构

    [root@localhost opt]# tree -L 3
    .
    └── project_network
        ├── network
        │   ├── db.sqlite3
        │   ├── __init__.py
        │   ├── logs
        │   ├── manage.py
        │   ├── network
        │   ├── __pycache__
        │   └── requirement.txt
        └── script
            ├── network.sock
            ├── nginx_access.log
            ├── nginx_error.log
            ├── uwsgi9090.pid
            ├── uwsgi.ini
            └── uwsgi.log
    
    6 directories, 10 files
    [root@localhost opt]# 
    

      

     uwsgi 标准配置 https://www.techatbloomberg.com/blog/configuring-uwsgi-production-deployment/

    [uwsgi]
    strict = true
    master = true
    enable-threads = true
    vacuum = true                        ; Delete sockets during shutdown
    single-interpreter = true
    die-on-term = true                   ; Shutdown when receiving SIGTERM (default is respawn)
    need-app = true
    
    disable-logging = true               ; Disable built-in logging 
    log-4xx = true                       ; but log 4xx's anyway
    log-5xx = true                       ; and 5xx's
    
    harakiri = 60                        ; forcefully kill workers after 60 seconds
    py-callos-afterfork = true           ; allow workers to trap signals
    
    max-requests = 1000                  ; Restart workers after this many requests
    max-worker-lifetime = 3600           ; Restart workers after this many seconds
    reload-on-rss = 2048                 ; Restart workers after this much resident memory
    worker-reload-mercy = 60             ; How long to wait before forcefully killing workers
    
    cheaper-algo = busyness
    processes = 128                      ; Maximum number of workers allowed
    cheaper = 8                          ; Minimum number of workers allowed
    cheaper-initial = 16                 ; Workers created at startup
    cheaper-overload = 1                 ; Length of a cycle in seconds
    cheaper-step = 16                    ; How many workers to spawn at a time
    
    cheaper-busyness-multiplier = 30     ; How many cycles to wait before killing workers
    cheaper-busyness-min = 20            ; Below this threshold, kill workers (if stable for multiplier cycles)
    cheaper-busyness-max = 70            ; Above this threshold, spawn new workers
    cheaper-busyness-backlog-alert = 16  ; Spawn emergency workers if more than this many requests are waiting in the queue
    cheaper-busyness-backlog-step = 2    ; How many emergency workers to create if there are too many requests in the queue

    下面告警需要关闭 selinux 

    getenforce 
    setenforce 0 关闭 setenforce 1 开启
    2021/09/26 21:30:57 [crit] 1463#1463: *19 connect() to unix:/opt/project_network/script/network.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.2.254, server: 192.168.2.2, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/opt/project_network/script/network.sock:", host: "192.168.2.2"
    2021/09/26 21:30:57 [crit] 1463#1463: *19 connect() to unix:/opt/project_network/script/network.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.2.254, server: 192.168.2.2, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/opt/project_network/script/network.sock:", host: "192.168.2.2"

    附件:

    inux使用netstat命令监控unix domain socket(unix socket,.sock文件)状态
    UNIX Domain Socket IPC
    socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
    UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的。
    使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。
    UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

     

     

     

     

     

  • 相关阅读:
    RedisCluster的rename机制失败报错,解决又是数据倾斜问题
    开发如何避免redis集群访问倾斜和数据倾斜
    Pika 连接 rabbitmq 集群
    RabbitMQ概念及环境搭建(三)RabbitMQ cluster
    Rabbitmq安装过程和踩过的坑( 二 集群搭建 )
    java中<<、>>、>>>
    用WordPress 插入广告的几种方法
    macOS Mojave 卡顿问题解决
    前端元编程——使用注解加速你的前端开发
    如何优雅安全地在深层数据结构中取值
  • 原文地址:https://www.cnblogs.com/zy09/p/15339971.html
Copyright © 2011-2022 走看看