工程师硬通货系列五:让你的架构专业

职场硬通货系列》首发于公众号“职场嘚吧嘚”,每周三更新,欢迎大家关注转发!


明明很努力,却没有什么成绩?知道自己要学的很多,但不知从何入手?对于普通人来讲,决定个人职场高度的是自己的优势上限,那么如何利用好自己的时间,去学习知识和技能来提高自己的优势上限,就是大部分人最大的难题!职场硬通货来帮你寻找答案!职场硬通货系列旨在帮助在职的工程师们明确行业边界,了解自己应该学习哪些技能,如何掌握这些技能;不断提升核心竞争力,让职业发展的道路越走越宽,从而成就更好的自己!

紧接上文,架构是演进出来的,不是设计出来的;演进中的沉淀是你快速复现成绩的关键。思考的沉淀是多维度的:定量地,如何把当前架构设计好,类似的问题通过哪些点可以快速呈现一套架构;定性地,用什么样的标准来衡量一个架构,怎么使架构变得更优秀,造福更多的人。

思考的越深,沉淀的越多,也就越有价值。我们做过 1w 个架构不一定就厉害;但是把 1个事做到极致,去挖掘足够多的点,就一定会厉害。


一个架构,哪怕是一个不大的工程,可以供我们思考的东西也有很多……


首先,如何让它保持活力,衡量架构的最佳标准是生命力,怎么能让它变矬的慢些?很大程度上架构是设计出来让别人用的,而不是一直只有作者在编辑。一个正常的工程架构应该会有三个角色:creator(设计架构的人)、updater(为架构增加 feature、增加业务策略的人)、reader(阅读理解架构的人)—— 而且一段代码应该是读的频率大于写的。

所以,我们的架构也好,代码也罢,应该是对读友好的。绝对不能有任何一段玄学代码,只有作者写的那一刻知道他在干嘛,架构尤甚。


一个好的架构是面向合作的,要让读的人、用的人舒服。

首先,代码结构需要清晰,降级阅读成本低,新的 feature 可以快速定位变更的位置。最好有 func 的 demo,updater 可以快速实现需求,并且融入架构。最佳的效果,让其它的人读起来新的代码没有突兀,好像它原来就在那里了。

当然,理想的状态是少数,架构设计的初期不可能 cover 所有未来需求 —— 那就需要架构易变,永远能让新加的逻辑不显突兀。

重点,通过架构的设计机制,可以保证设计思想的传承。架构能力不足的人,写的代码或许可以写的很漂亮,但融进整体后显得很笨拙。当然,可以有 CodeReview 去阻挡一下,但是人治永远是不可靠的:作者不在了,作者没精力了,架构就会任意起飞。在规范的有效性上,机制 > 文档 > 口头。


一个好的架构无处不体现着设计原则,而且原则尽力易懂。写的人、用的人、读的人,三类最小的信息 GAP —— 同样这个思路也可以用于 function、module 的设计。

比如,我们要保证函数签名直抒其意,尤其是 public 接口。慎用重载、继承,这些让架构变矬的最佳推手。懒人错用:现成代码乱 copy能不传的参数都不传,逻辑不符合预期;debug 时迷惑,耽误时间不能快速定义到真正逻辑跑来跑去。

比如,更多融入设计模式的价值,一些成熟的设计方案 & 命名策略:无论你搞一个多么新的东西,一定要让他尽量旧!能用人听懂的话说,就不要自己造词。我们需要一个工厂类,那就 xxxFactory 而不是 xxxMaker。


一个好的架构是多重视角的,模块解耦、团队解耦、运行高效。

首先在模块视角,“”式设计。横向,模块边界清晰,高内聚低耦合,模块之间通过 interface 通信。规范代码作用域,不能改一行代码带挂一片,修一个小 bug 引入一个大 bug。纵向,业务流程清晰。方便业务迭代,方便功能降级,方便新业务扩展。比如,策略驱动、配置化。控制层收敛,降级要降的干净,迭代要迭代的透亮。

然后在团队合作视角,对于一个较复杂的业务,团队可能有不同的分工:有些人专注于架构优化,有些人专注于策略迭代。基于上述模块视角的“井”式设计,可以把业务高频迭代 & 替换的模块独立出来。架构同学维护架构层,策略同学维护策略层。架构同学只需要关注下策略代码的性能,完全不用担心这些插件会破坏架构的设计原则 —— 保证了架构的生命周期。

另一方面,还要注意运行视角,核心就是性能:怎么让单机服务更多请求。随着业务量级变大,资源成本将是一个不容小视的问题;同时,请求 RT 直接影响用户体验更是不容轻视。那就需要重新审视运行模型:

  • 最简单的模型,如 PHP 的 one process for one request,每个请求使用单独的进程,以串行、同步的思路编写业务逻辑,优点是 code 写的舒服。进一步,可以使用进程池,减少创建频率。

  • 稍微好些的模型,如 apache 的 one thread for one request,其实是上一个模型的简单优化,因为进程创建成本太高,进而同样可以用线程池减少线程创建。但由于没有进程的销毁,内存问题便需要格外重视。

  • 更好的线程模型,one thread for one sub-request,其实是上一个模型的优化。把一个 request 切分成多个阶段,下一个阶段等待上一个阶段,而阶段内的逻辑是可以并发进行的(比如多个 rpc 一起请求)—— 提高了执行效率。

  • 异步模型,如 golang/redis/nginx:  epoll 驱动、dag 驱动、协程驱动。进一步优化,将 request 切成更小的单元,每个单元建立依赖关系 —— DAG 图:一旦依赖就绪,下游节点即刻执行。DAG 没有了等待,理论上可以得到最快的执行效率。协程的引入,又进一步减少了去线程的空占。不被执行的节点根本不会占用 thread 资源,进一步减轻了调度压力。


做到上面的点,就是一个好的架构了吗?不止做内容,还要做周边!你的框架如此优秀怎么让其他团队能够快速接入?快速上手?如何运维?不易用就没人用。

我们需要一个简明、清晰的介绍文档,一个好的 demo,一个简单的测试工具…… 回归第一章,我们如何更好的可视化,更好的运维:比如,完善的 log (info 级别、error 级别、debug 级别)、完整监控链路(出现报警怎么快速定位问题)。

进一步,你的框架怎么接入别人的系统。比如,一个公司已经有了一套完成的监控体系,数据上报方案,数据库接口等。我们的框架怎么方便的融入?这里回到团队合作视角,我们或许就需要把架构层更进一步抽象出资源层以及定制化的接口……


架构是一件艺术品,是可以 share 出来把玩的。要把自己想象成艺术家,你的作品就是你的身家。


下一期 

工程师硬通货系列六:系统知识,纵横捭阖

全部评论
工程架构还是非常不错的,有发展
1 回复 分享
发布于 2022-07-17 10:54

相关推荐

11-24 00:11
已编辑
广东工业大学 算法工程师
避雷深圳  yidao,试用期 6 个月。好嘛,试用期还没结束,就直接告诉你尽快找下一家吧,我谢谢您嘞
牛客75408465号:笑死,直属领导和 hr 口径都没统一,各自说了一些离谱的被裁理由,你们能不能认真一点呀,哈哈哈哈哈😅😅😅
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务