写点什么

浅谈业务系统设计哲学

发布于: 2020 年 08 月 27 日
浅谈业务系统设计哲学

作者:易振强

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.  总结

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

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



发布于: 2020 年 08 月 27 日阅读数: 1384
用户头像

公众号:普惠出行产品技术 2020.07.31 加入

这里是滴滴出行旗下普惠产品技术团队对外分享的窗口,普惠出行支撑滴滴代驾、货运等业务,建设了NodeX、Dokit、卡梅隆等开源项目,始终秉承聚心成事、聚气育人的原则。欢迎各位技术同仁一起交流,共同成长~

评论

发布
暂无评论
浅谈业务系统设计哲学