项目部署上线nginx+gunicorn+django

1 项目代码打包部署

包压缩技巧:

tar -cjvf python3.6_env.tar.bz2 python3.6_env/

tar xjvf python3.6_env.tar.bz2

一。压缩拷贝代码:

(1)进入工程主目录

cd SHDjangoLesson

(2)产生依赖库 pip freeze > requirements.txt

(3)压缩

cd  SHDjangoLesson

zip -r SHDjangoLesson.zip SHDjangoLesson/

二。远程拷贝

服务器端(ubuntu):

nc -l 11111 > SHDjangoLesson.zip

客户端:

nc IP 11111 < SHDjangoLesson.zip

三。配置环境, 解压

python依赖的环境: python3.5 或者 python3.6

安装并配置虚拟环境:

source python3.6/bin/activate

进入虚拟环境

pip install -r requirements.txt

查看环境依赖:pip list

四。启动服务

确认redis, mysql安装良好,能访问

setings.py 中 ALLOWS = [‘*’]

启动服务

python manage.py runserver 0.0.0.0:8000

(无问题情况,在后台运行:

nohup python manage.py runserver 0.0.0.0:8000 &

)

备注:

如果出现如下问题:

DjangoUeditor ModuleNotFoundError: No module named ‘widgets’

解决方案:

(1)从https://github.com/twz915/DjangoUeditor3.git重新下载到本地

(2)修改DjangoUeditor下的views.py中的240行,添加:

