Django 企业级研发开发过程中的隔离方案(经验之谈)
开发人员目前遇到的问题
公司目前在使用django-rest-framework构建产品的API平台,这样在后续前端业务迭代过程中就会方便很多。但是随之而来的问题是当有多个人进行开发后台平台的时候,由于之前的产品设计中各组件的解耦不够彻底,导致作为API平台的django层无法顺利的运行在开发机器中,于是需要重新设计整个开发的过程,帮助开发人员在配置环境,提交代码中很顺利的调试,测试自己所写的代码有效的降低代码出现bug的几率。
使用多层继承的方式进行配置隔离
原先的django项目中我们使用的是 proj/settings.py
进行项目的配置,后续因为牵扯的组件太多,导致配置文件一度达到几百行,虽说很多配置项都是固定的,在后续开发、部署中都不需要牵扯太多的精力在其中,但是过多、过长的配置文件仍然对我们梳理开发环境构成了一定的问题。后续面对散乱的配置项,无论是想修改什么多会令人头大,稍有不慎肯定会对已经稳定运行的代码构成风险,造成难以发现的bug。
后续为了避免这样的问题出现,我们将配置项拆分成了如下结构
proj/
|--settings/
|-- __init__.py
|-- base.py # django自身配置项
|-- celerys.py # django集成的celery的配置项
|-- context.py # 影响全局上下文的组件对接配置项
|-- defines.py # 定义的全局静态配置项
构建了上述的这种结构,我们就可以在后续修改中有效的管理起我们的配置项。按照每一层的结构说明,我们归纳好我们的现有配置项,然后逐层引用,这样最终在__init__.py
文件中只需要引用 defines.py
中的所有配置项就可以起到跟之前的一样的效果,并且不影响我们之前的代码使用,已有代码中针对settings的引用依旧生效不会影响使用。
使用django-environ做环境隔离
当拆分开我们的项目中的配置项之后,我们需要修改的就是针对于不同的环境中所用到的环境配置不同的问题。
举个简单的例子,目前这个阶段公司的项目中很多地方在生成路径时都使用了配置中的绝对路径,这样在后续过程中会导致我们在进行开发时无法在自己的开发环境中运行前端项目,必须手工的在系统中创建对应的路径。这种情况针对开发者本身是十分不友好的,如果我们有后续进入开发团队的伙伴,进行开发,需要很长的周期才能进入正式的功能性开发,其中配置环境就将占用大部分的时间。
此外上述的例子是说的当我们面对项目可以单独运行的时候,但是代码较为死板的情况。更可怕的是我们公司目前的项目无法单独的进行运行,必须依赖其他的项目接口和很多基础环境,这样在开发人员进行开发的时候则必须进入一个完整的开发平台,部署完整的真实环境。这种情况是一定不可接受的,因为我们在开发中必然会遇到冲突、覆盖的问题,最终导致开发的过程十分不顺利,这种情况必须做到环境的隔离。
后续为了进一步避免这样的问题出现,我们将配置项中针对于环境的设置进一步拆分了如下结构
使用django-environ进行环境隔离的时候,开发目录如下
proj/
|--.environ/
|--.env.release # 针对于发布环境
|--.env.develop # 针对于开发环境
|--.env.testing # 针对于测试环境
|--settings/
|-- __init__.py
|-- base.py
|-- celerys.py
|-- context.py
|-- defines.py
并将通过这个组件对base.py中的环境引用使用了全新的方式
env = environ.Env(
DEBUG=(bool, False),
SECRET_KEY=str,
BASE_HOST=str,
DATABASE_NAME=str,
DATABASE_USER=str,
DATABASE_PASS=str,
STORAGE_PATH_PREFIX=str,
OEM_CONFIG_PATH=str
)
env.read_env(env_file=os.path.join(BASE_DIR, 'web', '.environ', '.env.%s' % env.str('PROJECT_ENV', 'release')))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG')
其中引入了一个 PROJECT_ENV 作为系统环境变量,这样就可以在启动django服务的时候通过修改全局的变量环境构成 针对不同的环境所打造代码运行环境
这样在后续的开发中我们将直面的一些环境问题也能够做好处理
开发基础虚拟环境的服务隔离
此前公司中一直是分配真实开发机器给前端作为开发机器,这种情况下多个人在同一台开发机中容易造成拥堵,无法进行有效的并行开发,后续急需通过其他方式进行修改,将大家的开发环境进行有效的隔离,然后将数据方面进行有效的控制管理。
我们曾尝试过使用PVE作为我们公司内部的开发环境进行开发隔离处理,但是后续因为每个人都需要进行部署整套产品服务,造成很大程度上资源的不必要的浪费(单独产品必须64G才能运行,其中基础服务组件就占去了将近三分之二的资源)
后续为了彻底改善开发的基础环境问题我们将开发环境拆分成了如下配置
通过有效的将组件的解耦和合理拆分,我们将构建专门的一台流量拆分的机器,这台机器中将部属公司内部的流量机器,它将部署流量检测组件,通过自己给自己回放流量,将最终的数据输出到基础环境中;然后基础环境中部署公司的数据库组件等一系列其他的基础组件,并将接口暴露出来;然后分配两台独立的开发机器,将机器中的接口配置都引导向基础环境中,这样在产品内部的开发者将有效的通过任务的隔离选择合适的开发环境进行开发。