在系统设计阶段考虑全面很难,有许多人倾向于把整个设计分成若干阶段,在迭代中完成整个设计,这本身是非常好的,但是,就如同“先做出来,以后再优化”这样的经典谎言一样,本身并无错,只是许多程序员都不习惯于真正的迭代设计和迭代优化。举例来说,有一个日益复杂的类,每个人都修改一点点,一直到最后都没有人愿意去做重构,大家的心态都是一样的:“我只修改了一点点,为什么要我去动那么大的刀,于我没有任何好处”。我不在这里谈论这一问题的解决办法,我倒是想说,在开始阶段考虑清楚问题在多数情况下还是很有好处的,设计考虑得越是清楚,在后续阶段代码可以承受越多的变更而不腐朽。
再做系统设计的时候,我们常常会这样说:“一般情况下”、“99%”和“基本上”等等。如果你发现这是在悄悄地,或者潜意识地避谈问题,可就要小心了。有时候你可以找到根据,“事情不会那么坏吧”,“不会那么不凑巧吧”,在系统设计阶段尽把事情往好的方向想可未必是件好事;也许更多时候会觉得这是直觉,总觉得某一处设计别扭,不合理却有说不出强硬的理由来,最多只能抱怨一句“通常它不应该是这样设计的”。这种情况发生的时候,请千万不要放过它,很多次,在系统上线以后,最初的问题或者潜在的问题最终暴露出来,而这样的问题很多在系统设计阶段都是有端倪的。
例子1:用户行为记录的持久化
以前我参与做过这样一个系统,用户的行为需要被记录到数据库里去,但是每条记录发生的时候都写一次数据库觉得开销太大,于是设计了一个链表:
- 用户的行为会首先被即时记录到链表里面去;
- 每十分钟往数据库里面集中写一次数据,然后清空链表内的数据。
看起来确实可以实现需求,可是,这样的设计有什么问题?
这样的设计当时居然没有受到系统设计评审的人的质疑,我实在觉得奇怪。我想很多人都可以看得出潜在的问题:
- 清空链表数据是使用时间条件触发的任务来完成,换言之,无论这十分钟内如果事件暴增,也无法触发链表清空的行为,链表很容易变得非常大;
- 清空链表的任务如果执行过程中出了异常,甚至仅仅是处理速度受到阻塞,将直接导致链表数据无法得到清空;
- 如果往数据库里写数据和清空链表的行为需要锁定链表,倘若链表很大,或者写数据库过慢,都会导致链表写行为被阻塞。
这些问题当然在明确的情况下可以得到规避,但是毫无疑问,这样的设计充满了潜在的危险。事实上,最终这样的问题也确实发生了,导致的结果是链表巨大,撑死了整个系统,OOM,系统失去响应。
例子2:HashMap并发访问导致死循环
非常常见的并发访问HashMap的问题,我也遇到过。有潜在的危险导致HashMap死循环,表现就是CPU占用100%,而且这样的问题是不可逆的,问题的原因分析我相信大家可以在网上搜得到很多文章,我就不啰嗦了。我印象深刻的是当时定位完问题,向犯下错误的程序员解释原因的时候,他居然还说:“这个HashMap的读写很不频繁,哪有那么巧的事?”,这就是侥幸心理,即便知道了问题依然不愿意做出修正。
例子3:摘要算法的冲突问题
类似的问题还有,使用摘要算法的时候,比如MD5,我在做一个系统,使用一个中心集群缓存,使用一个巨长的字符串的MD5摘要来做key,好处在于key的长度可以大大缩短,但我们都知道,任何摘要算法都会使得结果字符串存在冲突(重复)的可能,即源字符串不同,但是摘要字符串相同,虽说用统计的话来说,单纯两个字符串发生这种情况的概率低到几乎不可能发生。但是我们依然需要谨慎,尤其是在数据量巨大的情况下,一旦发生冲突,要有解决办法(比如把源字符串放在缓存条目的结果对象中,在缓存条目命中,正式取出返回前,再进一步比较源字符串以确定100%的准确性),或者至少必须要能够承担风险。
例子4:文件处理后续流程的两个问题
最近有一位同事向我们介绍了他最近处理的一个问题,这个问题是,用户会上传一个多行的文件,比如文件有一万行,每一行都代表一条待处理的数据,在数据正确的时候,一切都正常;倘若有一行数据处理发生错误,会自动发送一封邮件通知,看起来似乎很不错的系统。但是这个时候问题来了,有一次文件的处理错误过多,导致一口气发送了几千封邮件,变成了邮件洪水。而在他介绍这个系统设计的时候,我们留意到了其中存在一个时间条件触发的任务,任务基于两个数据库的数据执行,这两个数据库的数据同步是单独完成的,因此可能存在数据不一致的情况,并且在这里假定在数据更新的一小时以后,两个库的数据就会一致了。这其实就涉及到了两个问题或者隐患,一个是邮件处理和发送的数量缺乏控制,另一个是用假定的时间来保证数据的一致性。
例子5:单点故障问题
单点故障问题也是很常见的会导致服务失去的问题,出了问题所有人都知道原因,但是有时候就是很难在系统设计阶段识别出来。以前我们给电信运营商提供服务,很多电信运营商通常有钱(比如国内的三家垄断巨头),不太在乎成本。服务器用的单板几万块钱一块,备了几十块,文件存储是一个大型的磁盘阵列,数据库是IBM小型机双机备份(PS:IBM的设备其实挺不可靠的,听维优的同学说,保修期内屁事儿没有,保修期一到一台台IBM的机器开始坏,搞得像定时炸x弹似的),当时唯独忽略了单点的负载分担硬件——F5,F5挂掉的时候,工程师都傻了眼。
例子6:文件不断写入导致磁盘满的问题
文件写满磁盘导致空间不够的例子也非常常见,绝大多数写文件的场景大家都会留意到,并且在系统设计评审的时候都会有人站出来问,“xxx的文件写入是否是可控的?”。但是,由于文件写入的场景非常多,还是有很多情况被忽略。比如JVM的GC日志的打印,这样的文件可以协助定位问题,但是如果不设置文件上限大小参数,就有导致磁盘空间不足的风险;还有日志文件,绝大多数系统都有日志文件压缩或者日志文件转移的脚本,但是和前面提到的例子1一样,一方是生产者,一方是消费者,消费者出了问题,就会导致数据堆积。如果这样的文件处理脚本执行出现问题,或者在系统压力大以及系统异常情况频繁的时候,日志疯涨,来不及及时把日志文件转移出去,导致日志文件把磁盘撑满。通常对于要求比较高的服务,磁盘空间监控是必要的。
例子7:服务器掉电以后的快恢复
再说一个问题,这个问题是从一个技术分享中流传开来的。亚马逊网站的数据都是页面服务器先从缓存服务中获取数据,通常这个命中率很高,如果获取不到数据或者数据过期以后再到数据库里查询。这样的模式非常常见,我们也总能看到很多技术报告里面写平均的缓存命中率能够达到百分之九十多,可以飙到多少多少的TPS,为此可以节约多少多少硬件成本。初看这样的设计真不错,但是很容易忽视的一点是,这样的数据是建立在足够长时间,以及足够多统计数据的基础之上的,但是在单个时间段内,缓存命中率可以低到难以承受的地步,导致底层的数据服务直接被冲垮。有一次亚马逊机房突然掉电,在恢复的时候把网页服务器都通上电,这时候缓存服务还几乎没有缓存数据,缓存命中率几乎为零,于是大量的请求冲向数据库,直接把数据库冲垮。外在的表现就是,掉电导致网站无法提供服务,短期内访问恢复,随后又丧失服务能力。
软件当中有些东西和经验有密切关系,不像很相对容易提高的语言技能和算法,系统设计经验,尤其是对问题的预估很需要时间和项目的磨炼。我不知道这样的系统设计经验怎样才能快速积累,但是我想还是有一些常规模式可循,我不知道是否有比较经典的资料可以学习。另一方面,系统设计真是一个细致和谨慎的活儿,不要随意放过那些潜在的问题,有时候甚至就是一点奇怪的感觉,或者是设计图看起来不那么协调和稳当,细究下去,还真能发现陷阱。如果你也有类似的经历,不妨谈一谈。
文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》
相关推荐
留人留心的薪酬设计考试题.doc
【教育精品资料留人留心的薪酬设计考试题.doc】这份文档主要涵盖了薪酬设计与人力资源管理的相关知识,涉及多个方面: 1. 薪酬问题分析:文档通过两个案例(《年会返岗率为何这么低?》和《涨薪之后满意度为何下降...
经典 非常感谢您留心我这份系统诊断报告,小菜鸟十万火急等待您的帮助! 该诊断报告由360安全卫士提供 http://www.360safe.com 诊断时间: 2008-12-10 13:44:18
谭一平留心皆学问.doc
本文旨在分析在汽车市场中,消费者应该特别留心的三种车型,它们分别是抵债车、重礼车以及翻新车,并揭示它们可能带来的安全隐患和后续问题。 首先让我们来聚焦于抵债车。抵债车是通过债务抵消的方式在市场上流通的...
- **《系统设计书》**: 记录了系统设计的整体思路和具体细节。 - **GJB438b《SDD》**: 规定了分系统设计文档的编写规范。 - **分系统在上游需求及方案中**: - 分系统的上游需求和方案设计是其设计的基础。 - 需要...
2. 薪酬问题案例分析:《案例-1》揭示了薪酬激励与市场信息敏感度的关系,《案例-2》则突出了薪酬调整后满意度下降的问题,这可能源于薪酬激励的定位不准确或激励体系的不完善。 3. 赫兹伯格的双因素理论:该理论...
综合来看,这个自定义指标结合了价格波动、移动平均线和速度变化等多重因素,通过可视化的方式展示市场趋势和潜在的转折点,帮助投资者识别底部区域的股票走强迹象,从而辅助交易决策。然而,需要注意的是,任何技术...
总结来看,制药用水系统的检查是一个全面细致的过程,其检查范围覆盖了系统设计、安装、运行的各个层面,以及日常的维护和清洁工作。通过这个培训教程的学习,参与者能够深入理解水系统检查的重要性,掌握执行检查的...
【企业留人留心概述】 企业管理的核心之一是留住人才,而这正是企业长期发展的关键。企业必须具备资金、知识产权和优质产品等基本要素,但在这之中,人才的竞争是决定企业生死存亡的重要因素。没有人才,企业无法...
教学设计的主题是“快乐小问号”,旨在培养学生的探究能力和好奇心,让学生学会留心观察生活中的常见事物,并对自然现象或生活中的问题有探究的兴趣。 教学目标: 1. 使学生留心观察生活中的常见事物,有好奇心,...
大家留心一下现在我们大多使用哪些种类的笔学习教案.pptx
物流系统模型是在物流系统分析和设计中的重要工具,它可以帮助我们更好地理解和认识物流系统,提高物流系统的效率和效果。但是,建立和应用物流系统模型需要遵循一定的原则和方法,以确保模型的准确性和可靠性。
对于那些得分较高的项目,表明儿童在该方面的行为或情绪问题较为显著,可能需要儿科医生、心理咨询师或行为专家的进一步评估和介入。 《Rutter儿童行为量表父母问卷》的广泛应用和认可,得益于其良好的信度和效度。...
要聆听那些对销售有利的信息,如行业动态、客户对公司和产品的正面评价,同时忽略不利因素,但也要留心客户的疑虑和问题。 2. **问**:提问是发现客户需求的重要手段。销售人员应提出能够引导客户思考、揭示其购买...
不考虑周全就轻易违约,可能会给你的职业声誉带来不良影响,因此如何处理与现有公司的关系,是需要慎重考虑的问题。 其次,当你的前领导跳槽到一个新的公司,并向你发出加入的邀请时,这种情形下的决策应更多基于对...
单位和个人必须制定消防安全制度和操作规程,明确消防安全责任人,定期进行防火检查,消除潜在的火灾隐患。这不仅是对自身负责,也是对他人和社会负责的体现。在日常生活中,我们应学会正确使用开关,避免火源与易燃...
【知识点详解】 1. “无字词典”指的是生活中的实际情况和自然现象,它帮助我们理解和运用词语。学会查“无字词典”,就是指在实际生活中观察、体验,通过情境来理解词汇的含义,例如,“大雨滂沱”形容雨下得非常...
首先,强加因果的问题需要辩手特别留心。在辩论中,我们经常会听到这样一种论调:“因为事件A发生在事件B之前,所以A是B的原因。”这种逻辑错误忽略了事物间复杂的因果关系,而是将它们简化为时间上的先后顺序,从而...
在公务员考试的行政职业能力测试中,成语理解与运用是备受青睐的考查领域。考生常常需在题目中灵活运用成语,以此来展现自己对语言的驾驭能力和对文化内涵的深刻理解。然而,成语并非单纯的文字游戏,它携带了丰富的...