output_path = "/static/" + urljoin(USettings.gSettings.MEDIA_URL, OutputPathFormat)
return_info = {
        # 保存后的文件名称
        #'url': urljoin(USettings.gSettings.MEDIA_URL, OutputPathFormat),
        'url': output_path,

(3)编译 进入到DjangoUeditor工程目录 python setup.py install

2 项目分布式部署的整体框架图

提供两种方案,一个备选方案:

方案1:

client —> Nginx(openresty) —> gunicorn (通过wsgi启动托管) —> django (应用服务)

方案2:

Nginx(openresty, upstream) —> supervisor (monitor ) ——> gunicorn (同uwsgi) —> django (应用服务)

备选:

按照原来的HTTP启动的方式

nohup python manage.py runserver 0.0.0.0:9001 &

Nginx(openresty, upstream) —> supervisor(minitor) HTTP —> django (HTTP)

使用如下框架和工具

  1. 反向代理负载均衡服务器: Nginx (Openresty)
  2. gunicorn (代替uwsgi)
  3. django
  4. supervisor (监控并拉起失败服务)

1 安装项目依赖包

pip list

采用pip freeze产生项目依赖包,输出到 requirements.txt

pip freeze > requirements.txt

拷贝requirements.txt文件到线上服务器,并在虚拟环境下安装

将线下项目工程目录打包,并用nc上传到服务器上。

假设线上的工程目录放在了

2 安装gunicorn

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

在虚拟环境下安装上述的requirements.txt中对应的依赖包

(1)pip install -r requirements.txt

注:

pip install future -i https://pypi.douban.com/simple     (可能会安装)

确保DjangoUeditor3安装成功,之前讲过从git下载安装

(2)pip install gunicorn -i https://pypi.douban.com/simple

(3)启动gunicorn, 命令如下:

具体chdir是项目所在的目录

nohup gunicorn --chdir /home/uesrname/工程name/  projectname.wsgi:application  --bind 0.0.0.0:9000  --workers=2 &

3 关于静态资源管理

将分散在各个app应用中的静态资源集中管理,采用如下命令:

python manage.py collectstatic

此时会在base_dir目录下产生statics文件夹

后面nginx静态文件配置就可以指定此路径

4 配置Nginx服务器

在nginx服务器配置中修改配置目录

将nginx.conf修改为:

# user  nobody;
# user nginx;
worker_processes  2;        #cat /proc/cpuinfo
# worker_cpu_affinity       0001 0010 0100 1000;

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

pid  logs/nginx.pid;

events
{
    use   epoll;
    multi_accept  on;
    accept_mutex_delay  50ms;
    worker_connections  1024;    #每个worker支持最大网络连接数
}    

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

# log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"'
#                  '"$upstream_addr" "$upstream_status" "$upstream_response_time" '
#                  '$request_time -- $http_cookie -- $cookie_pin';


# access_log  logs/access.log  main;

sendfile  on;
tcp_nopush  on;

keepalive_timeout  0;

gzip  on;
gzip_min_length  1k;
gzip_buffers 4 16k;
gzip_http_version  1.1;
gzip_types  text/plain application/x-javascript text/css  text/shtml application/xml;

proxy_intercept_errors  on;
charset  utf-8;

######################
include  conf.d/*.conf;
######################

}

创建目录conf.d, 并添加如下信息到project.conf:

proxy_next_upstream  error;

server
{
    listen 8000;       #nginx提供对外的端口是8000, 通过路由 / 转发到127.0.0.1:9000/art/index 服务,而9000端口是上述gunicorn提供的端口
    server_name   localhost;

    client_max_body_size  50M;

    #配置项目静态资源目录
    location /static/ {

        root /home/zhouguangyou/artproject/art;
    }


    location / {
        proxy_pass   http://127.0.0.1:9000;
        proxy_set_header  Host $host;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
     }

    # 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服务,生效。

通过以上的配置信息,基本已经完成了nginx + gunicorn + django的配置

测试:http://127.0.0.1:8000/, 可以看到项目的效果图

5 安装Supervisor与配置

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

(1)安装supervisor

(python3.6_env) zhouguangyou@ubuntu:~$ sudo apt install supervisor

上述方法我们直接管理gunicorn,让它启动和暂停,现在我们希望采用supervisor来管理gunicorn

(2)配置supervisor
将supervisor设置为管理启动监控 gunicorn

下面介绍与supervisor相关的几个概念:
echo_supervisord_conf命令:打印supervisor常用配置,可以重定向命令将配置输出到文本文件echo_supervisord_conf > haha.conf

supervisord:supervisor的后台守护进程,跟mysqld、ftpd等服务一样,它是一个TCP客户端,监听某个固定端口。

supervisorctl:command tools,是supervisor控制台,这个控制台可以远程控制服务器上的supervisord,它们之间的通信方式为XML-RPC

supervisorctl常用命令:help查看全部命令
当修改supervisord.conf之后,需要在supervisorctl中使用reload命令重新加载配置

配置文件最佳实践:

将每一个应用创建一个conf文件,放在/etc/supervisor/conf.d目录下,主配置文件/etc/supervisord.conf中默认包含了conf.d目录下的配置文件。
像这种一个主配置文件,允许自定义从配置文件的方式很常见,很多软件都是这样配置的。

/etc/supervisord.conf主配置文件包含了conf.d/*.conf

[include]
files = /etc/supervisor/conf.d/*.conf

往supervisor.conf 中添加如下信息

[group:artprojects]
programs=art-1, art-2  


[program:art-1]
command=gunicorn --chdir /home/zhouguangyou/artproject/ artproject.wsgi:application  --bind 0.0.0.0:9001  --workers=2
directory=/home/zhouguangyou/artproject
user=zhouguangyou
autorestart=true
redirect_stderr=true
stdout_logfile=log/art1.log
loglevel=info
stopsignal=INT


[program:art-2]
command=gunicorn --chdir /home/zhouguangyou/artproject/ artproject.wsgi:application  --bind 0.0.0.0:9002 --workers=2
directory=/home/zhouguangyou/artproject
user=zhouguangyou
autorestart=true
redirect_stderr=true
stdout_logfile=log/art2.log
loglevel=info
stopsignal=INT

[supervisord]
nodaemon=false
logfile=log/supervisord.log
pidfile=log/supervisord.pid
loglevel=info

创建log文件夹,存放日志文件

在nginx配置文件project.conf中加入如下信息

upstream artprojects{
    #ip_hash;  or  轮询(默认) or url_hash
    server 127.0.0.1:9001;
    server 127.0.0.1:9002;
 }

 location / {
       #(2) method2: use proxy_pass upstream to the supervisor who manage the gunicorn

      proxy_pass  http://artprojects;
  }

添加好上述配置信息后

(1)启动nginx

(2)通过supervisor启动gunicorn

supervisord -c supervisor.conf

页面通过http://127.0.0.1:8000/art/index进行页面访问,观看效果。

综合上述,nginx做反向代理和负载均衡,将请求upstream转发给一个Supervisor监管的Gunicorn进程,而Gunicorn进程拖管了Django工程代码。

至此,Nginx + Gunicorn + Supervisor + Django 线上环境部署都已经完成!

supervisor 启动时出现的问题

http://xiaorui.cc/2015/12/21/python-supervisor%E7%AE%A1%E7%90%86%E8%BF%9B%E7%A8%8B%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/

第一个问题:
unix:///var/run/supervisor.sock no such file
这个问题是因为yum版本的pip的版本不一致引起的,说白了rpm有bug. 我们尽量使用pypi里面的安装包,而不是rpm的包.

第二个问题:
起初在supervisord.conf配置了程序的名字,但是在ps aux里面看到的还是command的命令,最后通过官方的文档得知
process_name=transfer
process_name是启动的进程名字,这里的名字只是supervisor内部是别用,与你所启动程序的进程名无关,所以你ps ef看到的是command的命令.

第三个问题:
2015-12-21 18:10:09,688 CRIT Server ‘unix_http_server’ running without any HTTP authentication checking
2015-12-21 18:10:09,690 INFO daemonizing the supervisord process
2015-12-21 18:10:09,691 INFO supervisord started with pid 12822
2015-12-21 18:10:10,695 INFO spawned: ‘transfer’ with pid 12824
2015-12-21 18:10:10,704 INFO exited: transfer (exit status 127; not expected)
2015-12-21 18:10:11,707 INFO spawned: ‘transfer’ with pid 12825
2015-12-21 18:10:11,716 INFO exited: transfer (exit status 127; not expected)
2015-12-21 18:10:13,720 INFO spawned: ‘transfer’ with pid 12828
2015-12-21 18:10:13,730 INFO exited: transfer (exit status 127; not expected)
2015-12-21 18:10:16,736 INFO spawned: ‘transfer’ with pid 12829
2015-12-21 18:10:16,746 INFO exited: transfer (exit status 127; not expected)
2015-12-21 18:10:17,765 INFO gave up: transfer entered FATAL state, too many start retries too quickly

去掉supervisord.conf的directory=/home/ruifenygun/shop_master/shop_scripts配置行就可以了.
原因已经问老外了.

猜你喜欢

转载自blog.csdn.net/weixin_42143550/article/details/81139248