1. 部署服务
针对应用,python有一套完善的项目部署方案,从打包到环境隔离,再到监控,一应俱全.如果没有特殊需求,完全可以跳过容器直接使用.当然了如果运维希望使用docker这类容器部署以限制各个项目的资源使用量时,得益于zipapp
和pip
,python也同样简单易于部署.
1.1. 打包与分发
python应用其实并不一定需要打包就可以分发部署,但即便如此python也有多样的打包分发方案,比较主流的有:
- egg
- zipapp
- pyinstaller
我们以一个简单的sanic例子作为要打包的内容,这个例子代码在项目TutorialForPython/python-tool-chain中,其结构为:
testapp\ |--__main__.py |--app\ |--__init__.py |--api\ |--__init__.py |--core.py |--index.py
__main__.py
from app import main if __name__ == "__main__": main()
app/__init__.py
from sanic import Sanic from .api import restapi def main(): app = Sanic() restapi.init_app(app) app.run()
app/api/__init__.py
from .core import restapi from .index import *
app/api/core.py
from sanic import Blueprint from sanic.views import HTTPMethodView class APIView: def __init__(self, name='restapi', url_prefix="/api", app=None): self.restapi = Blueprint(name, url_prefix=url_prefix) if app: self.init_app(app) def register(self, url): def wrap(clz): if not issubclass(clz, HTTPMethodView): raise AttributeError("must HTTPMethodView's subclass") self.restapi.add_route(clz.as_view(), url) return clz return wrap def init_app(self, app): app.blueprint(self.restapi) restapi = APIView() __all__ = ["restapi", "APIView"]
app/api/index.py
from sanic.response import json from sanic.views import HTTPMethodView from .core import restapi @restapi.register("/") class IndexAPI(HTTPMethodView): async def get(self, request): result = { "description": "测试api" } return json(result,ensure_ascii=False) __all__ = ["IndexAPI"]
1.1.1. 不打包
python实际上在2.5版本就已经支持直接执行内含__main__.py
的文件夹了,实际上后面的zipapp和egg都是由这个特性来的.因此直接拿这个文件夹发布也是可以的.
执行:
python testapp
1.1.2. zipapp打包
python3.5提供了一种打包分发的方式--zipapp
(PEP 441).它可以将写好的项目打包成.pyz
文件,这样就可以简单的将项目四处分发了.注意,这种方式最好是打包纯python代码,这样不容易因为平台不同而出现无法使用的情况.如果有c扩展,那么最好单独抽出来写成模块利用pip单独安装.
.pyz
文件并不能独立运行,依然依赖python环境.因此如果不用docker
打包的话最好使用虚拟环境让项目在虚拟环境中运行.
zipapp
的用法如下:
python -m zipapp myapp -m "myapp:main"
myapp
是一个项目文件夹,并非模块,我们使用-m
指定使用其中的哪个模块的哪个方法作为入口
同时也可以使用-p
指定一个字符串作为Shebang
python -m zipapp myapp -m "myapp:main" -p "/user/bin/env python3"
zipapp
本质是一个用zip打包项目的工具,它的定位其实是简化版jar
.一个打包好的二进制文件远比文件夹好分发使用.这也是go语言的核心竞争力之一.现在python有了这样一个工具,虽然使用起来还是要配合虚拟机和pip包管理工具,但已经很够用了.
对上面的项目打包可以如下:
python -m zipapp testapp
执行:
from app import main if __name__ == "__main__": main()
0
1.1.3. egg打包
egg本质上也还是一个zip包,但要打包为egg需要写一个setup.py
testapp/setup.py
from app import main if __name__ == "__main__": main()
1
然后执行命令python setup.py bdist_egg
就可以打包一个egg文件,默认位置在testapp/dist/testapp-<version>-py<pyversion>.egg
执行:
from app import main if __name__ == "__main__": main()
2
1.1.4. pyinstaller
上面3种方式都需要依赖环境,当运行环境中有依赖没有安装或者由依赖冲突就无法执行,这就需要使用后面提到的'虚拟环境'.另一个跨平台的打包工具pyinstaller可以将环境一并打包到一起,但它并不能交叉编译所以需要每个平台打包一次然后分发,这也已经是很方便了.
针对上面这个项目我们在testapp
文件夹下使用如下命令:
from app import main if __name__ == "__main__": main()
3
其中-c
是编译为命令行工具,-F
是编译为单文件,--name
用于指定编译完成后的可执行文件名,最后一个参数则是指定入口文件.
pyinstaller会递归的寻找依赖,并将依赖包括python环境一并打包,编译出一个单独的可执行文件,默认在testapp/dist/testapp
.
执行:
from app import main if __name__ == "__main__": main()
4
1.2. 使用虚拟环境部署
项目部署运行时不可能通过常规手段激活虚拟环境.而事实上也不需要,其实要使用虚拟环境只要指定好用虚拟环境的python解释器运行项目了.比如有个虚拟环境建在~/VENV
文件夹.那么就可以直接使用这个文件夹下的python解释器直接使用.
~/VENV/bin/python myapp.pyz
1.3. *批量部署
python的运维神器fabric,用它可以实现对远程服务器的批量部署操作
一些使用方法和心得可以看我的博客
1.4. *服务监控
python的另一运维神器supervisor,配合cesi可以很好的监控管理项目进程.具体的可以看我的这篇博文
from app import main if __name__ == "__main__": main()
5
还没有评论,来说两句吧...