侧边栏壁纸
博主头像
码森林博主等级

一起走进码森林,享受编程的乐趣,发现科技的魅力,创造智能的未来!

  • 累计撰写 146 篇文章
  • 累计创建 74 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

技术TL要做哪些事情

码森林
2022-12-21 / 0 评论 / 0 点赞 / 454 阅读 / 8,044 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-12-21,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

技术TL,有些公司可能又叫「技术经理」,英文一般是 Tech Leader 或简称 TL。在拉姆·查兰 (Ram Charan) 的《领导梯队》中提到一个人的工作角色中至少有百分之五十以上的时间是花费在管理事务上,那么他的角色才算是一个经理(Manager),所以技术TL是一个Leader而不是Manager,TL指引整个团队前进的方向。

「技术主管」的定位是开发团队中的某位码农要对一起创建系统的整个开发团队负责时所承担的角色,在厂内俗称大头兵。通常这位老兄既要对最终交付的软件系统负责,另外也会像一个开发小哥一样去开发实现系统。一个技术主管的 60% ~ 70% 的时间可能花在了开发任务分解分配、开发实践、技术架构评审、代码审核和风险识别上,而剩下的 30% ~ 40% 的时间则花在为了保障系统按时交付所需的各种计划、协作、沟通、管理上。和团队管理者不同的是,技术主管的大部分管理工作都是针对具体研发任务和技术事务。

​ 随着每个人工作经验的不断积累,能力的不断提升,在熟练掌握一线工作技能后,每个人都有机会成为Tech Leader,然而在机会到来前,所以筒子们必须提前做好准备。接下来基于笔者在一线技术TL这个角色上,在开发规范、开发流程、技术管理与规划等方面的一些经验。

1.定开发规范

1.1 命名规范

​ 搭建项目结构是工作协同很重要的基础,大家的认知统一需要从名字归类做起,应用命名规范、模块的划分、目录(包)的命名,笔者觉得非常重要,如果做的足够好,别人导入项目后可能只需要10分钟就可以大概了解系统结构。具体包命名、类的命名、接口命名、方法命名、变量命名、常量命名,可以参考《阿里开发规约》,以前笔者有规定,每次有新伙伴加入团队后都会要求他对上手的项目参照开发规约,进行代码坏味道的分享并制定优化计划, 这样也让团队其他老成员完成温故而知新,对于不合适的剔除团队开发规约,对于共识的继续加强修正。

1.2 统一IDE代码模板

​ 约定了IDEA/Eclipse IDE代码的统一模板,代码风格一定要统一,避免不同开发人员使用不同模板带来的差异化以及代码merge成本。使用IDEA的同学可以使用Intellij的相关插件,和Intellij统一代码模板。

1.3 Maven使用规范

​ 所有二方库、三方库的版本统一到parent pom里,这样来所有的所有业务应用统一继承parent pom里所指定的二方库、三方库的版本,生产环境禁用SNAPSHOT版本,统一框架与工具的版本(Spring、Apache commons工具类、日志组件、JSON处理、数据库连接池等)。

1.4 代码Commit规范

​ 基于Angular Commit Message规范生成统一的ChangeLog,这样一来对于每次发布release tag非常清晰,Mac下都需要安装对应的插件,IDEA也有对应的插件,此刻忽然想起Linus面对pull request里的骚操作所发的飚:

Get rid of it. And I don’t ever want to see that shit again. – Linus

1.5 统一API规范

​ 统一Rpc服务接口的返回值ResultDTO,success代表接口处理响应结果成功还是失败,errorCode、errorMsg表示返回错误码和错误消息,module表示返回结果集,把ResultDTO定义到common-api顶层二方库,这样以来各个应用不需要来回转换返回结果。Http Rest接口规范约定同ResultDTO相差无几,需要额外关注一下加解密规范和签名规范、版本管理规范。

1.6 异常处理规范

