🍺基于Python的Web服务器系列相关文章编写如下🍺:
- 🎈【Web开发】Python实现Web服务器(Flask快速入门)🎈
- 🎈【Web开发】Python实现Web服务器(Flask案例测试)🎈
- 🎈【Web开发】Python实现Web服务器(Flask部署上线)🎈
- 🎈【Web开发】Python实现Web服务器(Tornado入门)🎈
- 🎈【Web开发】Python实现Web服务器(Tornado+flask+nginx)🎈
- 🎈【Web开发】Python实现Web服务器(FastAPI)🎈
- 🎈【Web开发】Python实现Web服务器(Bottle)🎈
- 🎈【Web开发】Python实现Web服务器(Django)🎈
- 🎈【Web开发】Python实现Web服务器(web2py)🎈
- 🎈【Web开发】Python实现Web服务器(Sanic)🎈
文章目录
- 1、简介
- 2、虚拟环境virtualenv
-
- 2.1 virtualenv
- 2.2 virtualenvwrapper
- 3、更换WSGI容器
-
- 3.1 waitress
- 3.2 gevent
- 3.3 Gunicorn
- 3.4 uWsgi
- 3.5 Twisted Web
- 3.6 Tornado+nginx
- 3.7 apache+mod_wsgi
- 4、打包工具PyInstaller
-
- 4.1 requirements.txt
- 4.2 安装
- 4.3 参数
- 4.4 示例
- 5、注册Windows服务
-
- 5.1 pyinstaller + nssm
- 5.2 pywin32
- 6、whl文件制作
-
- 6.1 安装
- 6.2 示例
- 结语
1、简介
Web 程序通常有两种部署方式:传统部署和云部署。传统部署指的是在使用物理主机或虚拟主机上部署程序,你通常需要在一个 Linux 系统上完成所有的部署操作;云部署则是使用其他公司提供的云平台,这些平台为你设置好了底层服务,包括 Web 服务器、数据库等等,你只需要上传代码并进行一些简单设置即可完成部署。
2、虚拟环境virtualenv
2.1 virtualenv
- 安装virtualenv:
pip install virtualenv
创建一个虚拟环境,暂且取名为 new_env:
virtualenv new_env
在 Windows 系统上面使用 virtualenv:
首先进入到虚拟环境目录中的 Scripts 目录:
cd new_envScripts
activate
在 Linux 上使用 virtualenv Linux 上面进入虚拟环境的方式跟 Windows 稍微有点不同,可以直接使用命令来进入,比如同样在 Linux 上面的 envs 文件夹下面有个 new_env 虚拟环境,则直接输入以下命令就可以进入虚拟环境:
source new_env/bin/activate
进入了虚拟环境之后,Windows 和 Linux 上面的操作都是一样的,这里就不单独去说明了。
2.2 virtualenvwrapper
virtualenvwrapper 是一个 virtualenv 虚拟环境的管理库,这个库可以更加方便的管理所有的虚拟环境,由于在 Windows 和 Linux 上面这个库的安装和配置不同,所以要单独做说明。
- Windows 上安装virtualenvwrapper环境
Windows 上需要安装的是virtualenvwrapper-win,直接使用pip命令就可以了:
pip install virtualenvwrapper-win
配置虚拟环境的保存路径。首先需要在想要统一存放虚拟环境的地方创建一个文件夹(我在F盘建立了D:test_env),然后把这个文件夹添加到系统的环境变量中。如果不设置系统环境变量,那么创建的虚拟环境会保存到默认的地方,不方便管理.
- Linux 上安装virtualenvwrapper环境
pip3 install virtualenvwrapper
配置环境变量文件。首先修改(文件不存在就创建)文件~/.bashrc,然后添加如下语句:
export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/workspace
source /usr/local/bin/virtualenvwrapper.sh
然后运行:
source ~/.bashrc
which python3
- virtualenvwrapper 命令:
创建虚拟环境:mkvirtualenv new_env
使用虚拟环境:workon new_env
退出虚拟环境:deactivate
删除虚拟环境: rmvirtualenv new_env
查看所有虚拟环境:lsvirtualenv
- 在使用命令workon任意目录使用虚拟环境
先使用workon查看所有的虚拟环境
在workon 名称 切入该虚拟环境
mkvirtualenv flask_env
workon
workon flask_env
pip install -r requirements.txt
deactivate
#生成文件
pip freeze >F:A_FILErequirements.txt
#复制环境
pip install -r requirements.txt
3、更换WSGI容器
-
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
虽然 Flask 提供了内置 Web 服务器,但是那种服务器是为开发打造的,达不到生产环境中需要的安全和效率,细心的同学会注意到,用 app.run() 或者 flask run 启动应用时,都会得到一句警告:Do not use the development server in a production environment.
那么在生产环境中,需要用生产专用 Web 服务器,比如 uWSGI、Gunicorn、Gevent 等等。
独立的WSGI容器:有很多流行的服务器用Python编写,它们包含WSGI应用程序并提供HTTP服务。
Web框架(Flask)和Web服务器(Nginx)之间的通信,需要一套双方都遵守的接口协议。而WSGI协议就是用来统一这两者的接口的(WSGI是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口)
3.1 waitress
安装waitress
Flask服务本身并不支持并发测试,本身的TPS很低,所以需要利用其他工具来支持并发测试。
waitress是Windows下基于python的一个框架,可以提高Flask的TPS。
waitress支持windows环境
Waitress是一个具备生产级品质并有高性能的纯python编写独立的WSGI服务器,它只依赖python标准库,不依赖任何第三方库。 同时它可以在多平台下运行,比如windows、linux、unix等,支持http/1.0和http/1.1。
pip install waitress
from waitress import serve
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World,爱看书的小沐!'
if __name__ == '__main__':
# app.run()
# app.run(host="127.0.0.1", port="8080")
# app.run(host='localhost', port=8080, threaded=False, processes=1)
serve(app, host='0.0.0.0', port=8080)
waitress-serve --call 'flaskr:create_app'
## Serving on http://0.0.0.0:8080
3.2 gevent
https://pypi.org/project/gevent/
http://www.gevent.org/
https://github.com/gevent/gevent
gevent is a coroutine -based Python networking library that uses greenlet to provide a high-level synchronous API on top of the libev or libuv event loop.
安装gevent:
flask直接用于生产环境无论是处理高并发还是鲁棒性都有所欠缺,一般会配合WGSI容器来进行生产环境的部署。WSGI主要规定了Web服务器如何与Web应用程序进行通信,以及如何将Web应用程序链接在一起来处理一个请求。
gevent支持windows环境
gevent是一个基于 libev的并发库。它为各种并发和网络相关的任务提供了整洁的API。
gevent:基于 libev 与 Greenlet 实现。不同于 Eventlet 的用 python 实现的 hub 调度,gevent通过 Cython 调用 libev 来实现一个高效的 event loop 调度循环。同时类似于 Event,gevent也有自己的 monkey_patch,在打了补丁后,完全可以使用 python 线程的方式来无感知的使用协程,减少了开发成本。
pip install gevent
from gevent.pywsgi import WSGIServer
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World,爱看书的小沐!'
if __name__ == '__main__':
# app.run()
# app.run(host="127.0.0.1", port="8080")
# app.run(host='localhost', port=8080, threaded=False, processes=1)
# serve(app, host='127.0.0.1', port=80, threads=1)
# serve(app, host='0.0.0.0', port=8080)
WSGIServer(('127.0.0.1', 8080), app).serve_forever()
引入gevent WSGI Server ,这里需要开启猴子补丁。而且需要注意 把gevent 猴子补丁 有关gevent的引入放在导入其他库的前面。
# gevent
from gevent import monkey
from gevent.pywsgi import WSGIServer
# 有人说添加了如下这一句就不阻塞请求
monkey.patch_all()
# gevent end
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
# 测试阻塞url1时,url2是否能够访问
time.sleep(3000)
return 'Hello World1'
@app.route('/hello')
def hello():
return 'Hello World2'
if __name__ == '__main__':
# app.run(port=5000,host="127.0.0.1")
http_server = WSGIServer(('127.0.0.1', int(5000)), app)
http_server.serve_forever()
3.3 Gunicorn
https://gunicorn.org
https://github.com/benoitc/gunicorn
Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP Server for UNIX. It’s a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.
Gunicorn和uWSGI是常用的WSGI容器,Gunicorn直接用命令启动,不需要编写配置文件,相对uWSGI要容易很多。
Gunicorn ‘Green Unicorn’ 是一个 UNIX 下的 WSGI HTTP 服务器,它是一个 移植自 Ruby 的 Unicorn 项目的 pre-fork worker 模型。它既支持 eventlet , 也支持 greenlet.
Gunicorn是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。
和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。
Gunicorn 是一个 Python 的 WSGI HTTP 服务器。它所在的位置通常是在反向代理(如 Nginx)或者 负载均衡(如 AWS ELB)和一个 web 应用(比如 Django 或者 Flask)之间。
目前Gunicorn只能运行在Linux环境中,不支持windows平台。
pip install flask
pip install gunicorn
pip show gunicorn
#创建软连接哦
ln /usr/local/python3.7/bin/gunicorn /usr/bin/gunicorn
# 在hello.py所在的目录下
# -w 设置进程数
# -b 设置端口
# 默认使用的是8000 可以通过-b 127.0.0.1:5000 设置到5000或其他端口
gunicorn -w 4 hello:app
gunicorn -w 5 --threads=2 main:app
gunicorn -w 5 --thread=2 --worker-class=gthread main:app
gunicorn --worker-class=gevent --worker-connections=1000 -w 3 main:app
gunicorn -w 4 demo:app --worker-class sync
gunicorn -w 4 demo:app -k sync
##第一种并发方式(workers 模式,又名 UNIX 进程模式)
#每个 worker 都是一个加载 Python 应用程序的 UNIX 进程。worker 之间没有共享内存。
#建议的 workers 数量是 (2*CPU)+1。
#对于一个双核(两个CPU)机器,5 就是建议的 worker 数量。
gunicorn --workers=5 main:app
##第二种并发方式(多线程)
#Gunicorn 还允许每个 worker 拥有多个线程。在这种场景下,Python 应用程序每个 worker 都会加载一次,同一个 worker 生成的每个线程共享相同的内存空间。
gunicorn --workers=5 --threads=2 main:app
or
gunicorn --workers=5 --threads=2 --worker-class=gthread main:app
#使用四核(4 个 CPU)机器并且我们想使用 workers 和多线程模式,我们可以使用 3 个 worker 和 3 个线程来得到最大为 9 的并发请求数量。
gunicorn --workers=3 --threads=3 main:app
##第三种并发方式(“伪线程”)
#有一些 Python 库比如(gevent 和 Asyncio)可以在 Python 中启用多并发。那是基于协程实现的“伪线程”。Gunicrn 允许通过设置对应的 worker 类来使用这些异步 Python 库。
#(2*CPU)+1 仍然是建议的workers 数量。因为我们仅有一核,我们将会使用 3 个worker。
#在这种情况下,最大的并发请求数量是 3000。(3 个 worker * 1000 个连接/worker)
gunicorn --worker-class=gevent --worker-connections=1000 --workers=3 main:app
并发是指同时执行 2 个或更多任务,这可能意味着其中只有一个正在处理,而其他的处于暂停状态。
并行是指两个或多个任务正在同时执行。
在 Python 中,线程和伪线程都是并发的一种方式,但并不是并行的。但是 workers 是一系列基于并发或者并行的方式。
gunicorn + flask 简单示例
- mytest.py:
from flask import Flask
app = Flask(__name__)
@app.route('/demo', methods=['GET'])
def demo():
return "This is a gunicorn and flask demo."
gunicorn mytest:app
#or
gunicorn --workers=2 mytest:app
#or
gunicorn --workers=4 --bind=127.0.0.1:8000 mytest:app
3.4 uWsgi
uWSGI 也是部署 Flask 的途径之一,类似的部署途径还有 nginx 、 lighttpd 和 cherokee 。其他部署途径的信息参见 FastCGI 和 独立 WSGI 容器 。 使用 uWSGI 协议来部署 WSGI 应用的先决条件是需要一个 uWSGI 服务器。 uWSGI 既是一个协议也是一个服务器。如果作为一个服务器,它可以服务于 uWSGI 、 FastCGI 和 HTTP 协议。
uWSGI是一个全功能的HTTP服务器,实现了WSGI协议、uwsgi协议、http协议等。它要做的就是把HTTP协议转化成语言支持的网络协议。比如把HTTP协议转化成WSGI协议,让Python可以直接使用。
最流行的 uWSGI 服务器是 uwsgi。
有网友说Windows 10安装uWSGI不可行,不要浪费时间。
pip install uwsgi
启动:uwsgi --ini uwsgi.ini
重启:uwsgi --reload uwsgi.pid
停止:uwsgi --stop uwsgi.pid
uwsgi --version
uwsgi --python-versioin
uwsgi --http :9090 --wsgi-file run.py
# --http: 通过 http 可访问,绑定端口为 9090
# --wsgi-file:指定启动脚本
#创建的文件名是 start.ini
[uwsgi]
#uwsgi启动时,所使用的地址和端口(这个是http协议的)
http=0.0.0.0:8000
#指向网站目录
chdir=/Users/myProjects/test001
#python 启动程序文件
wsgi-file=app.py
#python 程序内用以启动的application 变量名
callable=app
#处理器数
processes=4
#线程数
threads=2
#直接命令行启动项目
uwsgi --ini start.ini
#如果你执行了 ctrl + c 命令退出了命令行,会发现我们的项目访问不到了,因为你退出了前台运行的 uwsgi 命令。
#想要退出当前命令行,去执行其他命令,而 flask 应用可以正常访问,只需要多加一个参数 -d 即可,如下:
uwsgi -d --ini start.ini
#mac、Linux下首先查看 uwsgi 的进行号
ps -ef|grep uwsgi
3.5 Twisted Web
Twisted Web 是一个 Twisted 自带的网络服务器,是一个成熟的、异步的、 事件驱动的网络库。 Twisted Web 带有一个标准的 WSGI 容器,该容器可以使用 twistd 工具运行命令行来控制。
Twisted Web支持windows环境部署
pip install -i https://pypi.douban.com/simple/ twisted
- flask_web.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World'
if __name__ == '__main__':
app.run()
通过命令行执行:
twistd -n web --wsgi flask_web.app
或者通过bat文件执行:
- flask_run.bat
set PYTHONPATH=.;venv/Lib;venv/Lib/site-packages
set PATH=%PATH%;venv/Scripts
twistd -n web --port tcp:8080 --wsgi run.app
3.6 Tornado+nginx
【Web开发】Python实现Web服务器(Tornado+flask+nginx)
https://blog.csdn.net/hhy321/article/details/125233806
Tornado+nginx支持windows环境部署
3.7 apache+mod_wsgi
首先需要安装apache和mod_wsgi,需要注意的是python版本,apache版本,mod_wsgi版本要匹配,不然会出问题。
apache+mod_wsgi支持windows环境部署
Apache下载网址:https://www.apachelounge.com/download/VC10/
https://www.apachehaus.com/downloads/httpd-2.4.54-o111s-x64-vs17.zip
https://www.apachelounge.com/download/VC10/binaries/httpd-2.4.23-win64.zip
mod-wsgi下载网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#mod_wsgi
将下载好的httpd和mod-wsgi压缩包解压,然后将mod-wsgi的pyd文件放在httpd的modules文件夹里,如下图所示。
新建测试项目文件夹test,在里面新建test_flask.py。
- test_flask.py
import json
from flask import Flask, request, jsonify,render_template
app = Flask(__name__)
tasks = [
{
'id': 1,
'title': u'订阅 a 专栏',
'description': u'专栏Link: https://www.a.com'
},
{
'id': 2,
'title': u'订阅 b 专栏',
'description': u'专栏Link: https://www.b.com'
}
]
@app.route('/test')
def hello_world():
return 'Hello World,爱看书的小沐!'
@app.route("/")
def index():
# return render_template("index.html")
return jsonify({'tasks': 200})
@app.route('/api/v1.0/tasks', methods=['GET'])
def get_tasks():
return jsonify({'tasks': tasks})
@app.route('/getdata')
def get_data():
language = ['python', 'java', 'c', 'c++', 'c#', 'php']
value = ['100', '150', '100', '90', '80', '90']
return json.dumps({'language':language,'value':value},ensure_ascii=False)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8080)
在项目文件夹test里,新建文件myapp.wsgi
- myapp.wsgi
修改apache httpd的相关参数设置。
httpd.conf文件增加一行:
LoadModule wsgi_module modules/mod_wsgi.cp38-win_amd64.pyd
修改一下httpd.conf的第40行的SRVROOT的参数,不修改的话,运行可能报错:
httpd.conf文件的最后面增加一段代码如下:
VirtualHost *:80>
ServerAdmin "127.0.0.1"
ServerName localhost:80
DocumentRoot D: 627test
Directory D: