前言
献给那些和我一样懵懂中不断汲取知识,进步的人们。
部署目标
web项目基于python3+flask+MySQL进行开发。项目为实验室资产管理平台,面向用户为实验室管理员提供管理权限,为其他同事提供查询权限。
项目准备部署在本地虚拟机系统上(Linux),采用服务器组件为nginx+uWSGI+MySQL,至于为什么选择这些组件,因为是行业标准。刚开始部署的时候采用的是centos系统,部署过程发现比较麻烦,后改用Ubuntu系统。
说句题外话,强烈推荐Ubuntu系统,就算是面向个人使用,Ubuntu也有比较友好的图形操作界面。
环境安装
在本地系统(Windows)上安装WMware软件(一定要下载高版本15及以上,不然很可能出现兼容性问题。我在部署过程的就在这里出现了兼容性问题)。
然后去Ubuntu官网下载iso文件。
在VMware中安装Ubuntu系统,具体安装过程不再介绍,如果不清楚,可以去网上查找相关资料。
下面主要介绍一下,网络适配器相关设置,因为我们需要与虚拟机系统进行通信。
网络适配器设置
关于网卡设置这一块,具体根据需求和你的网络拓扑而定。在这里,介绍一下我的环境及网卡配置。我本地计算机操作系统为Win10,总共有7个网络适配器(实体网卡),别问我为什么计算机会有这么多网卡- -。目前本地计算机只用到了两张实体网卡,一张连接办公网,另一张连接路由器LAN口,用于访问外网。在VMware虚拟机设置中,为Ubuntu系统创建2个网络适配器,分别桥接至VMnet0、VMnet8。然后在VMware软件编辑-虚拟编辑器中设置VMnet0、VMnet8分别桥接至两张实体网卡。Ubuntu系统中桥接至办公网的虚拟网卡设置为静态IP地址,另一张虚拟网卡则设置为自动获取方式。
为什么我需要这样设置?桥接至办公网,一方面为了向内网同事提供平台web服务,另一方面便于从我Windows计算机通过终端软件(SecureCRT)SSH访问Ubuntu。从VMware软件中操作Ubuntu系统终端,实在太过繁琐且又比较占用计算机资源。桥接外网,便于Ubuntu系统从互联网上下载安装依赖包。
网卡设置完成后,在Ubuntu中打开终端并安装openssh-server,安装完成后,可以关闭VMware软件,选择后台运行虚拟机。在本地计算机上通过SecureCRT访问虚拟系统终端。
安装软件
更新apt1
2sudo apt-get update
sudo apt-get upgrade
一条命令就可以下载一些常用包,是不是非常方便。(Ubuntu系统自带python3)1
sudo apt-get install net-tools openssh-server vim mysql-server nginx python3-pip
下载uwsgi1
pip3 install uwsgi
MySQL相关设置
修改MySQL账户和密码
通过apt-get命令安装MySQL后,我们会存在一个疑问,我们怎么知道root用户的登录密码呢。不知道没关系,使用管理员权限进行设置。1
sudo mysql
使用mysql库1
use mysql
修改root用户名登录密码为root1
update user set authentication_string='root' where user='root'
设置远程连接MySQL
mysql安装完成后,输入以下命令。可以查看到127.0.0.1:3306,3306是mysql服务的默认端口。127.0.0.1代表只监听本地连接。1
netstat -anltp
如果未查到相关信息,则mysql服务未启动,输入下面命令启动mysql1
sudo service mysql start
关闭mysql服务则采用1
sudo service mysql stop
注释/etc/mysql/mysql.conf.d/mysqld.cnf中的bind-adress 127.0.0.1,然后重启msyql。1
sudo service mysql restart
再次输入以下命令,结果显示的是:::3306表示设置成功。1
netstat -apn|grep 3306
后面再修改mysql用户登录权限,以root权限在本地登录mysql。选择MySQL库1
2
3mysql -u root -p
use mysql;
select host,user from user;
更新user表,将root用户记录host改为’%’,最后刷新权限1
2update user set host ='%' where user='root';
flush privileges;
以上设置完成后,就可以在我的开发环境(Windows系统)上通过办公网,远程访问生产环境中数据库了。不过要注意保管生产环境中MySQL数据库的账户名密码,以保证数据安全。
MySQL数据传输
前面已经设置了能远程连接Ubuntu系统中的MySQL。这里推荐在本地计算机上使用Navicat for MySQL软件(30天免费试用)远程连接Ubuntu系统中的MySQL,可以获得图形化操作界面,便于操作查看数据。
在Ubuntu系统的MySQL创建数据库,注意这里的数据库名应与代码里数据库名保持一致,否则连接不到数据库。然后可以使用Navicat软件将开发环境中MySQL数据库中的数据传输到生产环境中的MySQL对应的数据库中。
源码上传
将源码上传至Ubuntu系统的/srv目录下,然后通过pip3安装项目依赖库。
Tips:如果Ubuntu系统上还部署了其他python项目,且项目之间依赖库的版本存在冲突。那么此时可以使用python虚环境,将本项目的依赖库安装在虚环境中,实现隔离。我们可以通过使用virtualenv库实现。1
pip3 install virtualenv
创建目录,然后进入该目录下创建一个独立运行的Python环境1
virtualenv --no-site-packages venv
激活venv环境,此时通过pip安装的都被放到这个环境中1
source venv/bin/activate
关闭venv环境,使用以下命令1
deactivate
因为我的系统只部署这一个项目,没有存在项目冲突的情况,所以不使用虚环境。
一键安装项目依赖库文件。1
pip3 -r requirements.txt
此文件可以通过以下命令得到(注意如果该项目不是虚环境中开发的,那么其他一些非依赖库也被添加进来,注意在.txt文件中删除。)1
pip3 freeze > requiremtns.txt
服务器组件
nginx介绍
nginx是一个高性能的web和反向代理服务器,也可以用做邮件代理服务器。nginx尤其在处理静态文件和资源拥有比较高的效率。在本项目中采用nginx组件,也是考虑使用它来处理静态资源,同时作为反向代理把动态请求交给uWSGI处理。
关于nginx详细配置,这里贴一下nginx官方中文文档。
nginx简单配置
nginx是一个非常强大的服务器组件,想在短时间内将它的功能和配置全部掌握基本不可能。我们根据自己的需求学习即可,一切均是为了业务而服务。
在Ubuntu系统中通过命令安装nginx后,nginx配置文件存放/etc/nginx/路径下。
进入/etc/nginx/sites-available下1
2cd /etc/nginx/sites-available
sudo vim default
修改default文件为如下配置,#代表注释:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
# nginx监听80端口
listen 80;
# 设置项目根路径及日志文件存放
root /srv/Lab_mangement/app;
access_log /srv/Lab_mangement/log/acess_log;
error_log /srv/Lab_mangement/log/error_log;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name localhost;
# 处理静态文件
location /favicon.ico {
root /srv/Lab_mangement/app;
}
# 处理静态资源
location ~ ^\/static\/.*$ {
root /srv/Lab_mangement/app;
}
# 设置与uWSGI通信,动态请求转发给uWSGI
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#proxy_pass http://127.0.0.1:5000;
include uwsgi_params;
uwsgi_pass 127.0.0.1:8888;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header Host $host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#try_files $uri $uri/ =404;
}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
配置default完成后,进入/etc/nginx/sites-enabled路径,删除default,创建软链接1
2
3$ pwd
/etc/nginx/sites-enabled
$ sudo ln -s /etc/nginx/sites-available/default .
以下列出一些配置nginx服务的命令
启动nginx服务1
sudo /etc/init.d/nginx start
停止nginx服务1
sudo /etc/init.d/nginx stop
重启nginx服务1
sudo /etc/init.d/nginx restart
uWSGI介绍
首先我们需要理清楚几个概念,uWSGI/WSGI/uwsgi,注意大小写。
uWSGI是一个c语言写的web服务器,性能比较高,能够用于实际生产环境。作为HTTP服务器,它将HTTP协议转化成语言支持的网络协议,比如把HTTP协议转化成WSGI 协议,让Python可以直接使用。Flask框架也自带web服务器,但只适用于开发调试,不适合实际生产环境。
WSGI(Web Server Gateway Interface)Web服务器网关接口。它是Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask、Django框架写的程序)通信的一种规范。
uwsgi协议是uWSGI服务器使用的本地协议,常用于在uWSGI服务器与其他网络服务器的数据通信。
Flask和Django是一个web框架,框架的作用使我们开发web应用时,关注于处理request和response。使得开发web应用更简单(专注于业务,而不是底层http通信等)。
uWSGI简单配置
创建uwsgi_cnf.ini,可以将其放在web项目根目录下
.ini文件内容如下,一些更复杂的配置请参考uWSGI文档1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[uwsgi]
# 与nginx通信接口,必须与前面nginx的配置保持一致
socket = 127.0.0.1:8888
# web应用的入口文件
wsgi-file = /srv/Lab_mangement/manage.py
# 项目根路径
chdir=/srv/Lab_mangement/
#
callable=app
# 启用线程指定进程数、线程数
enable-threads=true
processes=1
threads=2
master=true
# 使用的协议
protocol = uwsgi
buffer-size=65536
终端执行命令拉起uWSGI服务1
uwsgi uwsgi_conf.ini
其他组件
通过查阅资料,还有一些比较有用的工具,本次部署项目虽然没有用上,但先做个记录。比如Fabric,Supervisor
Fabric是一个用Python写的自动化工具,能够利用Fabric将本地开发环境上的代码自动部署到Linux系统,推荐Fabric,它能够支持python2和python3。
Supervisor是一个管理进程的工具,可以随系统启动而启动服务,它还时刻监控服务进程,如果服务进程意外退出,Supervisor可以自动重启服务。
组件之间是如何进行工作的?
简单说一下个人的理解,如有不正确的地方,欢迎发邮件给我指正。
首先浏览器发起http请求到nginx服务器,Nginx根据接收到请求包,进行url 分析,判断访问的资源类型,如果是静态资源,直接读取静态资源返回给浏览器,如果请求的是动态资源就转交给uWSGI服务器,uWSGI服务器根据自身的uwsgi和WSGI 协议,找到对应的flask框架,flask框架下的应用进行逻辑处理,有可能还需读取MySQL,将返回值发送到uWSGI服务器,然后uWSGI服务器再返回给nginx,最后 nginx将返回值返回给浏览器进行渲染显示给用户。
访问
以上均设置无误的话。假设Ubuntu系统桥接至办公网的那张网络适配器IP地址192.168.97.61,其他在局域办公网内的计算机通过浏览器访问这个地址,就能刷新打开页面了。