大家或多或少都有接触一个已存在的系统,面对不是自己做的东西都有觉得上手有些困难,笔者想从自身的经验去谈谈如何快速上手一个陌生的系统。
打算从以下几个维度去分析落地:
业务知识
从业务角度去学习系统,说白了就是从客户视角看系统提供了什么功能,一定是人能理解的维度,这样也方便你去理解系统。从业务下手则你需要去找设计 产品 运营等相关领域的人去了解,也有些对外的产品文档,方便用户熟悉系统的,都可以入手去学习。 业务知识可以按如下分类:
- 市场定位如何?哪些用户
- 竞争产品有哪些,有些公司同样在做?
- 主要特性有哪些?解决啥问题?
- 未来发展方向是啥样的?
技术知识
技术知识主要是深入了解系统的实现了,你去熟悉系统就避免不了去熟悉系统的架构、实现、运维等。建议可以从:逻辑架构、物理架构、数据架构入手,这几个层面了解了你对系统有了从表面到内部的了解。
逻辑部分
逻辑架构着重考虑功能需求,系统应当向用户提供什么样的服务,关注点主要是行为或职责的划分。这里搞清楚各个模块的对应的角色以及功能、职责就OK了。逻辑架构的核心设计任务是模块划分、接口定义、领域模型细化。 关注点:
- 有哪些子系统或模块?系统之间是什么样的关系?
- 对外上下游接口有哪些?对接人是谁?
- 关键业务流程怎么实现的?用类图、序列图等方式表达出来。
开发部分 主要是代码架构,主要关注系统源代码、SDK、框架、中间件、工具包。 主要关注:
- 开发工具,以及代码git路径?
- 产品包如何编包,各部分如何划分,例如MVC架构
- 用了哪些工具包?如apache commons、guava
- 用了哪些中间件?如messagequeue,struts spring
- 依赖哪些平台?如中间件 flink 等
系统运行
运行架构的着重考虑运行期质量属性,关注点是系统的并发、同步、通信等问题,这势必涉及到进程、线程、对象等运行时概念,以及相关的并发、同步、通信等。 主要关注:
- 系统能支撑多少qps?峰值qps多少?
- 与上下游系统怎么交互的?rpc?http?同步还是异步?
物理架构
物理架构的设计着重考虑安装和部署需求,关注点是目标程序及其依赖的运行库和系统软件最终如何安装或部署到物理机器,以及如何部署机器和网络来配合软件系统的可靠性、可伸缩性、持续可用性、性能和安全性等要求。 主要关注:
- 系统如何发布部署?有哪些部署环境?
- 系统有多少台机器?
- 系统部署怎么部署的?关注接入层,部署方式,如集群部署、分布式部署等
- 有没有容器化?
- 有没有多机房部署?
数据模型
程序就是数据+算法,所以数据对理解系统很重要,你把数据模型理清楚了,就知道系统围绕数据如何做运转。包括数据表,缓存数据,数据存储方式等。 主要关注:
- 数据存储在哪?用了什么数据库,如oracle、mysql。
- 数据之间依赖关系
- 数据是否涉及大表分库分表等?
- 用了哪些nosql库,如kv存储?
- 有哪些数据同步任务?
- 大数据框架的使用情况如何?
系统维护
系统运维重点关注什么时候会出问题,出了问题怎么解决。 主要关注:
- 会出现什么严重问题,怎么止血?对系统的压力很大,这时候很容易出问题。
- 对关键功能是否有监控?需要看系统有配置了哪些报警项,监控了哪些方面。
- 出了问题怎么解决?日志在哪?是否有全链路跟踪?是否有一些紧急操作,比如开关配置、降级、限流配置。
- 系统有哪些坑?找开发同学回顾历史问题,以免踩坑。通过同事总结的case,或者与负责的产品、运营、技术与了解。系统总会有一些坑,需要把这些坑填上。历史代码经过多次迭代总会导致复杂度高(分支、嵌套、循环很多),存在设计漏洞,性能隐患等,很难维护,这些就需要我们去重构了。记住有一句话:填的坑越大,能力越大。
- 运营、客服反馈的主要关注有哪些?
上手实战
熟悉了系统的业务和技术后,就要实战了,通过实战进一步加深对系统的熟悉程度。实战最好的方式是定位问题,通过问题端到端定位,你会了解各个子系统,能把整个流程关联起来。其他如需求、bug等写代码的活动也会对系统熟悉起到很大作用。测试、上线等活动会让你对用户场景的功能部分做深入的了解。 以笔者经历的几个大厂的项目为例,具体讲讲如何上手实践,仅供参考: 项目1: 在阿里内部有很多的数据平台,其中有很多的大数据平台,有个内部平台叫 blink 在开源社区叫 flink。blink作为一个大数据通用平台,是提供了标准的API。你调用API去提交一个job 会给你返回一个唯一的jobId。这个jobId在blink 内部是严格唯一的(后续大数据分析都会依赖这个jobId)。有个这个jobId你就可以到内部的kepler平台去根据JobId 找对应的计算任务,计算任务会被拆分很多算子,每个算子 串联起来就是整个job流,计算任务里面有过程日志,也有异常日志,如果你感觉计算job没有输出,则你应该先看异常日志,是否有exception。如果无异常则你看整个流程里面各个算子是否有输入输出流量,如果串行流的输入输出对不上,可能是你的算子条件不对把流量全部过滤掉了,还有重可能就是计算任务堆积了,这个时候你要到job的统计信息看是否有时延。。。。 通过这个我想表达的时候,只有通过实践你才知道整个业务流程是什么样,以数据为载体整个流动原理是什么。 项目2: 再举个例子,笔者曾经搞过分布式存储系统,在HW以及阿里都搞过。分布式存储系统里面有很多系统节点: 比如 Ngix 业务系统 数据存储引擎 硬件存储等。如果看到的时候客户端时延很大,你该如何去分析?搞清楚这个问题首先就是要定界,数据流经这么多系统,到底是哪个环节出问题。怎么定界?可以用网络抓包啊 这些系统基本都是跨网卡的,你就可以用 wireshark 去在各个系统节点去抓包,通过对同一个报文的输入输出看时延 来确定系统是否有问题。但是一般来讲 网卡不是瓶颈,磁盘才是短板(这个就是经验问题了)。举个笔者曾经的问题定位案例:客户上传一个大文件,很卡。首先看盘的iostat统计发现不高,说明服务端的硬盘不是瓶颈,接着看服务端的网卡流量,利用率也不高,基本认为就是客户端问题,再看客户端的上传带宽发现确实只有xM,而客户说以前是xxxM。再看客户的SDK的调用,发现大文件他调用的接口用错了,不是并发上传的接口,是个单线程接口。问题很快定位。 通过这个问题想表达的是,通过实践增强定位问题的能力的关键是问题范围缩小,把可能性给缩小直到找到问题
小结
笔者认为,首先心态上不要刻意去在意这是别人写的代码,我熟悉很困难。就权且认为是自己很早之前写的代码,现在要重新把这个代码捡起来,需要回忆去恢复记忆。这个过程中可能就需要一些活动去辅助:比如问题定位,比如需求开发,比如代码重构等,在这个过程中需要不断画系统全景图,逐步把整个系统掌握了。
|