​ 异常处理不仅仅是狭义上遇到了Exception怎么去处理,还有各种业务逻辑遇到错误的时候我们怎么去处理,推荐一本名字好像叫《异常处理》的书籍,当时我是从C++转Java的,一直分不清楚抛异常还是返回错误码为好,这本书非常系统地介绍了Java错误异常体系与平时业务处理方式以及需要注意点。service服务层捕获的异常主要包括BusinessException(业务异常)、RetriableException(可重试异常)到common-api,定义一个公共异常拦截器,对业务异常、重试异常进行统一处理。

​ 另外其他业务层有些特殊异常不需要拦截器统一处理,内部可以进行自我消化处理掉,根据场景对应的处理原则主要包括:

  • 直接返回
  • 抛出异常
  • 重试处理
  • 熔断处理
  • 降级处理

1.7 分支开发规范

针对分支开发规范,指定如下标准:

分支的定义(master、develop、release、hotfix、feature)

  • 分支命名规范
  • checkout、merge request流程
  • 提测流程
  • 上线流程
  • Hotfix流程

虽然这个和代码质量和架构无关,按照这一套标准执行下来,能够给整个研发团队带领很大的便利:

  • 减少甚至杜绝代码管理导致的线上事故,提高开发和测试的工作效率,人多也乱
  • 方便运维处理发布和回滚
  • 让项目的开发可以灵活适应多变的需求,提高协同开发效率

1.8 统一日志规范

​ 日志是产品必不可少的一个功能,具备可回溯性、能够抓取问题现场信息是其独一无二的优点,尤其在生产系统上问题定位等方面具有不可替代的作用。这里着重强调一下针对异常的日志规范:

  • WARN和ERROR的选择需要好好考虑,WARN一般笔者倾向于记录可自恢复但值得关注的错误,ERROR代表了不能自己恢复的错误。对于业务处理遇到问题用ERROR不合理,对于catch到了异常也不是全用ERROR。
  • 记录哪些信息,最好打印一定的上下文(链路TraceId、用户Id、订单Id、外部传来的关键数据)而不仅仅是打印线程栈。
  • 记录了上下问信息,是否要考虑日志脱敏问题?可以在框架层面实现,比如自定义实现logback的ClassicConverter。

正确合理的使用日志,能够指引开发人员快速查找错误、定位问题,因此约定了一套日志使用标准规范,是非常有必要的。

1.9 统一MYSQL开发规范

​ 表的设计和Api的定义类似,属于那种开头没有开好,以后改变需要花数倍的代价去修正,一开始在业务不明确的情况下,设计出良好的一步到位的表结构很困难,但是至少做的是遵循一个好的标准。

1.10 统一工具与框架

​ 对开发过程中所用到的公共组件进行了统一抽象与封装,包括dao层框架mybatis、cache组件、httpClient组件、common-tools(公共工具)、基于RPC框架增强组件,同时抽取出分布式锁、日志追踪、幂等等公共组件,把以上公共组件进行集成到各个应用,进行统一升级、维护。

1.11 技术文档规范

​ 文档的传承其实就是知识的传承,好的技术文档可以看出开发对需求的理解,比如需求价值确认、系统与功能模块设计、质量与风险控制、工作任务分解等等一系列内容,能让需求相关方如上下游链路的同事知悉相关的开发计划和任务事项。

2. 开发流程优化

目前团队的开发模式还是基于传统的瀑布开发模式,整体开发流程涉及需求评审、测试用例评审、技术架构评审、开发与测试、验收与上线,这里主要基于TL的角度从需求管理、技术架构评审、代码评审、发布计划评审几个关键重点环节进行探讨。

2.1 需求管理

