软件开发管理规范

1 容器化规范

在应用的容器化改造规范中,需要考虑的主要因素有:容器的高可用性、容器的运维、容器的安全性、容器的多租户隔离、容器的持久化存储等,容器化的过程中需要符合以下规范和要求:
(一) 建立清晰的可自动化编译和构建过程
使用Maven、Gradle、Make、Shell等工具实现编译步骤自动化
(二) 实现应用配置参数的外部化
基于环境变量或者配置文件的配置管理,便于容器适配不同的运行环境
(三) 提供合理可靠的健康检查接口
平台将通过健康检查判断容器状态,对应用服务进行状态保持
(四) 实现应用状态外部化,应用实例无状态化
应用状态信息存储于数据库或缓存等外部系统,实例实现无状态化
(五) 不涉及底层操作系统依赖及复杂的网络通讯机制
应用以处理业务为主,不强依赖于底层操作系统以及组播等网络通信机制以提高可移植性
(六) 部署交付件及运行平台的大小在2G以内
轻量级的应用便于在大规模集群中快速传输分发,更符合容器敏捷的理念
(七) 启动时间在5min以内
过长的启动时间不能发挥容器敏捷的特性

2 代码管理规范

代码管理我们使用git进行,git是一种较为先进的代码版本管理及协同工作平台,采用分布式文件块存储:
分布式:代码保存在所有协同成员的计算机上,网速较差时依然可用;而传统的集中式代码版本管理系统则较难脱离网络运行。
文件:直接以文件保存整个最新文档,版本提交及恢复速度快:而传统的增量式代码版本管理系统则在每次提交及恢复时都需要对所有的增量进行求和,速度慢。

2.1 git常用概念

(一) 仓库(Repositories)
类似我们生活中的仓库,存储东西,在这是网络或者本地实际存放代码的地方,同一个仓库可存多个项目。
(二) 参照(References)
可以看做是指向文件块中特定代码版本的指针,可沿代码版本有向图进行向前(一般指提交操作Commit),向后(一般是恢复操作Restore), 跳转(不同分支间的切换Switch)。
(三) 分支(Branch)
一般是为了进行代码调试或概念开发,从主要的开发版本中分离出一个副版本,并在此基础上进行修改,(实际中我们可以分离出来进行各自的模块开发)使版本有向图呈现分支状态。
(四) 合并(Merge)
一般是为了将代码调试或概念开发分支的代码加入到主要版本中,将对两部分的代码进行比较:
先向后回朔两个分支的最近公共节点,通过与最近的公共节点进行比较,分析两个分支各对哪些文件进行了修改(因为是文件块,所以需要对两个版本的文件求差,传统模式则需要对两个版本的记录进行求和)。
合并最容易产生的错误(冲突)如果某一个文件在 两个版本中均被修改过,则视为“冲突”,这时我们解决的办法是需要人工手动调整其中一个版本,需要确定找到两次提交的相关人员,确定双方修改的内容,进行逻辑的确认合并,切记此处不要随便删除改动一方的提交,一定要找到冲突双方进行确认,否则会造成计划外的错误和问题。
(五) 标签(Tag)
不移动的参照,以标记特殊的代码版本副本,比如说项目的里程碑等

2.2 git常用操作

(一) 新建分支
首先,每次开发新功能,都应该新建一个单独的分支

# 获取主干最新代码
$ git checkout master
$ git pull

# 新建一个开发分支myfeature
$ git checkout -b myfeature

(二) 提交分支commit
分支修改后,就可以提交commit了,建议,每天至少提交一次。

$ git add .
$ git status
$ git commit --verbose

git add 命令的all参数,表示保存所有变化(包括新建、修改和删除)。从Git 2.0开始,all是 git add 的默认参数,所以也可以用 git add . 代替。
git status 命令,用来查看发生变动的文件。
git commit 命令的verbose参数,会列出 diff 的结果。

(三) 撰写提交信息
提交commit时,必须给出完整扼要的提交信息,规范格式如下:

