资深网站如何做可以收取客户月费,泰安网站建设总结,wordpress图片调用,网站建设的安全威胁简介#xff1a;效能提升从小习惯开始#xff0c;这样才是代码管理和 Commit 的正确姿势#xff01; 专栏策划#xff5c;雅纯
志愿编辑#xff5c;张晟
软件交付是以代码为中心的交付过程#xff0c;其中代码的作用有几点#xff1a;第一#xff0c;最终的制品要交付…简介效能提升从小习惯开始这样才是代码管理和 Commit 的正确姿势 专栏策划雅纯
志愿编辑张晟
软件交付是以代码为中心的交付过程其中代码的作用有几点第一最终的制品要交付成什么样需要通过代码描述清楚第二代码定义了系统和软件是怎样工作的第三代码定义了系统的运行环境是怎样的。所有这些都是围绕代码。
那我们的代码管理和软件配置管理应该怎样做呢
我们先看一个例子。下图是某个团队的代码组织结构这样的代码组织结构会有什么问题呢 问题1代码组的命名方式混乱
我们发现在最上层的目录中叫risk-managenment这是一个系统这个系统是风险管理。但是子目录写的是叫“qinglong”那“qinglong”是应用还是团队我不知道。然后下面还有一个玄武下面还有一个aTeam中英文混杂这样的命名方式是很混乱的。
问题2用代码块存储外部二进制文件
在android-sdks里面会存放很多sdk文件这些文件是很大的这个代码库存储很多外部二进制文件我们知道在代码库直接存这样的大文件对整个代码库的资源消耗是非常大的。
问题3同一归属的代码保存在不同的代码组
在aTeam目录下有一个data-model但是其他相关的文件都在玄武下就是data-console、data-task、data-ui我们不知道它具体是什么但是我们知道这几个大概率是同一个应用或者是同一个产品所以它在两个不同的层级也是不合理的。
问题4公共库保存在子代码组里
再下一个是common-lib通过名字来理解就是公共库但是这个公共感觉只给玄武这个子代码组使用。
问题5应用的文档或测试与应用分开存放
最后还有一个docs目录下有risk-docs和data-docs一个是针对风险控制的系统一个是针对数据地系统。那这个里面文档也是一个代码库文档代码库和测试代码库它和应用是分开存放的这也是不合理的。
好的代码库组织形式是怎样的
问题假设所有的代码都保存在一个代码库且所有人均可访问代码库应该怎么组织
我们认为代码库是可以分组的代码组子代码组代码库大库。
基于这个逻辑我们再看看刚才那个例子里合理的代码组的结构应该是怎样的。 如上图所示整个代码库是一个系统这个系统有两个应用一个是risk一个是data。每个应用下面是有很多的服务和文档。它们有一个公共的Model叫common-lib这是被所有的应用所依赖的。所以我们把属于同一个应用的Git仓库放在一起让common放到该有的地方去。不是按照团队而是按照应用组划分这样划分结构就更加清晰了。这里我们稍微总结了一些实践的建议。
代码库的内容
-软件的源代码ProductionCode -将文档和测试的git库放到其相关应用组下 -不要将制品如系统二进制包保存在代码库中如果确实需要以LFS或类似方式存放 小编推荐云效代码管理Codeup为企业提供免费不限容量的LFS存储
代码库的组织结构
-按照系统、应用和模块的层次来组织代码库 -同一个系统/应用层级的所有内容位于同一个代码组下
代码库的可见性
-通用代码库放在其通用级别都可以访问的位置 -除核心算法等少数代码库外建议对代码库的访问在同一系统/应用下对所有相关人员公开
代码组织完了以后开发者就可以围绕代码库来进行协作。整个代码库的协作过程就是一切皆Commit。无论是rebase还是merge都是Commit。
那对于Commit我们有什么要注意的呢
什么是好的Commit
我们总结了3点建议给到大家 1.Samll
Git库要尽可能地小。尤其是目前的基础设施现状下虽然你的一个仓库里可以放多个应用但是维护起来的成本会很大的。还有管理方面不要在Git上存储构建产物和其他二进制文件。把构建产物放在构建仓库上虽然给别人方便了却很难知道这个构建产物是现在的代码产生出来的还是之前产生出来的这是很难去追溯的。对于二进制文件如果确有必要例如游戏的素材建议使用LFS的方式来保存。
2.Linear
避免无意义的merge尽量用rebase操作。其次是避免无效commit有很多代码库commit记录很长但是里面80%都是无效的例如都是fix1、fix2这样的commit都却不知道它具体做了些什么这种显然是不合理的对于这种冗长的commit列表有时候可以在merge的时候squash一下。
3.Atomic
原子性指操作的原子化。原子性有什么好处呢一个Commit解决一个特定的问题比如说我就是修复一个UTcase或者是加一个UT或者是加一个功能或者是加一个API这些明确的问题对应到一个commit很容易追溯。解决的问题不能很大不能写了2000行代码解决了一个feature一起提交这是非常危险的。作为开发者做的好的应该是快速有阶段性的成果并且持续地有反馈持续地贴近目标。反之开发者的体验不好相关协作者的体验也不好因为别人不知道你做了多少了很有可能跟你发生mergeconflict。
下面列举一些Commit的反模式
1.无效的commit
如Mergebranchdevelopof https://codeup.aliyun.com/abc/xyzintodevelop第一个问题在几乎所有公司里面都是随便拉开一个代码本地和远程都有这种情况本来一个rebase搞定的事情这样做会导致很多无效的commit甚至对commit追溯能力会产生很大地影响。
2.巨型commit
一个commit里面包含了大量的代码变化且属于多个实现目的就像codereview有些人提的mergerequest一下子过来3000多行代码作为reviewer你完全不知道他做了什么这是非常危险的。
3.半成品的commit
如包含有基本语法问题或实现错误的代码的commit半成品的commit。例如到饭点了不管了先提交一把。这样的代码连编译都过不了这个显然是不好的没有任何意义。
4.分支间的互相merge
最后一个是分支间的互相merge。从develop合到master又从master合到develop互相合来合去一旦这种合并多了以后commit就会很难追溯因为不知道源头在哪。我们建议代码库应该有一个唯一的主干单向往主干merge尽量避免反向merge的情况。
小编推荐云效代码管理Codeup的主干开发模式就提倡轻量的commit评审 和主干研发帮助企业避免分支间的复杂合并
软件配置管理
问题软件配置经常被修改被发布它属于代码吗
软件配置其实是另外一种形式的代码。有可能大家在实际工作中配置不是存在Git仓库里面的可能是在一个配置中心或者其他类似系统里面但无论在哪里本质上我们可以把配置等同于某种类型的代码。
下图是大家常见的静态配置和动态配置或者说启动相关的配置和运行相关的配置。 启动相关配置
启动相关配置是构建到镜像中或者作为启动参数传进去的。启动之后不再修改了不需要去动态监听它的变化。对这类配置的修改一般需要重新创建或者重启容器。
以此类推哪些配置是启动相关的呢比如DB连接串、容器CPU规格、启动模式等比如有的压测应用启动的时候区分master模式和worker模式。其它像DNS服务地址等诸如此类的我们都认为是启动相关的配置。
运行相关配置
通常是通过监听某个服务或文件来获取和更新的。比如说我要看一下我的白名单是什么我去读一下白名单。配置的更新是不需要修改容器和Pod。运行中的容器需要持续监听配置的变化当有变化后自动生效、无需重启。
我们举一下场景实例说明一下
大促时期调整日志级别只记录ERROR级别的日志。服务的黑白名单为了限制某些IP的访问将其列入黑名单。特性开关通过开关打开或关闭某个feature。监控采样频率由每分钟采样一次调整为每5分钟采样一次。
这些配置不需要也不应该每次修改都重新部署应用他们都属于运行相关的配置。
我们再来看一个demo示例里面哪些是启动相关的哪些是运行相关的。我们列举一下 这是启动的时候就会需要的一个参数。 我们将secret文件注入到Deployment中应用自动从文件感知secret的值无需重启因此它是运行时的配置。越内层的配置修改成本越高。 从另外的角度看一下配置它有不同的层次代码、镜像、Pod和系统。代码中的配置位于最内层修改成本是最高的。因此如果是编码级别的修改要经过所有的阶段才能上线。如果运行阶段的话我是不需要动前面的部分。
最后留一个问题给大家运行环境相关的配置是属于哪一种欢迎大家在评论区留言互动。
软件交付的终态是提供稳定可预期的系统要做到这点需要确保1.运行环境的一致性2.软件制品的一致性。所以下篇我们将开始分享如何保证运行环境的一致性以及环境中大家常见的痛点和应对方案。敬请期待 原文链接
本文为阿里云原创内容未经允许不得转载。