产品因需求而生,在产品的整个生命周期中,产品经理会收到来自各个方面的需求,但是每一个需求的必要性、重要性和实现成本都需要经过深思熟虑的分析和计划,避免盲目的决定需求或者变更需求,这样很容易导致工作混乱,技术TL如果不能正确的对需求进行把控,会导致整个项目偏离正确的轨道,要学会有理有据地拒绝业务/产品的不合理需求,这里更重要地是以用户的视角去梳理用户的痛点与需求价值,别怕得罪人,据笔者亲身经历,业务/产品可以接受你的有理有据,至于做不做是另外的事情。

​ 需求管理的第一步就是要梳理不同来源的需求,主要包括从产品定位出发、外部用户反馈、竞争对手情况、市场变化以及内部运营人员、客服人员、开发人员的反馈。首先技术TL对产品有足够认知和把控,简单来说就是自己的产品是为了满足哪些人的哪些需求而做,产品需求一定要根植于客户的需求、根植于客户的环境。每款产品必定有其核心价值,能够为客户创造更多的价值,基于此考虑往往能得到一些核心需求,摒除价值不大的需求。

​ 需求管理中最重要的就是对发散性需求的管理,往往因此也会导致产品在执行过程中不断的变更或增加需求。由于人的思维是发散性的,所以往往在产品构思的过程中会出现各种新鲜好玩的想法,这些想法可能来自业务、领导或者产品经理,但是这些想法往往都是和产品核心方向不相关的,但是由于这些想法能够在当时带来诱惑,因此这些不相关的需求会严重干扰了技术团队的精力,打乱或者延误产品原本的计划。同样技术研发同学也需要建立对产品的深度思考,不要把自己定位成产品需求的实现者,同样需要对需求负责。

2.2 技术架构评审把关

​ 互联网时代,大家提倡敏捷迭代,总嫌传统方式太重,流程复杂,影响效率,什么都希望短平快,在扁平化的组织中,经常是需求火速分发到一线研发,然后就靠个人折腾去了,其实技术架构评审这同样是一个非常重要的环节。架构评审或技术方案评审的价值在于集众人的力量大家一起来分析看看方案里是否有坑,方案上线后是否会遇到不可逾越的重大技术问题,提前尽可能把一些事情先考虑到提出质疑其实对项目的健康发展有很大的好处。

基于架构评审,我们的核心目标是要满足以下几点:

  • 设计把关,确保方案合格,各方面都考虑到了,避免缺陷和遗漏,不求方案多牛,至少不犯错;
  • 保证架构设计合理和基本一致,符合整体原则;
  • 维持对系统架构的全局认知,避免盲区;
  • 通过评审发掘创新亮点,推广最佳实践。

​ 架构设计既要保证架构设计的合理性和可扩展性,又要避免过度设计。架构设计不仅仅是考虑功能实现,还有很多非功能需求,以及持续运维所需要的工作,需要工程实践经验,进行平衡和取舍。架构评审需要以下几点:

1. 技术选型
为什么选用A组件不选用B、C组件,A是开源的,开源协议是啥?基于什么语言开发的,出了问题我们自身是否能够维护?性能方面有没有压测过?这些所有问题作为技术选型我们都需要考虑清楚,才能做最终决定。

2. 高性能
产品对应的TPS、QPS和RT是多少?设计上会做到的TPS、QPS和RT是多少?而实际上我们整体随着数据量的增大系统性能会不会出现明显问题?随着业务量、数据量的上升,我们的系统的性能如何去进一步提高?系统哪个环节会是最大的瓶颈?是否有抗突发性能压力的能力,大概可以满足多少的TPS和QPS,怎么去做来实现高性能,这些问题都需要我们去思考。

3. 高可用
是否有单点的组件,非单点的组件如何做故障转移?是否考虑过多活的方案?是否有数据丢失的可能性?数据丢失如何恢复?出现系统宕机情况,对业务会造成哪些影响?有无其他补救方案?这些问题需要想清楚,有相应的解决方案。

4. 可扩展性
A和B的业务策略相差无几,后面会不会继续衍生出C的业务策略,随着业务的发展哪些环节可以做扩展,如何做扩展?架构设计上需要考虑到业务的可扩展性

