自己搭建的ftp怎么做网站,手机如何制作代码,宝格丽官网,怎么查网站是否备案作者#xff1a;京东物流 冯志文 背景 在软件开发和运维领域#xff0c;变更管理是一个至关重要的环节。无论是对现有系统的改进、功能的增加还是修复漏洞#xff0c;变更都是不可避免的。这些变更可能涉及到软件代码的修改、配置的调整、服务器的扩容、三方jar包的变更等等… 作者京东物流 冯志文 背景 在软件开发和运维领域变更管理是一个至关重要的环节。无论是对现有系统的改进、功能的增加还是修复漏洞变更都是不可避免的。这些变更可能涉及到软件代码的修改、配置的调整、服务器的扩容、三方jar包的变更等等。然而变更的执行过程往往伴随着一系列的风险和挑战。变更管理对于确保系统的稳定性至关重要。只有通过有效的变更管理措施如合理的变更计划、全面的测试和验证、及时的问题解决等才能够最大限度地减少变更带来的风险确保系统的稳定性和可靠性。因此对于任何一个组织或团队来说都需要高度重视变更管理并将其作为稳定性建设的重要组成部分。 一、兼容设计 在变更管控各项变更中如果考虑好兼容设计其整体的变更就会比较平滑整个变更的兼容设计会从硬件、软件、数据三个层面展开其中软件部分还区分基础软件和应用软件现在从以上部分展开对应的兼容设计需要考虑的原则如下描述。 1、硬件变更兼容设计 硬件平台变更原则上不应该影响在其之上运行的应用服务(主机硬件平台升级网络设备升级存储设备升级防火墙升级)所有硬件升级必须考虑线下兼容性需要在线下环境进行详细的测试验证保证生产系统变更稳定性。 2、基础软件变更兼容设计 任何基础技术和系统软件的升级原则上不应该影响使用其的应用服务(框架消息组件缓存存储中间件操作系统JVMApacheJBossTomcat等)所有基础软件必须考虑线下兼容性需要在线下进行严格并且详细的测试保证生产系统变更稳定性。 案例1mysql数据库5.5升级5.7风险点 1、MySQL版本从5.5升级到5.7最大的风险在于数据精度不同尤其体现在时间类型的精度方面。 2、timestamp NOT NULL DEFAULT 0000-00-00 00:00:00 类型在5.5版本中create\_time虽然定义为not null ,但是实际是能插入null值会自动转换为current\_time5.6版本直接报错拦截语句插入。 3、timestamp 时间类型在5.6.4版本后支持毫秒。例如timestamp(3)即保留3位毫秒如果不指则不存储毫秒。 4、数据精度变化5.5直接截断5.6、5.7版本会按4舍5入取位。 \*关于时间类型、数值类型、浮点类型请进行严格验证。 \*mysql更新到5.6.4 之后 , 新增了一个叫factional seconds的特性 , 可以记录时间的毫秒值. 但是目前的数据库是不记录毫秒值的 , 所以会产生一个java中时间的Milliseconds超过500就会四舍五入的问题. 例如一个时间是2015-08-31 23:59:59.520 , 毫秒值超过500 , 入库的时候 , 时间就会变成2015-09-01 00:00:00 . 下面的两条sql就可以看出效果. 登录后复制 insert into money_record
values(null,1711929, jerry1bean, NULL, NULL, 20.00, 2.00, 1250,
2015-08-31 23:59:59.500000, NULL, NULL, NULL, just a test, NULL);insert into money_record
values(null,1711929, jerry1bean, NULL, NULL, 20.00, 2.00, 1250,2015-08-31 23:59:59.499999, NULL, NULL, NULL, just a test, NULL); 1.2.3.4.5.6.7. 5、5.5版本sql where 条件的值即使传入带毫秒sql解析后也不带毫秒 5.7 查询sql解析后会带着毫秒 所以在范围查询时同样的sql查询的结果可能不同。 3、应用软件变更兼容设计 应用升级方案中应该考虑应用向下兼容能力无法完全向下兼容的应用升级过程在联调、预发布及正式上线过程中会引起已有业务服务的不可用在关键业务路径上的一级服务如果发生不兼容现象后果更加严重会直接导致变更过程中的大量业务处理中断引起核心业务下跌。应用可向下兼容的评估点包括但不仅限于服务接口、方法、入参、返回值及服务方法具体实现的向下兼容性能力其中服务方法具体实现向下兼容是应用向下兼容能力的最核心表现。对于一、二级关键服务应用升级过程中必须完全向下兼容确保发布过程中不产生兼容性问题进而导致业务下跌或其他关键服务不可用。同时服务消费端设计上需要做到客户端可不要求同步升级。 案例1JSF默认的Msgpack序列化接口对象里增减字段如何处理 【现象描述】JSF默认的Msgpack序列化接口对象里增减字段如何处理 【原因分析】Msgpack是按字段顺序进行序列化和反序列化的其缺点是无法改变字段顺序。 【解决方案】 因Msgpack序列化不能改变字段顺序所以在两边不同时升级的情况下字段兼容规则如下(包括Bean和枚举) 1、不要调整原有字段顺序不能删减字段除非是删最后一个字段。 2、新加的字段必须在字段最后面(只是字段顺序不是文件最后面getter/setter方法等随意)。 3、父类的字段不能变。因为父类一变相当于子类的中间插入一个字段。 满足上面规则服务端和客户端哪边先升级都无所谓。 如果是需要父类加字段或者中间加减字段这种则需要服务端和调用端同时升级。 4、数据变更兼容设计 应用软件系统升级方案往往附有数据存储格式变更良好的数据兼容性设计对升级后应用平稳上线起到重要的保障作用。数据兼容性设计要求设计方案遵循安全的增量变更原则即在保障已有的数据存储结构不发生语义变化的前提下合理增加升级应用所必须的数据列并且所增加数据列不对已有业务服务造成影响如外部系统所调用的查询服务不会中断、业务返回结果不变。原则上当已有数据存储结构语义发生变化原存储列所存储值业务含义发生变化时应该通过新增存储列来完成避免直接复用已有存储列或修改已有存储列名的做法。对于重要性高的服务数据升级后必须完全向下兼容确实无法做到数据向下兼容的如原有存储列完全废弃的应该首先确保外围使用系统业务改造完成后方可上线。 案例1mysql表结构变更 背景新需求上线表结构需要增加个新的字段 1、代码上线前提交sql语句如下字段apply\_type 为not null 未给默认值导致不兼容线上逻辑 登录后复制 ALTER TABLE store_capacity_approve
ADD COLUMN apply_type tinyint(4) NOT NULL
COMMENT XXX类型 AFTER match_standard; 1.2.3. 2、但由于代码未上线导致线上报错Filed apply\_type doesnt hava a default value 3、修改sql给apply\_type该字段添加默认值兼容线上代码逻辑 登录后复制 ALTER TABLE store_capacity_approve
MODIFY COLUMN apply_type tinyint(4) DEFAULT 0
COMMENT XXX申请类型; 1.2.3. 二、新版本发布设计 1、停机性发布 原则上建议非高优先级系统不进行停机发布。对于高优先级系统应在系统设计阶段尽量避免停机发布如因系统拆分数据库拆分整体架构升级等原因一定需要停机需严格限定停机范围、停机的时间点与停机时长。如需停机的系统及业务可以独立发布则除这些系统外其他系统尽量保障采取非停机平滑发布方式。如因系统耦合度或者业务耦合度复杂无法独立发布则进行整体停机发布 2、发布顺序是否合理 根据系统间依赖指定合适的发布先后顺序。系统发布顺序遵照以下原则禁止系统启动依赖无因系统启动依赖导致的发布顺序依赖对于业务依赖需保证无相互依赖。高优先级系统原则上不应该依赖于低优先级系统其他系统默认无发布顺序可以根据发布进度进行无序发布。 3、发布时间点 发布时间点需尽量避开业务高峰尤其是发布过程会对业务产生影响的核心系统。系统发布因尽量避免影响业务如确实对业务影响较大又无法在系统设计上避免需将发布时间点放在绝对业务低峰点。 涉及新旧功能切换。验证切换方案地合理性可逆性。发布过程中涉及到的新旧功能切换方案应确保可逆即切换失败后能及时切回到旧功能。方案需在研发环境进行详细测试如无法在研发环境进行测试需在预发布环境进行模拟测试确保方案正确有效可回滚。 三、灰度变更 1、灰度意义 1.我们在编码完成后会在测试环境中进行测试验证这是为了找到问题和错误。当我们完成整个测试流程后我们可以认为已知的问题已经得到了解决。由于测试环境与线上真实业务和用户环境是隔离的所以测试环境中的问题不会对线上业务和用户造成影响。 2.灰度发布是为了验证我们的假设即“还存在我们不知道的问题”。因此在进行灰度发布时需要更加谨慎确保即使问题在生产环境中出现也能控制其对业务和用户的影响。通过灰度发布我们可以逐步验证系统的稳定性和可靠性减少风险并提高产品质量。 3.我们需要明确一点灰度从来不是为了测试。它的主要目的是对抗“未知的不确定性” 。在软件开发过程中我们无法预测所有可能的问题和错误因此需要通过灰度发布来验证系统的稳定性和可靠性。 4.在分布式系统中常见通用的灰度过程有 beta 发布、蓝绿发布进行流量级别的灰度过程能够满足绝大部分变更灰度验证需求。如果变更复杂度较高或者业务比较重要在方案设计中也需要进行更精细变更影响面控制例如按照影响用户维度逐步生效的设计但要注意一次业务完整流程中开关一致性问题。 5.灰度发布是一种有效的风险管理方法可以帮助我们在软件开发过程中识别和解决潜在的问题提高产品质量和用户体验。 在灰度的落地与推进过程中有效性非常重要。因为灰度是一个很耗时的复杂的过程。如果不注意的话很容易出现“形式化”的情况即只是表面上的灰度而实际上并没有达到预期的效果。 为了确保灰度的有效性需要注意以下几个方面 1.制定详细的灰度计划在进行灰度之前应该制定详细的计划包括灰度的范围、时间、节点等信息以确保灰度过程的可控性和可预测性。 2.逐步推进灰度在进行灰度时应该逐步推进而不是一下子全面铺开。比如可以先在一个机房的一个分组中部分节点进行灰度然后再扩大到全部节点和集群最后再扩展到另外一个机房的相同步骤。 1.监控和反馈在进行灰度时应该及时监控和反馈以发现和解决可能出现的问题和风险。关键点在于时间和流量 时间 每个灰度阶段至少有 5 \~ 10 分钟的观察时间这个时间可以根据业务系统的具体情况进行调整。在观察期间需要密切关注监控、日志和各方反馈等信息以发现和解决可能出现的问题和风险。只有当这些信息没有异常时才能扩大灰度范围进一步推广灰度计划。在灰度过程中需要保持高度警惕和敏锐的洞察力及时发现和解决问题以保证系统的稳定和可靠性。 流量 在进行灰度时流量是一个非常重要的因素需要特别注意。特别是对于一些业务场景可能需要特定的触发条件才能进行灰度测试比如只有满足某些条件的用户或订单才能参与测试。 在这种情况下仅仅通过单位时间内是否存在异常来判断灰度是否成功是不足够的。还需要确保有足够的有效流量来触发这些特定的业务场景。否则即使系统在灰度测试中没有出现异常也不能完全保证系统在实际使用中的稳定性和可靠性。 因此在进行灰度测试时需要确保有足够的有效流量来触发这些特定的业务场景。同时还需要注意监控和日志等信息及时发现和解决可能出现的问题和风险。通过这种方式可以更好地保证系统的稳定和可靠性提高灰度测试的效果和价值。 有效的灰度可以把问题影响锁定在一个小范围内但是同样也降低了问题的“明显性”所以你要通过监控和日志更加仔细、谨慎地去寻找、观测异常并对比发现问题。灰度是一个复杂的过程需要仔细考虑和规划。通过制定详细的计划、逐步推进和及时监控和反馈等措施可以确保灰度的有效性和可持续性。 2、部署编排灰度 为解决用户手动部署操作耗时高、对人依赖度高、人工容易遗漏等导致线上问题痛点强烈推荐您使用 【部署编排】 功能用户可灵活制定部署策略实现从编译构建到实例部署的自动化运行提高部署效率但部署编排第一次使用的时候需要验证好。 比如这分组每次发10%具体分组灰度比例多少需根据业务特性而定。 四、数据迁移分析 发布过程所需的数据迁移方案需事先在线下环境进行模拟演练反复梳理迁移过程执行步骤将可能发生的迁移风险降到最小。数据迁移方案的可行性包括 方案的完整性是否本次升级内容所必须包含的待迁移数据项全部覆盖到位。 方案的安全性对于敏感信息如用户隐私信息的迁移方案是否存在由于迁移脚本的不合理导致隐私信息泄露风险。 方案的可实施性包括数据迁移操作方案的合理度(发布过程中完成或者发布前、发布中、发布后多阶段完成)相关角色配合实施步骤同时必须考虑本项目的数据迁移方案所占用时间是否对同一发布窗口的其他项目造成影响。 方案的可检测性迁移过程各个阶段的数据完整性、准确性检查脚本是否准备到位。 方案的可回滚性迁移过程中各个阶段如果发生了计划外风险必须要终止迁移操作的是否具备了已迁移数据回滚能力。 涉及重要性高的服务的数据迁移方案必须完整、安全、可实施、可检测、可回滚。 案例可参考 Redis渐进式rehash 兼容性 扩展或收缩哈希表需要将 ht\[0]里面的所有键值对 rehash 到 ht\[1]里面 但是 这个 rehash 动作并不是一次性、集中式地完成的 而是分多次、渐进式地完成的。 这样做的原因在于如果哈希表里保存的键值对数量很大时 如四百万、四千万甚至四亿个键值对 那么一次性将这些键值对全部 rehash 到 ht\[1] 的话庞大的计算量(需要重新计算链表在桶中的位置)可能会导致服务器在一段时间内停止服务(redis是单线程的如果全部移动会引起客户端长时间阻塞不可用)。 因此 为了避免 rehash 对服务器性能造成影响 服务器不是一次性将 ht\[0]里面的所有键值对全部 rehash 到 ht\[1] 而是分多次、渐进式地将 ht\[0]里面的键值对慢慢地 rehash 到 ht\[1]。 总结渐进式 rehash 执行期间的哈希表操作 (1)删除和查找在进行渐进式rehash的过程中字典会同时使用ht\[0]和ht\[1]两个哈希表所以在渐进式rehash进行期间字典的删除、查找、更新等操作会在两个哈希表上进行。比如说要在字典里面查找一个键的话程序会先在ht\[0]里面进行查找如果没找到的话就会继续到ht\[1]里面进行查找诸如此类 (2)新增数据在渐进式 rehash 执行期间新添加到字典的键值对一律会被保存到ht\[1]里面而ht\[0]则不再进行任何添加操作。这一措施保证了ht\[0]包含的键值对数量会只减不增并随着rehash操作的执行而最终变成空表。 五、可回滚设计 1、制定回滚计划 故障恢复最好的手段是各种预案而回滚则是预案中最普遍、也最有效的。 回滚的必要性 应用上线应该制定详尽的回滚计划能够在最短时间内将应用恢复至上一稳定运行版本然而系统并不是天然可以无缝回滚的想要系统具备回滚的能力在设计与实现阶段需要付出额外的精力。可回滚的本质是系统的兼容性设计与实现比如常见的“只增不改”一个 API 内要调整很多实现逻辑才能满足新业务的需求此时不妨直接新增一个 API 两个 API 保持参数一致那么一旦新 API 有异常直接通过开关技术切换回旧的 API 即可。一般情况下应用本身可回滚而数据层面的可回滚性是重要的考量因素之一。遵循安全的增量变更原则所设计的数据变更方案具备可回滚能力发布过程中所产生的增量数据列存储值要求可废弃。原则上任何应用服务在发布之前都必须具备可回滚的能力没有回滚能力的系统不允许发布上线。 回滚操作对业务的影响 由于应用升级的回滚实施必然会影响本次升级业务所服务的业务需求同时会直接影响对本次升级有依赖的其他业务系统回滚方案中必须明确本次发布窗口所有相关性需求项目明确一旦发生回滚处理受影响范围提前告知相关项目组及业务方同时尽可能降低多个业务关联性较强项目同一发布窗口的回滚风险。 涉及重要性较高的服务应用升级方案要求必须提供回滚方案且此回滚方案事先在线下环境得到完整模拟演练并确认可行回滚完成后要求不得中断服务业务运行正常 2、回滚原子性 回滚的复杂性 除应用本身及数据层面的可回滚性考虑外若服务使用客户端已完成同步升级则必须考量客户端的可回滚性极端情况下若客户端的本次同步升级也造成了其作为服务提供方的使用客户端同步升级则存在多个应用系统复杂的连带可回滚需求相关系统也需要评估其应用本身及其数据层面的可回滚能力作为本次应用升级回滚方案的一并考虑项。在升级方案设计中应该提前预知复杂回滚方案的实施成本防止发生上述的同步升级的多重强依赖关系。回滚方案包括但不仅限于应用回滚、数据回滚及清理、代码回滚、运维策略回滚、监控方案回滚等。 切记代码需要及时回滚以防在未修复问题前下次团队其他同事上线把未回滚代码部署到线上导致二次问题发生。 3、代码回滚之开关技术 在大部分场景下开关技术才是线上代码问题快速止血快速回滚的最佳方式(需根据业务系统特性而定)。如遇线上问题的话采用通用的回滚方式需要5-10分钟()并且回滚如果操作不当会加重问题,而采用开关技术则是秒级。同时Promise在处理日常迭代需求和稳定性保障方面功能开关技术同样发挥了重要的作用。针对改动范围大、影响面广的需求我通常会问上线了最坏情况是什么应急预案是什么你带开关了吗 。当然开关也是有成本的 4、行云部署的回滚方式 4.1、部署编排回滚 优点回滚过程平滑操作简单 缺点回滚时长与发布时长相同时间较长。 应用场景对于非紧急场景我们建议使用部署编排一键回滚的方式。 4.2、分组回滚 优点回滚步伐灵活可控速度快。 缺点需要每个分组单独回顾。 应用场景针对需要快速止血的场景可以采用分组回滚的方式这样可以更快地恢复系统状态。需要注意的是我们需要设置好回滚批次间隔以确保回滚操作不会对系统造成过大的影响。 六、配置变更控制 涉及生产配置参数的变更原则上必须进行严格变更审批流程保障。所有对于生产动态配置变更由专业运维保障团队统一操作。 动态配置能力可以从以下方面进行设计 动态配置变更的时机预发布变更、发布后变更等 动态配置的可验证变更接收方能够以日志等形式验证推送的内容否则是否推送何时推送推送的内容正确与否无法确证 动态配置的生效同步性在某动态配置涉及多个系统都需要同步时应用需要考虑在多个系统间不同步时会出现的问题 动态配置的容错性处理防止进行线上配置填写错误时系统即按照错误的情况运行动态配置必须有默认值; 动态配置是否系统启动时加载需要系统初起时加载的内容需要防止出现系统启动依赖 周期性动态配置对于定时刷新缓存方式实现的动态配置需要保证刷新成功后才更新或者替换缓存内容不能在主线程中判断和刷新缓存而应该另起线程刷新防止刷新缓存出现抖动或者阻塞而影响主线程的功能。 案例 1、修改JMQ的消费策略可能影响下游链路相关风险(比如依赖的下游流量、中间件等) 2、修改JSF限流可能导致对应风险点 七、复核验证 每个变更都需要有复核人对于标准变更复核人可只对结果进行复核。对于普通变更和重大变更复核人需要对变更流程、变更表单、实际操作进行核对确认对变更后的结果进行日志、监控等检查。复核人应对变更不当而引发的问题负责。 每个变更后需要有一系列的基于变更清单管理的效果检查的内容。如服务是否正常启动功能是否可用性能是否正常以及变更的内容是否符合预期。通过对变更效果进行验证才能最终确认本次变更是否正确。同时针对服务相关的全局核心指标的监控在变更期间既不应该出现异常也不应该随意屏蔽。 附Promise的checklist清单及DoubleCheck机制 1、建立CheckList清单 检查列表可以提醒人遗漏的东西、用来减少失败保持一致性和完整性。把checklist清单作为xbp流程中一部分集成到了行云部署发布中申请上线的时候必须填写。 附Promise上线案例之CheckList清单包含 1、向下兼容是否兼容之前功能 2.抽取文件检查比如JSF别名配置JIMDB配置等 3.ducc配置检查、是否新增加了开关 4.生产环境DDL检查比如数据库表字段等 5.JSF别名配置如上新接口或者服务需检查 6.jar包相关 7.JMQ配置检查 8.新日志文件检查(异步) 9、代码比对 10.上线过度方案检查、回滚策略检查 11.UAT环境是否测试 、性能测试、R2引流验证等 2、DoubleCheck验证机制 小组群同步上线信息并且执行DoubleCheck机制 那DoubleCheck验证看哪些 1、对外核心接口UMP(TP99、可用率、流量)或者MQ 等这个没什么好讲的。 2、根据日志验证对应场景(新功能场景及之前线上核心流程场景) 。比如promise场景复杂上线会验证不同订单类型的下传时间等相关的重要场景订单如下图 3、通过可视化界面验证线上订单全流程(用户、业务角度等) 。 比如xxx订单号预分拣环节命中了上线的机器通过持久化页面发现跟其他环节(转移、worker环节)时效是一样并且通过OM系统查看全程跟踪时效也是一直。说明上线的机器跟之前机器算出来时效是一直的如果不一致需要分析是由于业务刚修改了配置还是系统代码问题。 4、用户角度 总结 变更管理在稳定性建设中扮演着至关重要的角色。它涵盖了兼容设计、新版本发布计划、灰度变革、数据迁移、可回滚设计、配置变更控制和复核验证等多个方面旨在确保系统在变更过程中的稳定性和可靠性。 首先兼容设计和新版本发布计划是变更管理的基础。通过充分考虑现有系统的功能和架构我们可以预测并解决可能出现的兼容性问题。同时制定详细的新版本发布计划可以确保变更过程有序进行避免对用户造成不必要的影响。 其次灰度变革和数据迁移是降低变更风险的重要手段。通过逐步引入变更我们可以及时发现和解决问题减少对整个系统的影响。而数据迁移则是确保用户数据安全和完整性的关键步骤需要仔细规划和执行。 另外可回滚设计和配置变更控制是保障变更可控性的重要措施。 可回滚设计意味着我们可以随时将系统恢复到变更前的状态以应对可能出现的问题。而配置变更控制则可以确保变更过程的合规性和安全性防止未经授权的变更发生。 最后复核验证是确认变更有效性和正确性的关键步骤。通过对变更后的系统进行全面的测试和验证我们可以确保变更没有引入新的问题并且达到了预期的效果。 综上所述变更管理在稳定性建设中起着至关重要的作用。通过合理的变更管理措施我们可以降低变更带来的风险确保系统的稳定性和可靠性。只有在充分重视和有效实施变更管理的前提下我们才能够建立一个稳定、可靠的系统。 参考 信通院稳定性建设指南