Categories
程式開發

浅谈业务系统设计哲学


作者:易振强

1.  背景

设计和开发业务系统是一个很“神奇”的工作,我已经在软件行业工作多年,遇见过各种类型的业务研发工程师,干我们这行的人都知道,软件开发入门门槛没像外行人所认为的那样高,当然,这个行业也绝对不乏“高手”。再回到之前说的,为啥我会认为设计和开发业务系统是一个很“神奇”的工作?因为“开发工程师”这职位应该是软件行业人数最多的群体,我们如今在PC或者手机上用到的各式各样的软件都离不开他们,在这一职位上,我们能结识各式各样的人,所谓历经人生百态。

可能有很大一部分工程师认为开发业务系统很简单,所以对这一日常工作内容不那么感冒,他们常常用自己“六七分”实力来做设计、写代码,所以也容易导致工作七八年,写过“一麻袋”的业务系统,但自身能力提升较慢,最后自我埋汰到:“写了这么多年业务系统代码,都把自己都写废了”。

我们当然不希望自己是这样的结局。

2.  业务系统的设计哲学

2.1 可维护性是根本

系统也需要人来“保养”代码可读性很关键打造可扩展系统

把这个放第一条,有些人会感到意外,如何理解这里的“可维护性”?简单来说就是我们的业务系统——

1.能否在当前组织模式下满足业务的发展而进行快速迭代;

2.能否为了承接增长的流量而横向快速扩容;

3.能否支持团队内多人协作维护;

4.能否支持快速对线上问题进行定位和止损;

5.运维成本能否可控。

可维护性和系统的架构设计和编码实现高度相关,这里很有必要说下设计的实现部分——编码,编码是开发阶段很重要的一环,其实很多一线研发工程师的能力,在写代码时就能“高下立判”。

那么业务系统编码阶段最重要的是什么?这个问题很多人会有不同的答案,但我这边的答案只有一个:

即——在正确实现功能的前提下让代码具备较高的可读性。我在进行CR时,会非常看重这一点。代码可读性并不等同于你的代码一定要写的很短或很精炼(但是短代码或格式规整的代码确实能降低阅读者负担,让阅读者赏心悦目),而是说一定得说明这段代码为什么这么做(加注释也好,代码能自说明也好),特别是某些“特殊逻辑”!

之所以在这里特别强调这一点,是因为业务系统总在随着业务不断在迭代,“铁打的代码流水的猿”,只要业务活得够久,你永远不知道下一个维护这套系统的人是谁、是哪个团队,而系统的可维护性、可扩展性、稳定性、重构等,强依赖的是后续继承者能看懂你写的代码,千万不能造成:我很懂业务,但我看不懂你代码为什么这样写,尴尬的是我又不敢改。

特别怕一些“天赋异禀”的开发者,用“很巧妙”的思路将业务系统实现的只有他自己能懂,而其他人“望而生畏”,导致后续遭人诟病,所以我们需要记住,只有学习成本低,系统才能谈可维护性。

2.2 稳定性是底线

充分拆解背后的非功能性诉求核心资源和非核心资源需要隔离尽可能做到自动降级实现异常出口

任何业务系统不能只满足基本的业务功能需求,很多非功能性需求产品和业务方同学不一定会直接展现在PRD上,需要我们研发工程师或架构师来“拿捏”,常见的非功能性需求比如系统稳定性、吞吐量、性能、响应时间、时效性、数据安全性、数据一致性等。这其中,系统稳定性是最常见的非功能性需求,也是很多大型互联网公司业务方能直接感知到产研的一面,一旦系统故障被用户投诉,业务方第一直觉就是技术那边出了问题。

系统稳定性建设的抓手很多(参见:稳定性全系列文章),一线研发同学在设计和实现时,一定得有自己的原则和意识,比如核心接口和非核心接口的资源隔离(例如线程池、部署隔离等);弱依赖做到真正的弱依赖,出问题不能影响核心链路(设置合理的超时时间,能做到自动降级或熔断最好);关键资源一定得受保护(比如借助SDS、Sentinel、Hystrix等)和监控;异常情况得可看、可感知(配置合适并且有效的告警策略和大盘)。

系统稳定性犹如工程师的底子,不能随便拿出来到处说,但需要花精力花功夫不断去维护和巩固,一旦没做好,鬼知道别人背后咋说你。

2.3 多参考业界的成功模式