5. 可伸缩性
每个环节的服务是不是无状态的?是否都是可以快速横向扩展的?扩容需要怎么做手动还是自动?扩展后是否可以提高响应速度?这所有的问题都需要去思考清楚,并有对应的解决方案。

6. 弹性处理
消息重复消费、接口重复调用对应的服务是否保证幂等?是否考虑了服务降级?哪些业务支持降级?支持自动降级还是手工降级?是否考虑了服务的超时熔断、异常熔断、限流熔断?触发熔断后对客户的影响?服务是否做了隔离,单一服务故障是否影响全局?这些问题统统需要我们想清楚对应的解决方案,才会进一步保证架构设计的合理性。

7. 兼容性
上下游依赖是否梳理过,影响范围多大?怎么进行新老系统替换?新老系统能否来回切换?数据存储是否兼容老的数据处理?如果对你的上下游系统有影响,是否通知到上下游业务方?上下游依赖方进行升级的方案成本如何最小化?这些问题需要有完美的解决方案,稍有不慎会导致故障。

8. 安全性
是否彻底避免SQL注入和XSS?是否有数据泄露的可能性?是否做了风控策略?接口服务是否有防刷保护机制?数据、功能权限是否做了控制?管理系统是否做了日志审计?数据传输是否加密验签?应用代码中是否有明文的AK/SK、密码?这些安全细节问题需要统统考虑清楚,安全问题任何时候都不能轻视。

9. 可测性
测试环境和线上的差异多大?是否可以在线上做压测?线上压测怎么隔离测试数据?是否有测试白名单功能?是否支持部署多套隔离的测试环境?测试黑盒白盒工作量的比例是怎么样的?新的方案是否非常方便测试,在一定程度也需要考量。

10. 可运维性
系统是否有初始化或预热的环节?数据是否指数级别递增?业务数据是否需要定期归档处理?随着时间的推移如果压力保持不变的话系统需要怎么来巡检和维护?业务运维方面的设计也需要充分考虑到

11. 监控与报警
对外部依赖的接口是否添加了监控与报警?应用层面系统内部是否有暴露了一些指标作监控和报警?系统层面使用的中间件和存储是否有监控报警?只有充分考虑到各个环节的监控、报警,任何问题会第一时间通知到研发,阻止故障进一步扩散。

​ 其实不同阶段的项目有不同的目标,我们不会在项目起步的时候做99.99%的可用性支持百万QPS的架构,高效完成项目的业务目标也是架构考虑的因素之一。而且随着项目的发展,随着公司中间件和容器的标准化,很多架构的工作被标准化替代,业务代码需要考虑架构方面伸缩性运维性等等的需求越来越少,慢慢的这些工作都能由架构和运维团队来接。一开始的时候我们可以花一点时间来考虑这些问题,但是不是所有的问题都需要有最终的方案。

2.3 代码评审

​ 代码质量包括功能性代码质量和非功能性代码质量,功能质量大多通过测试能够去发现问题,非功能性代码质量用户不能直接体验到这种质量的好坏,代码质量不好,最直接的“受害者”是开发者或组织自身,因为代码质量好坏直接决定了软件的可维护性成本的高低。代码质量应该更多的应该从可测性,可读性,可理解性,容变性等代码可维护性维度去衡量,其中CodeReview是保证代码质量非常重要的一个环节,建立良好的CodeReview规范与习惯,对于一个技术团队是一件非常重要核心的事情,没有CodeReview的团队没有未来。

​ 每次项目开发自测完成后,通常会组织该小组开发人员集体进行代码review,代码review一般review代码质量以及规范方面的问题,另外需要关注的是每一行代码变更是否与本次需求相关,如果存在搭车发布或者代码重构优化,需要自行保证测试通过,否则不予发布。CodeReview我会重点关注如下事情:

