项目环境
- python 3
- Django 3
- 阿里云ECS服务器 CentOS 8.2
- Nginx
- uWSGI
相关信息
wsgi:一种实现python解析的通用接口标准/协议,是一种通用的接口标准或者接口协议,实现了python
web程序与服务器之间交互的通用性。 利用它,web.py或bottle或者django等等的python
web开发框架,就可以轻松地部署在不同的web server上了; uwsgi:同WSGI一样是一种通信协议
uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型,它与WSGI相比是两样东西。 uWSGI :一种python
web server或称为Server/Gateway uWSGI类似tornadoweb或者flup,是一种python web
server,uWSGI是实现了uwsgi和WSGI两种协议的Web服务器,负责响应python 的web请求。
因为apache、nginx等,它们自己都没有解析动态语言如php的功能,而是分派给其他模块来做,比如apache就可以说内置了php模块,让人感觉好像apache就支持php一样。
uWSGI实现了wsgi协议、uwsgi协议、http等协议。
Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。
其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好
Nginx作为负载均衡服务:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为
HTTP代理服务对外进行服务。 Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。
Nginx
首先客户端请求服务资源, nginx作为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析,
如果是静态文件请求就根据nginx配置的静态文件目录,返回请求的资源,
如果是动态的请求,nginx就通过配置文件,将请求传递给uWSGI;uWSGI 将接收到的包进行处理,并转发给wsgi,
wsgi根据请求调用django工程的某个文件或函数,处理完后django将返回值交给wsgi,
wsgi将返回值进行打包,转发给uWSGI, uWSGI接收后转发给nginx,nginx最终将返回值返回给客户端(如浏览器)。
*注:不同的组件之间传递信息涉及到数据格式和协议的转换
Django本身也可以完成项目的运行,django在debug=False下对静态文件的处理能力不是很好,而用nginx来处理更加高效。
第一级的nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程;
在nginx上加上安全性或其他的限制,可以达到保护程序的作用;
uWSGI本身是内网接口,开启多个work和processes可能也不够用,而nginx可以代理多台uWSGI完成uWSGI的负载均衡;
安装与配置
安装Nginx
- 使用yum进行安装 (通过sudo yum install nginx安装的安装目录在 /etc/nginx 下面,
通过官网下载稳定版压缩包的安装目录在 /usr/local/nginx/ 下 且通过压缩包安装的使用nginx命令需要配置 或者加路径)
sudo apt-get install nginx
或
sudo yum install nginx (该项目使用)
- 安装后配置文件在/etc/nginx/下的nginx.conf文件
- 运行Nginx
[root@iZwz90d8ja42qkr0jmvvqtZ ~]# nginx (任意位置运行nginx)
- 浏览器访问IP显示nginx欢迎页面就ok
安装uwsgi
- 安装uwsgi。推荐使用pip安装,命令行输入:
pip3 install uwsgi
- 测试uWSGI: 新建文件test.py,写入以下内容
touch test.py 新建文件
vim test.py 打开编辑文件
输入i进行文件编辑
编辑完成点击Esc
输入 :wq 保存退出
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
print('123432444')
return [b"Hello World"] # 注意python2 和python3的写法不一样
# return ['hello world'] # python2
- 测试uwsgi是否正常运行,在测试文件同级目录下输入
uwsgi --http 0.0.0.0:8000 --wsgi-file test.py
- 浏览器输入 ip:8000, 可以正常显示表示uwsgi安装测试成功
- 如果端口占用,使用
netstat -ntulp |grep 8000 //查看所有8000端口使用情况·
列出占用端口的程序的PID号,并使用以下命令杀掉所有占用端口的程序
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 2224/uwsgi
kill -9 PID
- 用uwsgi跑django
uwsgi --http :8000 --module myweb.wsgi (myweb项目下的wsgi, 创建项目的时候已经给我们自动生成了一个wsgi.py文件了)
(这是由于静态文件未加载的问题)
安装python
centos 8 自带python3 所以这里不需要下载安装python
centos 7 自带python2, 可以自行下载python3,并设置软链
安装Django
pip3 install django
创建Django项目
- 创建项目根目录并进入
mkdir data
cd data
- 创建Django项目 myweb
django-admin startproject myweb
- 进入myweb创建app01
django-admin startapp app01
- 创建静态文件夹static
mkdir static
进行settings.py配置(进入myweb, 打开settings.py 进行配置,输入i进行编辑, 按Esc 输入 :wq 保存退出)
DEBUG = True # 正式上线DEBUG设为false ALLOWED_HOSTS = [‘域名或者ip’]
- 注册app
```python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',# 注册app
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 配置模板文件路径
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
- 当DEBUG设置为true时, 用python3 manage.py runserver
0.0.0.0:8000启动项目,浏览器输入ip:8000可以访问Django欢迎页面,至此django项目创建并运行完毕 - 出现 Error: That port is already in use. 是因为端口被占用 直接kill掉该端口就可以了
在django项目下的setting.py文件中进行修改,便于下一步部署:
将debug改为False。移植静态文件配置,这个主要是将原项目的静态文件移植出来以便访问。注意括号中第二个参数为移植后的目录,不要和之前的静态文件目录相同就好(因为原Django项目的静态文件一般是static,所以可以换一个名字static_flies,
这里由于是新项目并没有配置static所以不影响)。setting.py文件中添加,将静态文件转移到static目录中
STATIC_ROOT = os.path.join(BASE_DIR, "static")
- 进行静态文件移植,完成上面的步骤 之后,在django项目目录下运行
python3 manage.py collectstatic
执行python3 manage.py
collectstatic命令之后,会生成一个static文件夹,文件夹中包含了css、js等一些静态文件,也包含admin的静态css文件,
(解决了当debug为False的时候Django后台管理无法显示样式)
- 配置uwsgi。对于uwsgi的配置有很多种方式(ini, xml等),这儿用ini配置,在项目目录下新建uwsgi.ini文件
[uwsgi]
socket = 127.0.0.1:8000 # 内部socket端口 自己设置 nginx把动态请求通过该端口发送给uwsgi
chdir = /data/myweb # 项目根目录
module = myweb.wsgi:application # 表示myweb项目下的wsgi.py文件 django创建项目时自动创建 (使用wsgi-file可能会报错)
processes = 4
threads = 2
master = true
pidfile = uwsgi.pid #
daemonize = uwsgi.log #日志文件,可以设置其生成位置
- 需要修改的就是chdir、module两行,第一行的端口可以自己设避免冲突,后面配置nginx时会用到。
配置nginx文件
- 打开/etc/nginx/nginx.conf 配置如下代码
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx; # 默认使用nginx用户, 最好自己用自己创建的用户
worker_processes auto; # 根据服务器的核心数自动配置进程
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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 /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server; # 监听80端口, 也就是浏览器访问时的端口
listen [::]:80 default_server;
server_name 域名或者IP;
root /data/myweb; # Django项目的更目录
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
include uwsgi_params; # 该文件在/etc/nginx/下有包含, 定义了请求数据
uwsgi_pass 127.0.0.1:8000; # 将接收到的请求传给本地的8000端口, 也就是uwsgi的socket端口, 实现和uwsgi通信
}
location /static { # 静态文件配置
alias /data/myweb/static_files; # 就是django项目中settings.py 文件里面配置的STATIC_ROOT 的路径
}
#如果还有media文件之类的静态目录,和static一样配置
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server. # 这个是配置ssl证书的暂时可以不用管
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
- 配置完成后先清掉所有的uwsgi和nginx进程, 让后先启动uwsgi再启动nginx
[root@iZwz90d8ja42qkr0jmvvqtZ myweb]# cd /data/myweb
[root@iZwz90d8ja42qkr0jmvvqtZ myweb]# uwsgi --ini uwsgi.ini # 启动uwsgi
[uWSGI] getting INI configuration from uwsgi.ini
[root@iZwz90d8ja42qkr0jmvvqtZ myweb]# ps -ef|grep uwsgi # 查看是否启动
root 2505 1 0 10:10 ? 00:00:01 /usr/local/bin/uwsgi --ini uwsgi.ini
root 3775 2505 0 11:38 ? 00:00:00 /usr/local/bin/uwsgi --ini uwsgi.ini
root 3776 2505 0 11:38 ? 00:00:00 /usr/local/bin/uwsgi --ini uwsgi.ini
root 3777 2505 0 11:38 ? 00:00:00 /usr/local/bin/uwsgi --ini uwsgi.ini
root 3778 2505 0 11:38 ? 00:00:00 /usr/local/bin/uwsgi --ini uwsgi.ini
root 3897 1288 0 12:47 pts/0 00:00:00 grep --color=auto uwsgi
[root@iZwz90d8ja42qkr0jmvvqtZ myweb]# nginx # 启动nginx
[root@iZwz90d8ja42qkr0jmvvqtZ myweb]# ps -ef|grep nginx # 查看是否启动
root 3836 1 0 12:04 ? 00:00:00 nginx: master process nginx
nginx 3837 3836 0 12:04 ? 00:00:00 nginx: worker process
root 3900 1288 0 12:48 pts/0 00:00:00 grep --color=auto nginx
[root@iZwz90d8ja42qkr0jmvvqtZ myweb]#
- 中间未报错,就可以通过域名和IP进行访问(前提是你的django项目通过runserver可以正常运行)
注意事项
- 请确认自己django的静态文件目录所有者用户
- uwsgi socket端口 和nginx uwsgi_pass端口一致
- 确认服务器端口是否开放, 安全组是否放通
- setting.py 中ALLOWED_HOSTS 是否配置
- 防火墙是否允许端口通行
firewall-cmd --query-port=80/tcp 查看端口是否开放
firewall-cmd --zone=public --list-ports
firewall查看所有打开的端口-cmd --add-port=80/tcp 开放端口
firewall-cmd --zone=public --add-port=80/tcp --permanent (--permanent永久生效,没有此参数重启后失效)