[Type]: subject
Type包括:
type用于说明 commit 的类别,只允许使用下面8个标识。
br: 此项特别针对bug号,用于向测试反馈bug列表的bug修改情况
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
revert: feat(pencil): add 'graphiteWidth' option (撤销之前的commit)

例:

[fix]: add 'graphiteWidth' option

(四) 与主干同步
分支的开发过程中,要经常与主干保持同步。

$ git fetch origin
$ git rebase origin/master

(五) 合并commit
分支开发完成后,当本地留存大量commit,但是合并到主干的时候,往往希望只有一个(或最多两三个)commit,这样不仅清晰,也容易管理。可以使用git rebase 命令将多个commit合并。

$ git rebase -i origin/master

关于合并commit细节在此不进行赘述。

(六) 推送到远程仓库
合并commit后,需要推送当前分支到远程仓库

$ git push origin myfeature
$ git push --force origin myfeature  //rebase以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送

(七) 发出Pull Request
提交到远程仓库以后,需要发出 Pull Request 到master分支,然后请求相关技术管理人员进行代码review,确认后再合并到master。

2.3 其他

(一) 代码库分类:
a) 远程仓库:位于服务端,所有开发的代码最终都要合到远程仓库。
b) 个人工作库:位于每个开发人员的开发机器,从远程仓库(服务端)clone到本地。每个开发人员开发的代码,先commit到个人工作库,再由个人工作库push到远程仓库的对应开发分支。

(二) 人员角色分类:
a) Owner:拥有远程仓库的所有权限。
b) Master:具有将开发人员的合并需求(MR)合入远程仓库主分支的权限。基于安全考虑,我们设置为只能通过MR的方式将代码合入主分支,而不能直接push到主分支。
c) Developer:只能从自己的个人开发分支提交合并代码的请求(MR),是否能够合入主分支,由Master进行审核。

(三) 基本流程和分支管理基于git flow和github flow两种流程模式
项目可以根据实际需求践行对应的流程管理模式,具体的流程在2.3 分支管理规范中详述。

3 分支管理规范

3.1 git-flow模型

git-flow 模式会预设两个主分支在仓库中,开发人员不可以直接操作这两个分支,在开发完成的功能分支提交到远程仓库后,需要提出merge request,由技术管理人员审核后才能合并至develop分支。

(一) 发布主分支master:
a) 每个代码库有且仅有一个主分支 master。所有提供给用户使用的正式版本,都在这个主分支上发布,同时都要一对一的生成一个 tag。除初始化仓库生成的 master 分支以外,master 分支的所有提交都应是提供给用户的正式版本。
b) master 分支仅用于发布正式版本,同时需确保主分支的任何内容都是可部署的。并且只允许对 master 进行其他分支的合并和创建标记操作,不能单独在 master 分支上进行提交。
c) master 分支应该只授权给项目代码的管理者,不允许其余人员操作。

(二) 开发主develop:
a) develop 分支是进行开发的基础分支,其他的短特性分支是基于develop分支切分出来的,当你开始一个新的功能分支时,它将是开发的基础。
b) 新功能的开发分支会合并在develop分支中,等待被整合到 master 分支中。

(三) master 分支应该只授权给项目代码的管理者,不允许其余人员直接操作。

软件开发管理规范_第1张图片
这两个分支被称作为长期分支。它们会存活在项目的整个生命周期中。而其他的分支,例如针对功能开发的分支,针对版本发布的分支,仅仅只是临时存在的,它们是根据需要来创建的,当它们完成了自己的任务之后就会被删除掉。

(四) 功能分支feature:
a) feature 分支为开发某个功能点而创建。
b) 完成功能点的开发后,feature 分支的最新内容会被部署至 staging 环境进行功能测试验收。功能点测试完成后再合并入 develop分支,并删除 feature 分支。
c) feature分支的名称格式一般为feature-[任务号码]的格式,例如feature-10980,10980对应任务管理平台中的任务号码。