1. 确认代码功能:
代码实现的功能满足产品需求,逻辑的严谨和合理性是最基本的要求。同时需要考虑适当的扩展性,在代码的可扩展性和过度设计做出权衡,不编写无用逻辑和一些与代码功能无关的附加代码。

2. 编码规范:

​ 以《阿里巴开发规约》、静态代码规约、灵狐代码扫描插件为前提,是否遵守了编码规范,遵循了最佳实践。除了形式上的要求外,更重要的是命名规范。目标是提高代码的可读性,降低代码可维护性成本。

3. 潜在的BUG:
可能在最坏情况下出现问题的代码,包括常见的线程安全、业务逻辑准确性、系统边界范围、参数校验,以及存在安全漏洞(业务鉴权、灰产可利用漏洞)的代码。

4. 文档和注释:
过少(缺少必要信息)、过多(没有信息量)、过时的文档或注释,总之文档和注释要与时俱进,与最新代码保持同步。其实很多时候个人觉得良好的变量、函数命名是最好的注释,好的代码胜过注释。

5. 重复代码:
当一个项目在不断开发迭代、功能累加的过程中,重复代码的出现几乎是不可避免的,通常可以通过PMD工具进行检测。类型体系之外的重复代码处理通常可以封装到对应的Util类或者Helper类中,类体系之内的重复代码通常可以通过继承、模板模式等方法来解决。

6. 复杂度:
圈复杂度是用来衡量一个模块判定结构的复杂程度,能帮助开发者识别难于测试和维护的模块,在成本、进度和性能之间寻求平衡。代码结构太复杂(如圈复杂度高),难以理解、测试和维护。

7. 监控与报警:
基于产品的需求逻辑,需要有些指标来证明业务是正常工作的,如果发生异常需要有监控、报警指标通知研发人员处理,review业务需求对应的监控与报警指标也是Code Review的重点事项。

8. 测试覆盖率:
编写单元测试,特别是针对复杂代码的测试覆盖是否足够。实际上维护单元测试的成本不比开发成本低,这点团队目前做的的不到位。

针对以上每次代码review所涉及到的经典案例会统一输出到文档里,大家可以共同学习避免编写出同样的烂代码。

2.4 发布计划评审

​ 涉及到10人日以上的项目,必须有明确的发布计划,并组织项目成员统一参加项目发布计划review,发布计划主要包含如下几点:

  • 明确是否有外部依赖接口,如有请同步协调好业务方
  • 发布前配置确认包括配置文件、数据库配置、中间件配置等各种配置,尤其各种环境下的差异化配置项
  • 二方库发布顺序,是否有依赖
  • 应用发布顺序
  • 数据库是否有数据变更和订正,以及表结构调整
  • 回滚计划,必须要有回滚计划,发布出现问题要有紧急回滚策略
  • 生产环境回归测试重点Case

3. 做技术规划与管理

​ 以前的技术TL生涯,每周都会做系统健康度巡检,避免日积月累的技术债一天转变成生产环境故障,如果有一天真的故障来了,如何处理生产环境的故障处有明确思路。

3.1 系统健康度巡检

​ 为什么要把系统健康度巡检放到技术管理里,笔者认为这是一个非常重要的环节。像传统的航空、电力、汽车行业都要有一定的巡检机制,保障设备系统正常运转,同样软件系统也同样需要巡检机制保障业务健康发展。

​ 随着业务的不断发展,业务量和数据量不断的上涨,系统架构的腐蚀是避免不了的,为了保障系统的健康度,需要不断的考虑对系统架构、性能进行优化。

​ 系统的监控与报警能够一定程度发现系统存在的问题,系统存在的一些隐患需要通过对系统的巡检去发现,如果优化不及时在极端情况会导致故障,巡检粒度建议每周巡检一次自己所负责的业务系统。

