前言
献给那些和我一样懵懂中不断汲取知识,进步的人们。
部署目标
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访问虚拟系统终端。
安装软件
更新apt
1 | sudo apt-get update |
一条命令就可以下载一些常用包,是不是非常方便。(Ubuntu系统自带python3)
1 | sudo apt-get install net-tools openssh-server vim mysql-server nginx python3-pip |
下载uwsgi
1 | pip3 install uwsgi |
MySQL相关设置
修改MySQL账户和密码
通过apt-get命令安装MySQL后,我们会存在一个疑问,我们怎么知道root用户的登录密码呢。不知道没关系,使用管理员权限进行设置。
1 | sudo mysql |
使用mysql库
1 | use mysql |
修改root用户名登录密码为root
1 | 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服务未启动,输入下面命令启动mysql
1 | 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 | mysql -u root -p |
更新user表,将root用户记录host改为’%',最后刷新权限
1 | update user set host ='%' where user='root'; |
以上设置完成后,就可以在我的开发环境(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 | cd /etc/nginx/sites-available |
修改default文件为如下配置,#代表注释:
1 | ## |
配置default完成后,进入/etc/nginx/sites-enabled路径,删除default,创建软链接
1 | $ pwd |
以下列出一些配置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 | [uwsgi] |
终端执行命令拉起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,其他在局域办公网内的计算机通过浏览器访问这个地址,就能刷新打开页面了。