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() 01.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() 21.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() 41.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


 
		 
		 
		

还没有评论,来说两句吧...