前言:
今天你们对“python启动服务”大致比较注意,兄弟们都需要分析一些“python启动服务”的相关文章。那么小编也在网摘上搜集了一些有关“python启动服务””的相关内容,希望我们能喜欢,同学们快快来了解一下吧!基本概念
解释器和系统组件
系统安装的Python或者使用的miniconda, anaconda都是Python解释器,用以解释执行Python程序。
一般Python安装完毕,会自带基本的组件,比方sys、os和threading等等,使用这些组件我们不需要从头去实现功能。一般这些组件也是跨平台的,方便开发使用。
第三方组件
程序经常需要去连接数据库或者MQ中间件,Python和其他语言一样,有非常方便的组件例如rabbitmq或者mysql-connector-python
解释器安装第三方组件之后,第三方组件的程序代码会存放在解释器制定的目录下
程序代码和资源文件
程序代码就是Python的代码或者编译之后的程序。
资源文件比较多,一般大致有如下几类
类型
名称
说明
配置文件
环境配置
随着部署环境和服务器的变化,需要修改的配置,例如IP、端口和密码之类的
项目配置
如果是平台类产品,会有大量的公共代码,对应不同的项目可以发布项目配置来适配不同的项目。
该类配置在对应项目的版本发布之前需要配套发布,不随部署环境的改变而变化。
模型文件
权重文件
算法的权重文件,标识AI的网络权重参数
模型配置
一般随权重一起发布,采用ini配置,说明模型类型以及通用处理参数
其他文件
模板文件
程序处理预置的一些模板文件,例如二进制色卡,word报告的模板,一般版本发布随代码一起发布(现在一般和代码放到同一个目录下)
混合编程so
其他语言实现的so,Python会去调用,一般编译好了之后和Python代码放到同一个目录下
supervisor
supervisor是常用的一个服务管理程序,可以配置Python的环境,自启动和守候服务
virtualenv
虚拟环境,当python解释器版本有差别,或者第三方组件有多版本时,可以按照需要在当前解释器基础上扩展虚拟版本。
系统服务
一般linux程序注册到后台服务,这样系统开机或者重启之后,程序能够自动启动。
Python程序执行和环境变量
对于Python程序来说,环境变量包括两大类,第一个是PYTHONPATH,第二类是其他环境变量,其他环境变量通过程序带来来解析和处理,属于业务层面的东西,不再赘述。
PYTHONPATH是Python解释器引用包的时候自动搜索的路径,当我们使用模块启动方式的时候可以按照目录成绩,使用.隔开来启动,例如python3 -m test.run_here
部署说明
部署架构
基于supervisor的管理,将supervisord注册到系统服务中,各个服务的管理通过supervisor来处理。
supervisor可以为服务配置不同的解释器,例如Python3.7和Python3.6,如果有不同组件冲突,可以使用virtualenv创建分支,例如下图的pyocr
对于不同的程序版本,supervisor也可以指定程序目录到具体服务。
统一程序版本
如果只有一个代码版本,supervisor支持统一的代码版本配置,一般在公共supervisord.conf配置文件中指定,如下将%(here)s/../your_project作为默认的代码路径,里面的所有python包可以直接引用。
%(here)s是配置文件本地路径,一般发布版本可以固定miniconda, python程序和supervisord.conf路径,使用相对路径可以将miniconda,python程序,supervisor启动和服务配置一起打包,与docker类似,可以放置到任意路径,启动supervisord就行
[supervisord]environment=PYTHONPATH="$PYTHONPATH:%(here)s/../your_project:%(here)s/../your_project/code_django:%(here)s/..服务配置程序版本
如果服务会使用独有的代码版本,需要在服务中environment指定程序路径
服务配置解释器(包括虚拟环境对应不同的组件包)
可以配置不同解释器
服务配置参数和路径
一种可以配置环境变量,在程序中去解析; 另外一种通过命令参数传递到程序解析。
典型配置
服务注册,解释器等路径配置如下红框部分,这个如果发布包目录变更,需要修改(对于发布程序,需要注意的仅此一点)
supervisord配置,主要是公共环境配置,守候日志配置等
服务配置,包括环境,服务命令,守候配置(自启动守候,异常重启守候,启动尝试次数,启动用户,日志配置等)
;sam服务[program:sam];environment=PYTHON_APP_CONF= %(here)s/common, PYTHON_APP_DEBUG=falsecommand=%(here)s/../pysam/bin/python -m service.sam.run_rest_samautostart=trueautorestart=truestopasgroup=truekillasgroup=truestartretries=99999priority=10user=rootredirect_stderr=truestdout_logfile=%(here)s/../log/%(program_name)s.stdstdout_logfile_maxbytes=10MBstdout_logfile_backups=10目录约束和发布边界
智能机经过几年的部署摸索,按照前面的部署架构,已主解释器为主目录,例如miniconda,一般将程序配置都放到该目录下,生成一个统一的版本包。
如下图,bin目录是解释器程序python3和supervisorctl所在目录;your_project开头的目录放置编译后的程序代码,可以多版本存放: etc中存放服务配置和环境配置(环境配置可以从配置中心获取)等。
etc进行约定之后,里面的服务配置就可以使用相对路径,这样miniconda整个包可以作为一个容器,随意更换目录或者名称。例如
envs里面一般放其他版本解释器,或者虚拟环境建立带其他第三方组件的版本的解释器。
FAQ
使用多版本Python解释器的最佳实践?
很多教程一上来喜欢将python执行程序所在目录注册到系统环境里面,这样就污染了系统环境。 使用miniconda,不建议注册系统环境。
生产或者测试环境,建议使用绝对路径或者相对路径来调用解释器,而不是直接使用Python3,这样就和docker一样,多个Python解释器版本之间不会相互影响。
为什么不打包独立so和解释器分离?
Python是动态语言,有很多自省等高阶特性,比方__file__,pydantic中的Any类型等等,都不支持直接打包成so,程序打包也需要注意代码和资源文件的组织,产生很多约束,这样就失去了Python的灵活性。
Python使用的一些大组件比方cv2,torch打包也比较困难,容易出错。暂时没有必要花费这么大代价来做这个事情。
当然可以持续跟进打包组件对这些特性的支持情况,这些问题解决了。
为什么没有使用docker?
参考前面的架构,如果有miniconda和pyocr两个解释器版本, 程序有v1,v2两个版本,服务1,2,3;
如果服务3需要升级v3版本,只需要上传v3程序,修改服务3的配置指向v3版本即可。
如果服务1需要升级解释器版本pytest,只需要新建pytest,修改服务1的配置指向pytest解释器即可
如果新增服务11,对应miniconda解释器和v4版本,只需要上传v4版本程序,新建服务11,指向miniconda和v4
docker需要将解释器、程序和服务配置全部打到镜像中,打包时间长,启动和配置比supervisor还复杂。
supervisor的使用要求python解释器和代码等等都不注册到系统环境中,各个服务在启动的时候才初始化环境,服务之间隔离相互不影响,对于Python服务和程序来说和docker效果一样,所以没使用docker。如果使用docker,docker内部也是按照miniconda+supervisor+程序的模式来构建。
使用docker的场景?
在一台物理机上,Python的解释器可以多版本共存,第三方组件版本也可以使用virtualenv虚拟化方案来解决多版本共存问题,所以标准的Python程序本身就支持多版本的,但是目前基于NVIDIA的AI框架大部分都会使用到CUDA,cuda的多版本共存必须使用docker,而且cuda无法做到像miniconda一样绿色移植,所以涉及到CUDA部分,可以采用docker方式来搭建AI的软件和驱动环境。
按照AI的经验, cuda+cudnn软件环境打包到docker即可,解释器、程序代码和模型都可以在物理机磁盘上映射到docker,该方式镜像维护和升级都会方便很多。
#首发创作赛#