(五) 预发布分支 release:
a) release 分支是指发布正式版本之前(即合并到 master 分支之前),基于develop分支切出来作为预发布版本以此进行测试的分支。一个 release 分支对应一个版本发布计划,包含一个或多个的用户故事、不定量的功能点、漏洞修复等。
b) 分支的命名格式为release-[版本号],例如release-0.1.0。
c) 完成发布计划的所有开发后,将 release 分支的内容部署到 UAT(User Acceptance Testing) 环境进行测试验收,测试通过后,再将release分支合并入develop分支,并删除该release分支,然后基于最新的develop分支创建一个新的版本标记。
d) 最后确认发布后,需要将develop分支合并至master分支,表示产品进行了发布,所有的新功能与新特性已经合并到了master分支。

(六) 修补Bug分支bugfix:
a) 修补 Bug 分支 bugfix 是指在开发过程中,对于发现的漏洞进行修补的分支,基于develop分支切分出来,与feature的开发过程比较类似。
b) 分支的命名格式为bugfix-[任务号码],例如bugfix-10980,10980对应任务管理系统中的bug任务号码。
c) 完成漏洞修补的开发后,bugfix 分支的最新内容会被部署至 staging 环境进行功能测试验收。最后将其合并入 develop分支,并删除 bugfix 分支。

(七) 热修复分支hotfix:
a) 软件正式发布以后,难免会出现 Bug 。这时就需要创建一个 hotfix分支 ,进行 Bug 热修复,与bugfix不同的地方在于,hotfix是基于master分支进行切分的,完成会合并入master分支,再合并到develop分支。
b) 分支的命名格式为hotfix-[新版本号码],例如hotfix-0.1.1。
c) 漏洞修复后需要为hotfix 分支制作一个新的修订号版本标记。最后,根据实际情况可选的合并入 master 分支,再合并到develop分支,并删除 hotfix 分支。
软件开发管理规范_第2张图片

3.2 github-flow 模型

Github-flow分支模型与git-flow分支模型比较类似,区别在于github-flow模型中去除了develop分支,预设的保护分支仅留master分支,feature、bugfix、release直接基于master分支切出进行开发,开发完毕后经由merge request合并至master分支,版本发布时tag直接打在release分支上,而后合并至master分支。而线上的热修复分支hotfix则基于版本tag进行切出,确定修复后在hotfix分支上打出对应的版本tag,然后合并到master分支。除了master分支,其他分支在完成对应的工作后都需要合并到master分支,然后删除。实际的分支管理示意图如下:
软件开发管理规范_第3张图片

4 版本控制规范

在软件管理的领域里存在着被称作“依赖地狱”的死亡之谷,系统规模越大,加入的包越多,你就越有可能在未来的某一天发现自己已深陷绝望之中。
在依赖高的系统中发布新版本包可能很快会成为噩梦。如果依赖关系过高,可能面临版本控制被锁死的风险(必须对每一个依赖包改版才能完成某次升级)。而如果依赖关系过于松散,又将无法避免版本的混乱(假设兼容于未来的多个版本已超出了合理数量)。当你专案的进展因为版本依赖被锁死或版本混乱变得不够简便和可靠,就意味着你正处于依赖地狱之中。
我们的版本控制规范采用业内较为统一认可的语义化管理规范,大体版本格式为:
主版本号.次版本号.修订号
版本号递增规则如下:

主版本号:当你做了不兼容的 API 修改,
次版本号:当你做了向下兼容的功能性新增,
修订号:当你做了向下兼容的问题修正。