其中系统巡检重点要关注如下几点:

  • **系统指标,**系统CPU、负载、内存、网络、磁盘有无异常情况波动,确认是否由发布导致,还是系统调用异常;
  • **慢接口,**通常rt大于3s的接口需要重点关注,极端并发场景下容易导致整个系统雪崩;
  • **慢查询,**MYSQL慢查询需要重点关注,随着数据量上涨,需要对慢查询进行优化;
  • **错误日志,**通过错误日志去发现系统隐藏的一些bug,避免这些bug被放大,甚至极端情况下会导致故障.

3.2 技术规划

​ 技术规划通常由团队的TL负责,每个财年/季度/月份,技术TL都需要从大局的角度去思考每个季度的技术优化规划,去偿还技术债,技术债也是有利息的,因为利息的存在,技术债务不及时偿还的话,会在未来呈现出非线性增长,造成始料不及的损失,比如需要做一个平台去收敛业务域内的烟囱式的功能模块,就需要把管理端的一些功能模块优先级放到平台衍生功能之上,不然相关功能模块又会继续迭代演进。这里的技术规划包括如下几点:

  • 架构优化

一些结构不良、低内聚高耦合的代码则会使得哪怕是微小的需求变更或功能扩展都无从下手,修改的代价很可能超过了重写的代价。

同样系统之间的耦合也需要重点去关注,遵循微服务化的原则,系统也要遵循单一职责原则,对于职责不清晰的系统去做解耦优化,进行一些模块化改造、服务隔离、公用服务抽象

  • 性能优化

​ 基于财年对于业务量、数据量的发展评估,根据目前系统服务的QPS\RT,需要提前规划对系统性能进行一些升级策略,包括重点关注对一些慢接口、慢查询的优化。

  • 弹性与可靠性

​ 系统提供的服务需要保障括数据一致性、幂等、防重攻击,同时也需要从熔断降级、异地多活的角度去考虑存在哪些问题,目前系统的SLA指标是否能够达到高可用,需要做哪些优化保障系统的高可用。

  • 可伸缩

​ 应用服务是否保证无状态,关键节点发生故障能够快速转移、扩容,避免故障扩大化。

总结

​ 笔者认为最重要的是架构设计的能力,可能管理能力还次之。对于管理能力笔者认为最重要的是对团队的感知能力,因为一旦到了技术TL这个级别,不能脱离一线太远,业务细节可以不清楚,大的方向必须要明确。如果没有很细腻的感知能力,很多的决策会有偏差。

如果他不是一个业务架构师,不是一个能给团队指明更好方向的人,他最终会沦为一个需求翻译器,产品经理说怎么做就怎么做。他更多的只是负责保证产品的质量、开发的速度,最终被肢解成一个很琐碎的人。一旦团队上了一定的规模,团队就会从单纯的需求实现走向团队运营,而运营是需要方向的,业务架构就是一个基于运营和数据的一种综合的能力。关于技术层面,技术TL需要具备如下素养:

  • 技术视野良好,解决问题能力与架构设计能力出色。技术TL要有良好的技术视野,不需要各种技术都样样精通,但是必须要所有涉猎,有所了解,对各种技术领域的发展趋势,主流非主流技术的应用场景要非常了解。知道在什么场景应用什么技术,业务发展到什么规模应该预先做哪些技术储备。产品架构的设计要有足够的弹性,既能够保证当前开发的高效率,又能够对未来产品架构的演进留出扩展的余地。
  • 动手能力要强,学习能力出色。技术TL并不需要自己亲自动手写代码,但是如有必要,自己可以随时动手参与第一线的编码工作,技术TL不能长期远离一线工作,自废武功,纸上谈兵。否则长此以往,会对技术的判断产生严重的失误。另外,技术TL也应该是一个学习能力非常出色的人,毕竟IT行业的技术更新换代速度非常快,如果没有快速学习能力,是没有资格做好技术TL的。

作者:代码的色彩
链接:https://juejin.cn/post/7178095805172023352
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0

评论区