Django实现自动发布(1数据模型)
公司成立之初,业务量较小,一个程序包揽了所有的业务逻辑,此时服务器数量少,上线简单,基本开发-测试-上线都是由开发人员完成。
随着业务量逐渐上升,功能增多,代码量增大,而单一功能上线需要重新编译整个程序,编译时间由原来的几秒到几分甚至几十分钟,一方面效率降低,另一方面横向扩容带来的处理性能提升效果逐渐减弱。所以由大一统拆分出各个子模块,将大而全的程序“微服务”化。
微服务的好处自然是不言而喻,但是许多个服务部署、变更也确实让人头疼。
如何解决这个问题呢?百度一下大把的服务治理、服务标准化、流程化,各种名词层出不穷,但就是没有一个具体的实现,对我这种新手真的很不友好。
所以结合具体公司业务,满足线上需求,实现了一套自动发布系统。
背景
我司开发人员完成新功能,测试通过后,再通过脚本上传程序包、启动进程以及一些其他的操作。
对于不是经常变更的业务来说,这么干确实没什么问题,但是我司已经拆出几百个微服务,部署在几百个主机上,而且这样的操作每天都要进行几十甚至上百次的时候,弊端就显现出来了:
- 编译打包本身耗时很长,再上传到服务器又是漫长的等待
- 发布时面对一堆零散的脚本,老司机虽然游刃有余,但是这些重复性的工作着实让人厌倦
- 突发状况需要回退时,又是一阵操作猛如虎
怎么办呢。。。
打包上传时间长?提前把程序包放在仓库,要用的时候直接拿行不行
一堆离散的脚本?老夫来接管脚本,提供一个统一的调用接口ok不
难回退?版本管理想用哪个版本就用哪个版本
为了实现版本管理和发布,我们需要记录服务的版本信息,服务发布实际上就是将对应的主机和服务的某个版本关联。
现有的主机管理是由前一位大佬搭建,技术栈是 Django 1.10.1 ,很老的版本了,为了快速实现功能就在此基础上开发吧。
说干就干,老夫写代码就是一把梭,ctrl+c、 ctrl+v 已是炉火纯青。
服务版本管理
一个服务会有很多个版本,如果用一张表来记录所有的信息,势必会有很多冗余的字段,所以拆分为服务、服务版本两张表,做外键关联。对应到 django 的 model 如下:
我司的代码由自建的gitlab管理,构建也是直接用了gitlab-ci,所以服务表里记录gitlab对应project的地址
from django.conf import settings
from django.db import models
class MicroService(models.Model):
LANGUAGE_TYPE = (
('cpp', 'cpp'),
('go', 'go'),
('python', 'python')
('other', 'other')
)
name = models.CharField(u'服务名称', max_length=64)
language = models.CharField(u'语言类型', max_length=16, choices=LANGUAGE_TYPE)
build_orig = models.CharField(u'构建来源', max_length=16, default='git')
build_url = models.CharField(u'构建地址', max_length=128) # gitlab or jenkins 的构建地址,用于触发构建任务
description = models.CharField(u'描述', max_length=256, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='created_by', on_delete=models.DO_NOTHING)
updated = models.DateTimeField(auto_now=True)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='updated_by', on_delete=models.DO_NOTHING)
class Meta:
db_table = 'micro_service'
unique_together = (('name', ), )
ordering = ['-created']
通过gitlab触发一个构建任务时,服务的某个版本的构建状态有预备、运行中、成功、失败、超时、重复构建,可以使用枚举来记录状态的变化;版本创建完成后不能修改,所以只有创建人和创建时间
from enum import Enum, unique
@unique
class BuildStatus(Enum):
pending = 0
building = 1
success = 2
timeout = 3
failed = 4
duplicate = 5
class MicroServiceVersion(models.Model):
BUILD_STATUS = tuple([(v.value, k) for k, v in BuildStatus.__members__.items()])
microservice = models.ForeignKey(MicroService, on_delete=models.DO_NOTHING)
version = models.CharField(u'版本', max_length=48) # 版本号格式: 时间戳-提交分支-提交id
description = models.CharField(u'描述', max_length=128, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
status = models.PositiveSmallIntegerField(choices=BUILD_STATUS,default=1)
file_path = models.FilePathField(u'程序包存放路径', max_length=128, null=True, blank=True)
ref = models.CharField(u'构建分支', max_length=128, default='master')
class Meta:
db_table = 'micro_service_version'
unique_together=(('microservice', 'version'),)
ordering = ['-created', 'version']
服务实例
服务发布实际上就是将主机和服务的某个版本关联:
- 部署,在实例表里创建一条主机、服务版本的关联记录
- 升级、回退,修改对应实例的版本
- 删除,删除相关数据
状态
当我们进行部署、升级、回退、删除等操作时,可能由于一些原因导致失败,所以用一个字段来记录实例的状态,方便进行后续的重试等操作。
锁定
假如 A用户 正在对 service_a 的实例进行升级操作,那么其他用户不能操作 service_a 的实例,可以将这些实例全部锁定,A用户的操作完成后再解除锁定
对应的 model :
from asset.models import Asset
@unique
class InstanceStatus(Enum):
running = 0 # 运行中 大部分时候处于此状态
installing = 1
upgrading = 2
reverting = 3
deleting = 4
install_failed = 11
upgrade_failed = 12
revert_failed = 13
delete_failed = 14
class MicroServiceInstance(models.Model):
STATUS = tuple([(v.value, k) for k, v in InstanceStatus.__members__.items()])
microservice = models.ForeignKey(MicroService, on_delete=models.DO_NOTHING)
version = models.ForeignKey(MicroServiceVersion, on_delete=models.DO_NOTHING)
host = models.ForeignKey(Asset, on_delete=models.DO_NOTHING)
port = models.IntegerField(u'端口号', null=True, blank=True, )
tag = models.CharField(u'标签', max_length=64, blank=True, null=True)
weight = models.PositiveSmallIntegerField(u'权重', default=100)
description = models.CharField(u'描述', max_length=128, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
status = models.PositiveSmallIntegerField(u'实例状态', choices=STATUS, default=0)
locked = models.BooleanField(u'操作锁定', default=False)
is_maintain = models.BooleanField(u'是否维护中', default=False) # 保留字段
class Meta:
db_table = 'micro_service_instance'
ordering = ['-created']
理清了服务、版本、实例的关系,建好了数据模型,接下来就是视图了。
Django实现自动发布(1数据模型)的更多相关文章
- Django实现自动发布(2视图-任务接收)
上一篇服务版本的新增,是通过触发 gitlab 任务来实现的,那么如何得到任务的最终状态呢? 好在 gitlab 为我们提供了webhook,也就是消息钩子,可以发送pipeline消息到我们指定的地 ...
- Django实现自动发布(2视图-服务管理)
通常页面要能对资源进行增删改查,对应http的 POST.DELETE.UPDATE.GET 页面显示使用了layui,而layui的表格有自己的数据获取方式,所以我们的视图要做一些调整,不使用后端渲 ...
- Django实现自动发布(3发布-升级和回退)
发布实际上就是将服务的某个版本和一台主机关联,我用一张表(MicroServiceInstance)记录了主机id.服务id.版本id,目前一台主机只能部署一个版本,所以主机id和服务id要做联合索引 ...
- Django实现自动发布(3发布-安装)
相对于服务的升级.回退,新部署一个服务要复杂一些,要满足以下要求: 已经运行了服务实例的主机不能重复部署 进程启动需要的配置文件要先同步到主机上 之前的升级.回退都是指进程的操作,不涉及配置文件的变更 ...
- Django实现自动发布(2视图-服务版本查找和新增)
前面做好了服务的管理,接下来是服务版本的管理,和服务类似,版本也有增删改查.先在服务的管理页面做一个入口,如下图: 需要在上一步的服务管理页面增加按钮.按钮方法,点击按钮跳转时要打开一个新的页面,所以 ...
- nginx+uWSGI+django+virtualenv+supervisor发布web服务器
nginx+uWSGI+django+virtualenv+supervisor发布web服务器 导论 WSGI是Web服务器网关接口.它是一个规范,描述了Web服务器如何与Web应用程序通信,以 ...
- eclipse项目自动发布到tomcat目录,缺文件。
eclipse项目自动发布到tomcat目录,缺文件. 解决方案: 项目--Properties-->Deployment Assembly-->Add--> Folder Add- ...
- php利用svn hooks将程序自动发布到测试环境
利用svn hooks将php程序自动发布到测试环境 复制仓库hooks目录下的post-commit.tmpl为post-commit cp post-commit.tmpl post-commit ...
- 一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)
一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp) 程序员的生活要一切自动化,更要幸福^_^. 转载请注明出处http: ...
随机推荐
- VsCode中编写python环境配置
1. VsCode中编写python环境配置 1.1. 前言 有过开发经验都知道idea一系列的软件虽然功能比较多,但比较容易卡,电脑不好还真容易上火,这里我想要入门python,还是选了款vscod ...
- Android中自定义水球
如图所示: 自定义属性: 在values下创建attrs.xml 文件 <?xml version="1.0" encoding="utf-8"?> ...
- Java集合学习(7):ArrayList
一.概述 ArrayList可以理解为动态数组,就是Array的复杂版本.与Java中的数组相比,它的容量能动态增长.ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包 ...
- CDA数据分析【第一章:数据分析概述】
一.数据分析行业发展 1.如何收集.保存.管理.分析.共享正在呈指数式增长的数据是我们必须要面对的一个重要挑战. 2.数据分析包括数据采集.数据存储.检查.清洗.分析.转换和建模等方法对数据进行处理的 ...
- 一步一步从PostgreSQL安装到delphi 访问
今天,我们使用ubuntu 19 来安装PostgreSQL. 1.直接使用包安装 sudo apt-get install postgresql 按Y,直接安装. 安装完毕. 初次安装后,默认生成一 ...
- 【Swagger2】解决swagger文档地址请求404的问题
一.出现的问题背景 某个项目,本地启动后,访问swagger文档地址可以访问到, http://localhost:8203/doc.html.但是部署到开发环境就访问不到,报404资源找不到的问题 ...
- Backbone——数据驱动UI的js开发模式
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826074.html 一:Backbone是什么——JS的MVC框架 Backbone基于undersco ...
- Vagrant+VirtualBox虚拟环境
Vagrant+VirtualBox虚拟环境 VagrantVirtualBox 软件安装 虚拟机基础配置 虚拟机创建 共享目录 配置网络 配置私有网络 配置公有网络 打包box与添加box 打包bo ...
- 如何将VOC XML文件转化成COCO数据格式
数据转换实在是个烦人的工作,被折磨了很久决定抽出时间整理一下,仅供参考. 在一个项目中,我需要将已有的VOC的xml标注文件转化成COCO的数据格式,为了方便理解,文章按如下顺序介绍: XML文件内容 ...
- Mysql insert on update
数据库 Mysql INSERT INTO table (column_list) VALUES (value_list) ON DUPLICATE KEY UPDATE c1 = v1, c2 = ...