解析软件系统稳定性的三大秘密:制度纪律、思想之道、实践之术

何谓系统稳定性?
控制系统理论认为:系统受到某种干扰而偏离正常状态,当干扰消除,如果系统的扰动能逐渐收敛并最终恢复正常状态,则系统是稳定的,反之,系统偏离越来越大,则是不稳定的,所以,稳定性是系统抗干扰和返回平衡状态的能力。
对于经典的传递函数的软件系统,一般我们讲的稳定指的是BIBO稳定,即有界输入有界输出稳定。一个系统如果对任意有界输入得到有界输出,它就是BIBO稳定的。一句话,稳定的系统对于各种输入需要有符合预期的输出。
随着软件复杂性越来越高,稳定性的保障越来越难,随着服务规模越来越大,稳定性的重要性越来越高。
我们的软件需求和计划很少考虑非功能部分,然而软件的结构和实现却有非常大的比重服务于此,这也许是软件项目计划经常延期的重要原因。
如何保障稳定性?
虽然理论上没有绝对稳定的系统,但我们依然可以有所作为,使我们设计和开发的系统在生产环境接近稳定运行。
从大的方面讲,稳定性保障,可以分成3个部分:
制度纪律
编码规范、代码提交门禁
Code Review
静态代码扫描,动态代码分析
Unit Test、压测
灰度发布、Rollback、应急预案
监控
复盘、故障树分析
思想之道
保持简单、降低复杂度
不(零)信任、面向失败设计
实践之术
冗余设计(数据、计算、带宽冗余)
快速恢复设计(无状态设计)
容错、灾备
隔离
过载保护(限流、熔断、有损服务)
错误重试策略,避免流量风暴
去关键路径、去中心化、避免单点故障
负载均衡(load balance)
看门狗设计
安全编码
制度纪律
通过制度去规范操作和行为,通过纪律去约束大家在框架内活动,被证明是保障稳定减少出错行之有效的方式。
纪律是关键,只有持之以恒的遵守制度,才能避免方法和规定沦为空谈。
但制度和纪律只是划出质量底线,只能解决大多数稳定性问题,难以发现一些隐匿的问题,需要配合思想之道和实践之术,持续改进软件质量,才能全面保障稳定性。
思想之道
道是大的层面,它具有全局性的指导意义,我从众多的指导思想里,挑选最重要的两点:保持简单和不信任/面向失败设计,展开来讲。
1. 保持简单
复杂是稳定性的天敌,保持简单即保持稳定。单一职责,功能清晰即是践行保持简单。
把简单的东西搞复杂很容易,而化繁为简则堪称化腐朽为神奇。所以保持简单并不是低要求,它需要你透过表象洞悉事物本质,用最直接最土味的方式解决问题,做技术的同学有一个奇怪的癖好,喜欢把自己最近琢磨的东西用到项目中,不然总有锦衣夜行的感觉。
2. 不信任设计、面向失败设计
不信任设计又叫零信任设计,和面向失败的设计有相似之处,其本质都是防御性编程思想。
不信任设计思想假设系统依赖的上下游都不靠谱,假设周围都是坏人,假设攻击无处不在。
网络服务需要对客户端请求参数做严格验证,不仅检查合法性,也要验证NaN。游戏开发有一句名言:假设客户端的数据都是假的。
进程内的函数调用大多时候很安全,会有可预期的结果,但如果跨进程调用(RPC)的可靠性则会低很多,有可能超时,有可能丢包,有可能失败,调用者必须意识并处理好各种异常情况,是重试?如果重试的话重试多少次?重试之间的间隔应该怎么确定?请求的上下文怎么保存和恢复?
我们要正确理解不信任设计的内涵,避免用力过猛,警惕借面向失败设计之名行无效编程之实,比如已经对客户端请求数据做了严格校验,在服务器处理过程中,重复检验,比如已经对接口入参判空,在内部调用过程中重复判断。这会降低代码浓度,混入大量无效代码,损伤可读性和执行效率,本质上是违背“保持简单”原则的。
实践之术
术是局部层面,它是实践经验,牵扯方方面面,难以尽数枚举。
如果以文章写作类比软件开发,谋篇布局相当于设计层面,设计层面要致广远,遣词造句相当于实现层面,实现层面要尽精微。
所谓千里之堤溃于蚁穴,防微杜渐功德无量。
1. 冗余设计
冗余设计指留出安全余量,冗余包括数据冗余、计算冗余、带宽冗余。
数据冗余指一份数据多个副本,一主多备。
计算冗余,比如服务实例的QPS极限是10K,但实际上我们会按5K跑,这样,即使出现流量超速增长,我们依然有反应时间。
2. 快速恢复设计(无状态设计)
互联网服务很多都是无状态设计,服务实例只是逻辑的盒子,后面跟着分布式一致性数据库,这样能极大简化设计,即使实例挂了,客户可以很容易迁移到其他服务实例执行,而有状态设计则要复杂难搞得多。
3. 容错、灾备
容错指我们的系统要有一定的错误容忍能力,这意味错误发生,我们要能查错、检错、避错、甚至改错,只要可能,我们就要吞咽错误。
灾备这个大家耳熟能详,主从设计,异地备灾,目标都是为了应对各种极限情况。
4. 隔离
隔离本质上就是说如果故障发生了,如果故障发生,而又不能吞咽,那也应该隔离避免错误传播扩散,千方百计缩小影响范围,相当于感染新冠要被隔离起来。容器化等技术为隔离提供良好能力支撑。
5. 过载保护
熔断
熔断机制不止软件设计独有,股市也有,我甚至怀疑软件的熔断机制是从股市学来的。
限流
系统设计要做好资源耗尽、资源不够用的情况,如果服务请求超过服务能力,那就应该限流,这应该作为一种配置,或者自动执行的策略。
这个跟地铁限流差不多,处理不了,那就排队。
有损服务
有损服务我印象中最先是腾讯跟海量服务的概念一起提出来的,指如果出现服务能力不够,不能为所有客户所有业务提供服务的异常情况,那系统有所取舍,尽可能保持业务运行,减少损失,比如在微信服务器在处理能力有限的情况下,可以优先保消息发送,而关闭朋友圈服务能力,比如直播业务在带宽有限的情况下,应该降低码率减少清晰度,而不应该拒绝服务。
有损的意义就是有损失,有损伤的意思,它是一种思想,是退而求其次,是不得已而为之。
6. 错误重试策略,避免流量风暴
如果设计一个ToC服务,在客户大规模断连的情况下,客户会重连,重连失败再连,如果重连尝试的频率不控制好,正常客户端重连有可能演变成对服务器的大规模攻击,打爆一台服务器,又去灭另一台,这太吓人了。
可以参考kernel TCP的重连策略,有最大尝试次数,而且重试间隔是逐渐拉大的。
7 去关键路径、去中心化、避免单点故障
企业不要关键先生,关键先生会成为瓶颈,软件也不能把宝压到一个地方,去中心化去集中式,没什么难理解的。
8 负载均衡
load balance其实就是分担压力,LB要避免倾斜,有多种LB算法,比如RR,比如一致性hash,各有利弊,有兴趣可以研究下。
LB不仅限于服务,进程内的多线程可能也会需要考虑这个问题。
9 看门狗和心跳机制
可以参考kernel的watch dog,其实就是看护机制,检测错误并努力掰过来。
10 安全编码
安全编码是一个职业程序员的基本要求,安全编码规则很多,很细节的一些规矩。这个可能跟语言相关,如果是C++相关的可以参考:C++的门门道道
C相关的规则要少一些,我顺手列举一些。
比如要注意初始化。
比如全局变量不要有构造顺序的依赖。
比如慎用强转,强转等于接管了编译帮你做的类型检查。
比如理解线程安全函数,理解可重入的概念,理解信号机制。
比如要避免死锁,理解ABBA锁理解自死锁。
比如要谨防资源泄漏。
比如处理好内存分配失败的情况,理解野/悬垂指针。
比如要处理好边界,防止越界,溢出。
比如内存拷贝要避免内存重叠,理解memmove的用途。
比如理解递归的低效和栈的大小限制,避免爆栈。
比如建议使用STD安全版本函数(_s+n)版本。
比如了解unsigned < 0导致死循环的情况。
比如了解浮点数跟0比较的问题。
比如理解整型数据溢出和反转。
比如不要返回临时变量的引用或者指针,理解栈帧动态伸缩的原理。
比如理解做好把关检查的必要性,包括系统把关和模块把关。
小结
最后来读段经典:《系统化思维导论》一书中引用冯诺依曼的话写道:如果你观察一些自动装置,不论它们是人类设计的还是自然界本来就存在的,你通常会发现,它们的结构很大程度上受控于它们可能失效的方式,以及针对失效所采取的防御性措施(多少有些效果),说它们能预防失效有点夸张,它们不是能预防失效的,只是被设计成试图达到这种状态,这样至少大部分失效都不会是毁灭性的。所以,根本谈不上消除失效,或完全消除失效带来的影响。我们能尝试的只是设计一种自动装置,在大部分失效发生时仍能继续工作,这种装置减轻了失效的后果,而不是治愈失效,大部分人造的和自然界存在的自动装置,其内部原理都是如此。
软件开发
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们微信:Informat_5 处理,核实后本网站将在24小时内删除侵权内容。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系邮箱:hopper@cornerstone365.cn 处理,核实后本网站将在24小时内删除。
相关文章推荐
织信低代码开发“核心引擎”与“拓展能力”介绍
低代码平台不能只看表单、流程和页面。真正进入企业管理场景后,更重要的是底层能不能承载数据、权限、流程、集成、自动化和AI能力。
织信低代码平台的能力,可以分成两部分:核心引擎和拓展能力。核心引擎决定系统能不能搭起来、跑起来;拓展能力决定系统能不能接入更多业务场景,持续扩展。
一、核心引擎:支撑企业应用运行
1、数据建模引擎
织信以数据模型为基础,支持数据表、字段、记录、关联关系等能力。企业可以围绕客户、供应商、项目、合同、物料、设备、工单、库存等业务对象搭建系统,而不是只做一张张孤立表单。
它的价值在于:先把业务数据结构建清楚,再承接流程、权限、报表、接口和AI能力。这是织信区别于轻量表单工具的重要特点。
2、流程自动化引擎
织信提供工作流能力,支持审批、任务、变量、事件、子流程、多实例、多版本等机制。企业可以用它搭建采购审批、合同审批、项目立项、设备维修、费用报销、异常处理等流程。
流程自动化的价值,不只是线上审批,更是把责任、状态、节点和处理记录留在系统里,让业务可追踪、可复盘。
3、权限治理引擎
织信支持组织、部门、用户、角色、应用成员、应用角色等权限管理能力,可以根据岗位、部门和业务场景配置访问范围和操作权限。
企业系统里,不同部门看到的数据、能修改的字段、能审批的节点都不同。权限治理做细,系统才能既安全,又能正常协同。
4、自动化与脚本引擎
织信支持自动化、定时任务、监听器、脚本、HTTP请求等能力,可以在数据变化、流程变化或时间条件满足时自动触发动作。
例如自动提醒、自动校验、自动同步、自动生成记录、自动调用接口。这样系统不只是记录工具,也能参与业务执行。
二、拓展能力:支撑复杂场景扩展
1、系统集成能力
织信支持WebAPI、开放接口、HTTP、JDBC、消息队列、第三方集成、单点登录等能力,可以连接ERP、MES、CRM、OA、财务系统、钉钉、企业微信、飞书、LDAP、数据库等系统。
这让织信既能搭建新应用,也能作为企业系统之间的协同层。
2、界面与组件拓展能力
织信提供表单设计器、组件设计器、自定义组件字段、自定义视图、仪表盘、网站页面等能力,可以根据不同业务场景设计页面、看板和操作入口。
这使企业既能快速搭建标准应用,也能针对复杂需求做个性化扩展。
3、AI Agent能力
织信官方文档将其定位为企业级AI开发平台,强调数据建模、流程自动化、权限治理、系统集成与AI Agent能力。
在织信中,AI能力可以结合知识库、专家、技能、智能体、设计器智能体等模块,参与应用搭建、数据分析、流程辅助和业务处理。
更重要的是,织信的AI能力建立在数据、流程、权限和系统集成之上。这样AI进入企业系统时,能明确数据范围、操作边界和审批要求。
三、织信的独特之处
织信不是单点工具,而是企业信息化AI开发底座。
它既有低代码平台常见的表单、流程、权限、报表和自动化能力,也具备企业级系统需要的集成、部署、运维、SSO、信创适配、私有化部署等能力,同时把AI Agent纳入应用建设过程。
因此,织信更适合有复杂业务系统建设需求的企业。比如项目管理、OA、ERP扩展、MES补位、WMS、SRM、CRM、设备管理、人事管理等场景,都可以基于织信进行搭建和扩展。
简单来说,织信的价值在于:把数据模型、业务流程、权限治理、自动化执行、系统集成和AI能力放在同一个平台里,让企业系统搭得快、管得住、连得上,也能持续扩展。
各行业用户的共同选择