先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
详细规范如下:
(一) 使用语义化版本控制的软件必须定义公共 API。该 API 可以在代码中被定义或出现于严谨的文件内。无论何种形式都应该力求精确且完整。
(二) 标准的版本号必须采用 X.Y.Z 的格式,其中 X、Y 和 Z 为非负的整数,且禁止在数字前方补零。X 是主版本号、Y 是次版本号、而 Z 为修订号。每个元素必须以数值来递增。例如:1.9.1 -> 1.10.0 -> 1.11.0。
(三) 标记版本号的软件发行后,禁止改变该版本软件的内容。任何修改都必须以新版本发行。
(四) 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。
(五) 的版本号用于界定公共 API 的形成。这一版本之后所有的版本号更新都基于公共 API 及其修改内容。
(六) 修订号 Z(x.y.Z | x > 0)必须在只做了向下兼容的修正时才递增。这里的修正指的是针对不正确结果而进行的内部修改。
(七) 次版本号 Y(x.Y.z | x > 0)必须在有向下兼容的新功能出现时递增。在任何公共 API 的功能被标记为弃用时也必须递增。也可以在内部程序有大量新功能或改进被加入时递增,其中可以包括修订级别的改变。每当次版本号递增时,修订号必须归零。
(八) 主版本号 X(X.y.z | X > 0)必须在有任何不兼容的修改被加入公共 API 时递增。其中可以包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须归零。
(九) 先行版本号可以被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰。标识符必须由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止留白。数字型的标识符禁止在前方补零。先行版的优先级低于相关联的标准版本。被标上先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求。范例:1.0.0-alpha、1.0.0-alpha.1、1.0.0-0.3.7、1.0.0-x.7.z.92。
(十) 版本编译元数据可以被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。标识符必须由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,且禁止留白。当判断版本的优先层级时,版本编译元数据可被忽略。因此当两个版本只有在版本编译元数据有差别时,属于相同的优先层级。范例:1.0.0-alpha+001、1.0.0+20130313144700、1.0.0-beta+exp.sha.5114f85。
(十一) 版本的优先层级指的是不同版本在排序时如何比较。判断优先层级时,必须把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译元数据不在这份比较的列表中)。由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较,例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定。例如:1.0.0-alpha < 1.0.0。有相同主版本号、次版本号及修订号的两个先行版本号,其优先层级必须透过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:只有数字的标识符以数值高低比较,有字母或连接号时则逐字以 ASCII 的排序来比较。数字的标识符比非数字的标识符优先层级低。若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。范例:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。

5 环境管理规范

软件开发环境(Software Development Environment,SDE)是指在基本硬件和宿主软件的基础上,为支持系统软件和应用软件的工程化开发和维护而使用的一组软件,简称SDE。它由软件工具和环境集成机制构成,前者用以支持软件开发的相关过程、活动和任务,后者为工具集成和软件的开发、维护及管理提供统一的支持。环境管理规范基于业内IT项目管理的基础规范进行整理。软件应用开发的经典模型有这样几个环境:开发环境(DEV)、集成环境(SIT)、测试环境(TEST)、QA验证(QA)、用户接受度测试环境(UAT)、类生产环境(PRE)、生产环境(PROD)。而根据实际项目管理经验中,我们认为最少需要4个环境进行实际开发。

5.1 DEV环境

开发人员或者开发团队的工作环境,可以根据开发的需求随时将变更更新在环境当中用于测试,可以是开发人员的本地环境,也可以是团队统一的环境,此环境必须与其他环境和资源严格隔离。

5.2 SIT环境

该环境用于测试所有开发人员的代码进行整合之后运行环境,供测试人员使用。目前结合更为成熟的开发模式和DevOps工具,将该环境与DEV环境整合在一起,尽可能快的产生能够运行测试的交付环境。

5.3 UAT环境

UAT环境主要是用来作为客户体验验证测试的环境,供真实用户验收使用。UAT环境应尽可能多地模拟生产环境,也可以兼作演示、培训用环境。

5.4 PROD环境

即正式环境,软件经过层层测试校验后会部署在正式给用户使用的环境,该环境由于性能要求等可能会采用分布式、集群式等复杂的架构,部署生产环境是一件非常严肃的事情,需要避免一些可能出现的问题。
除以上环境之外,可根据项目管理的实际需求进行部分调整,例如自动化测试环境、压力测试环境、预发布环境等,其他特例环境在此不做赘述,可根据实际需求做出对应调整。

你可能感兴趣的:(devops,经验分享,经验分享,git)