• DevOps最佳实践之应用开发和部署


    关于最佳实践

    本系列内容是我们在不同项目的维护过程中总结的关于DevOps/SRE方面的最佳实践,我们将致力于在项目上尽最大的努力来推行这些最佳实践。我们希望这些最佳实践能对项目的稳定运营提供帮助,也希望刚接触DevOps/SRE的新人能通过学习这些最佳实践来提升自己在这方面的水平。

    因为DevOps/SRE涉及到的方方面面比较多,一次性完成的工作量太大,所以我们决定分阶段来完成,这一次发布的是“应用开发和部署”这个部分的内容,后续我们将逐步发布“云平台与网络”,“操作系统和服务”,“用户与权限”,“监控与可视化”,“数据与备份”,“敏感数据”,“故障与应急响应”这几部分的内容。

    所谓“最佳实践”应该是最适合自己的实践,而不一定是最先进的,而且每一种实践本身也存在一定的局限性,所以我们在描述了对应实践的优点的同时,也把可能存在的缺点写了出来,就是希望大家在看到它的好处的时候,也能知道可能存在的风险在那里,理性地去评估到底是不是要采用相应的实践,所以这里总结的最佳实践请适度取用,不要为了“最佳”而实践。

    我们深知自己在诸多方面存在一定的局限性,相关的内容可能存在一些不足,而且最佳实践本身会随着技术更新等因素不停地变化,我们将会把蓝皮书内容同步发布在Github上(https://github.com/toc-lib/DevOps-SRE-best-practice) ,希望引发更广范围的传播和讨论。也请使用PR或Issue的方式来提出你的不同的观点和更好的建议,谢谢。

    应用开发和部署

    使用牲口模式

    在传统的运维环境中,由于条件的限制无法快速的提供新的基础设施和环境,所以通常在业务的依赖环境如操作系统内核,服务,类库,运行时版本等需要变化时,我们会根据需要在现有的环境上做持续性变更。而且我们还可能会在机器上运行一些临时任务,做调试和排错等,很多的时候,这些操作对应的变化并不具有可追溯性,甚至不可以恢复到之前的状态。这样,刚开始统一配置的无差别的一批机器随着时间的推移慢慢的就会变得各自具有一些独有的特性。另外还有一些类型的服务,比如数据库,存储等,其业务本质就导致了集群中的每一台机器具有独特的属性。当我们在维护这些服务的时候,需要根据每台机器的特性来做不同的管理和配置,而且一旦机器出现故障的时候,也很难去创建出一样的机器来替代。因为这种情形和养宠物类似,比如我们会给宠物起一个名字,它也需要悉心照料,生病的时候要带去看病,所以我们称这种服务模式为宠物模式。

    而在具有云原生能力的平台上,我们可以按需定制基础镜像,也能快速的从这个基础镜像中创建出运行环境,我们的变更就可以基于基础镜像来做更新和版本迭代。这样当某一台机器发生了故障,我们可以快速的复制出一台一模一样的机器来替代。如果需要做一些临行性的操作和变化,在任务结束之后,也可以销毁这台已经发生了变化的机器,使用一台新的机器来替代,使整个集群恢复到一个最初的收敛状态。这个场景和我们现实生活中的规模化牲口养殖类似,对应的我们称这种服务模式为牲口模式。

    大家所熟知的无状态应用,就是牲口模式的最常用的一种实现方式。在业务的设计和实施过程中,我们建议把逻辑和数据分离,在逻辑运行环境不要兼顾数据存储工作,比如请求的session相关的数据,不要保存在本地,而是把它放在一个共享数据服务中,从而达到无状态的目的,这样就可以对逻辑运行环境进行牲口化的管理方式。

    优点:
    1. 可随时被销毁或替换,结合自动化基础设施和监控,自动完成对故障机器或节点的替换。
    2. 配合自动化基础设施和监控,可实现自动水平伸缩,从容应对业务峰谷,节约成本。
    3. 在不影响服务稳定性的前提下可部署所需要版本的应用、进行系统升级或者打补丁。
    4. 监控和管理的重心不再是具体的单一资源的使用率,而是整体的承载能力和更深层次的性能关注点。
    缺点:
    1. 需要基础设施平台具有相应的能力支撑,否则很难实现。
    2. 不是所有的业务类型都能做牲口模式设计,比如数据库。
    实施要点:
    1. 除计算和业务处理过程中的临时产生的数据,数据的来源和最终的持久化应由外部服务来提供,如独立的内存型数据库或者关系型数据库。
    2. 可以使用客户端Cookie、cache取代外部数据服务。如果有敏感数据,服务器端可以加密后交由客户端存储,在之后的请求时发回服务器解密使用。
    3. 通过锁或者幂等性设计,使得应用能正确、快速、自动地解决对同一份数据的竞争而导致的流程异常、数据不一致等问题。例如,多个定时任务同时处理一批数据。

    使业务升级向前兼容

    向前兼容指低版本的系统、程序或技术能优雅处理(例如:忽略其不理解的部分)高版本的系统、程序或技术。向前兼容技术的目标是让旧系统能够识别为新系统生成的数据,简单的说就是旧版本的系统可以接受新版本的数据,是旧版本对新版本的兼容。

    我们建议在做业务升级时候,设计你的业务具有向前兼容的能力,以应对升级失败时某一功能模块或者依赖无法随之回滚的风险。比如说在有数据库字段变化的升级中,在正式对数据库做变动之前,基于旧的业务流程做代码层面更新,使其可以兼容数据库将要发生的改动并加以部署。在数据库升级完成之后,如果新的业务流程上线后不幸出现重大的问题等情况需要回滚时,回滚之后的代码仍然可以兼容数据库的变化,而不用对数据库也进行回滚,毕竟数据库的回滚成本非常高。

    优点:
    1. 可以在新版本出现不容易修复和存在重大的风险的时候快速当回滚到旧的版本,业务中断的可能性会大大降低。
    2. 即使整个系统中存在不可回滚的部分,但我们不用花费很多的精力去考虑和解决完全不可回滚的问题。
    缺点:
    1. 设计成本:要做到兼容未来的变化。这听起来就很难。一开始很难获知所有用例、极端案例和业务理解。回顾过去并说这是一个错误的决定很容易,今天做出明天不会后悔的决定要困难得多。
    2. 为了同时兼容两种数据格式,需要在代码中增加额外的处理逻辑,增加复杂度和投入的成本。
    实施要点:
    1. select语句只获取需要的字段,避免使用select * from语句,有效防止新增字段对应用逻辑的影响,还能减少对性能的影响。
    2. 对数据库表结构变更通过新增字段实现。
    3. 尽量新增接口,避免对现有接口做修改&#
  • 相关阅读:
    远程桌面无法复制粘贴文件
    Docker学习
    IPV6地址详解
    java BufferedReader类、BufferedWriter类
    跟循泰国国内游宣传曲MV,像本地人一样游曼谷
    C语言实现DNS请求器
    react中受控组件与非受控组件
    meta标签是什么
    基于SSM的车辆租赁管理系统
    微信小程序通过 movable-area 做一个与vuedraggable相似的上下拖动排序控件
  • 原文地址:https://blog.csdn.net/toafu/article/details/128144671