GoF的23种设计模式面向对象的X大设计原则学习业界的成功或失败案例

合理利用设计模式,遵循面向对象的设计原则,有了这些大家熟知的模式,会降低整个业务系统的学习成本,无形中也优化了系统的内部结构,提升了系统的可扩展性。

研发工程师或架构师得有自己的独立思考能力和创造力,但创新这东西我们不能强求,很多成功的设计或方案,都是在前人的成功或失败经验加上自己的一些因地制宜的“变化”而“长”出来的,我们在做业务系统架构设计时应该多看看行业标杆如何做,他们这样做的效果是什么?目前他们遇到的问题是什么?他们的方案有哪部分是不适合我们的?

有了这些,哪怕是“管中窥豹”,根据以往经验,我们也能看出个所以然来。

2.4 选择恰当的设计方案

中间件的设计方式不一定适合业务系统方案选型要考虑团队的技能水位方案要符合项目当前的发展阶段重点评估方案的维护成本从多套方案中选择最合适的方案

一个系统的架构是客观存在的,在业务系统进行架构设计时,一定要结合业务形态、非功能性诉求、当前组织架构、团队技能水位、现有基础设施、运维资源等。

业务形态

要考虑如下问题:服务的可靠性和准确性是否会影响用户的生命财产安全?服务的用户人群是什么?服务是否有早晚高峰期?服务是否要存储大量数据?服务流量如何?

非功能性诉求

即非功能性需求,架构设计时一定要充分挖掘隐藏在业务背后的一些需求,比如给心跳起搏机开发软件系统,其他的可以不提,但一定要绝对的安全和可靠。

当前组织结构

我们当然应该避免多个团队去维护一个系统,所以系统拆分力度一定要和组织结构相当或细于组织,这本质上和”康威定律”也有些关系。

团队技能水位

这是一个很残酷的现实,团队应该去维护和发展符合自己能力的系统,如果某个框架或某项技术是该系统架构设计的关键,而这个框架或技术是团队短时间内无法有效承载的,那这就不是合适的架构设计。我们不能把屠龙刀才能砍的架构设计,去丢给手里只有菜刀的程序猿来实现。

现有基础设施

底层设施决定上层建筑,我们需要有效的利用周边的基础设施,如果没有MQ的使用经验,但我们的架构设计却强依赖MQ,除非你希望借这个业务系统的实现来“培养”一些MQ专家出来,那么我们架构设计时最好将MQ换成另一个“现成”技术套件。

运维资源

这也是一个残酷的现实,我们很多架构设计需要考虑运维团队,甚至很多架构师在设计系统时,会主动去和运维同学沟通,参考他们的建议,这样做没错,有好的运维团队支持,你的系统成功了一半。

业务系统和中间件系统的设计和实现思路有差别,中间件系统可以“无止境”的去打磨系统的性能和扩展性,很多技术大牛在给中间件添砖加瓦时怎么巧妙怎么来,所以有时候中间件代码的可读性并不高(当然,不排除某些中间件产品在这方面做的很好),往往中间件系统关注的点和业务系统的关注点大相径庭,尽量不要以中间件的思路去写业务系统,否则容易走极端。业务系统的设计和开发一定得带着理解业务的思路去做。避免过度设计或过于前瞻性设计(如果真有必要,这些可以放到二期、三期去做),不然会给系统实现增加负担,得不偿失。如果拿捏不准,可以先给出多套设计方案,然后再仔细分析,权衡利弊来做选择。

这里有个遗留问题,就是怎样的系统架构设计才是合格的设计?我认为,只有能抓住现阶段业务成败关键点的设计才是合格的架构设计方案(就好比只有准确抓住社会主义初级阶段社会的主要矛盾,才对党和国家工作重点的转移、推动社会生产力的发展和社会全面进步,具有重大的理论意义和实践意义)。所以,这也从侧面验证了,架构设计可以“扣”细节,只要这些细节会影响系统建设的成败,那么架构设计就应该包含它。

3.  总结

好的设计方案一定要被大多数人所接受和理解的,那些只有少数一两个人能看懂的方案,要不另辟蹊径(风险高),要不其实是过度设计(性价比低),当然,我们说的是一般情况,在某些业务领域,确实是存在一些“最佳方案”。

更多精彩文章,请扫码或长按下方二维码阅读原文

浅谈业务系统设计哲学 1