Technicalsupervisor,又称“技术经理”,英文一般是TechLeader,简称TL。随着工作经验的不断积累和能力的不断提升,每个人都有机会成为TeamLeader。但是,在机会到来之前,我们必须提前做好准备,对TL的工作职责有一定的了解。当然,这也为与天合更好的合作打下了基础。今天,阿里巴巴资深技术专家云迪将结合多年经验,从开发规范、开发流程、技术规划和管理等方面分享对技术TL作用的理解和思考。欢迎讨论交流。“技术负责人”是开发团队中的程序员在负责整个开发团队共同创建系统时所承担的角色。通常他不仅要负责最终交付的软件系统,还要像程序员一样开发实现系统。一个技术主管60%~70%的时间可能花在开发任务分解分配、开发实践、技术架构审查、代码审查和风险识别上,而剩下的30%~40%的时间花在确保系统的各种规划上准时交付所需的、协作、沟通和管理。与团队经理不同,技术总监的大部分管理工作是针对具体的研发任务和技术事务。接下来,我将基于我作为技术TL的角色,从开发规范、开发流程、技术管理和规划等方面,与大家分享一些心路历程。1.规范的制定。我当时负责的业务是集团收购子公司,整体技术标准和集团的技术标准有很大的差异。开发规范可以说是我来到这个团队做的第一件事。我当时面临的问题是API接口格式混乱,没有标准的RPC服务,代码没有统一标准的开发规范,技术框架组件不规范等等一系列问题问题,作为一个业务新人,我很快制定了一套比较规范和完善的技术开发规范,边写代码边梳理开发规范,带领团队走上了统一规范的开发之路。针对团队研发规范暴露出的上述问题,主要制定了以下规范:命名规范我很注重项目结构搭建的初始过程,我认为应用命名规范非常重要、模块划分、目录(包)命名。够用了,其他人导入项目后大概只需要10分钟就可以对系统结构有个大概的了解。具体规范包括包命名、类命名、接口命名、方法命名、变量命名和常量命名。统一IDE代码模板约定IDEA/EclipseIDE代码统一模板。代码风格必须统一,避免不同开发者使用不同模板造成的差异和代码合并成本。使用IDEA的同学可以安装EclipseCodeFormatter插件和Eclipse统一代码模板。Maven使用规范定义父pom中所有二方库和第三方库的版本,使得所有业务应用项目统一继承父pom中指定的二方库和第三方库的版本,并统一框架和工具(Spring、Apachecommons工具、日志组件、JSON处理、数据库连接池等)的版本,要求生产环境禁用SNAPSHOT版本。这样,要升级通用框架和工具的版本,只需要应用工程升级父pom即可。CodeCommit规范在AngularCommitMessage规范的基础上生成了统一的ChangeLog,使得每次发布的release标签都非常清晰。Mac下需要安装相应的插件,IDEA也有相应的插件。详情请看阮一峰先生的《Commit message 和 Change log 编写指南》。这时突然想起了Linus对pullrequest中的风骚操作的吐槽:滚蛋吧。commit信息生成的releasetag对于生产环境中的故障??回滚行业非常关键,可以提供一些有价值的信息。统一API规范了统一Rpc服务接口的返回值ResultDTO。具体代码如下:success表示接口处理响应结果成功或失败,errorCode和errorMsg表示返回错误码和错误信息,module表示返回结果集,定义ResultDTO到common-api顶层第二方库,让每个应用程序不需要来回转换返回的结果。HttpRest接口规范与ResultDTO几乎相同,需要额外注意加解密规范、签名规范、版本管理规范。异常处理规范异常处理不仅仅是狭义上如何处理Exception,而是指如何处理各种业务逻辑错误。service服务层捕获的异常主要包括BusinessException(业务异常)、RetriableException(可重试异常)到common-api,定义一个通用的异常拦截器,统一处理业务异常和重试异常。对于可重试异常,调用的服务接口需要保证其幂等性。另外,其他业务层的一些特殊异常不需要拦截器统一处理,可以在内部自行消化处理。根据场景对应的处理原则,主要原则包括:直接返回、抛出异常、重试处理、熔断处理、降级处理。这就涉及到弹性设计。主题,我们的系统经常与各种外部服务和API连接,大多数服务没有SLA。即使在大并发下,我们也需要考虑外部服务不可用对自己的影响,会不会把自己拖死。我们始终希望:尽量以尽可能低的成本完成业务;如果外部服务基本不可用,而我们同步调用外部服务,则需要进行自我保护,直接熔断,否则在持续并发的情况下,会自己崩溃;如果对外服务特别重要,我们往往会考虑引入多个同类型的服务,按照价格和服务标准路由,出现问题自动降级。推荐使用Netflix开源的hystrix容灾框架,主要解决外部依赖失效时拖累业务系统甚至导致雪崩的问题。目前我的团队也在使用,可以很好的解决异常熔断器、超时熔断器、限流熔断器基于并发数的降级处理。早期的分支开发规范,源码的版本管理是基于svn,后来逐渐切换到git。每个公司的分支机构管理方式略有不同(基于Gitflow)。对于分支开发规范,指定如下标准:分支定义(master、develop、release、hotfix、feature)分支命名约定checkout、mergerequestprocess、testprocess、onlineprocess、Hotfixprocess虽然这与代码质量和架构,按照这套标准的实施,可以给整个研发团队带来极大的方便:减少甚至杜绝代码管理带来的线上事故;提高开发和测试的效率,即使人太多;减少甚至杜绝代码管理引起的线上事故;方便运维处理发布和回滚;让项目的开发能够灵活适应不断变化的需求,多人协同开发。统一日志规范日志是产品不可或缺的功能。它的优点是可追溯性和捕获问题现场信息的能力。特别是在生产系统中的问题定位方面,有着不可替代的作用。这里强调异常的日志规范:WARN和ERROR的选择需要慎重考虑。一般WARN倾向于记录可自恢复但值得关注的错误,ERROR表示不能自恢复的错误。业务处理中遇到的问题用ERROR是不合理的,catch异常也不全是用ERROR。记录什么信息,打印某个context(linkTraceId,userId,orderId,keydatafromoutside)而不是仅仅打印线程栈。记录了上下查询信息,是不是应该考虑日志脱敏?可以在框架层面实现,比如自定义实现logback的Cla??ssicConverter。正确合理的使用日志可以指导开发人员快速发现错误,定位问题。因此约定了一套日志使用标准,现在大家可以参考《阿里经济体开发规约——日志规约》。统一MYSQL开发规范表的设计类似于Api的定义。属于一开始没开过的那种,以后改要10x的钱。我知道一开始业务不清楚的时候,设计好的一步表。结构很难,但至少我们能做的是有一个好的标准。2、统一的工具和框架开发过程中使用的公共组件统一抽象和封装,包括dao层框架mybatis、缓存组件jetcache、httpclient组件、common-tools(公共工具)。同时,全局ID、分布式锁、幂等等公共组件,将以上公共组件集成到各个应用中,统一升级维护,让大家可以将更多的精力集中在业务发展上。开发流程团队目前的开发模式还是基于传统的瀑布式开发模式。整个开发流程包括需求评审、测试用例评审、技术架构评审、开发测试、验收上线。这主要是从需求管理和技术架构的角度,基于TL。将讨论审查、代码审查和发布计划审查的几个关键环节。欢迎来到拍砖。美国专门跟踪IT项目成败的权威机构StandishGroup的DemandManagementCHAOSReports报告了该公司的一项研究。在调查了多个项目后,该公司发现74%的项目都是失败的,即使这些项目不能按时按预算完成。项目失败被提及最多的原因是“改变用户需求”。另外,从StandishGroup历年的报告分析来看,项目失败最重要的原因与需求有关。StandishGroup的CHAOS报告进一步证实,与项目成功最密切相关的因素是良好的需求管理,即项目范围管理,尤其是良好的项目变更管理。产品因需求而生。在整个产品生命周期中,产品经理会收到来自各个方面的需求,但每个需求的必要性、重要性和实现成本都需要仔细分析和规划,避免盲目确定或更改需求,容易导致工作混乱。如果技术TL不能正确控制需求,整个项目就会偏离正确的轨道。需求管理是对不同来源的需求进行梳理,主要包括从产品定位、外部用户反馈、竞争对手情况、市场变化,以及内部运营商、客服人员、开发人员的反馈等入手。首先,技术TL对产品有足够的了解和把控。简而言之,我的产品是为了满足谁和什么人的需求而设计的。产品需求必须植根于客户的需求和客户的环境。每个产品都必须有它的核心价值,才能为客户创造更多的价值。基于这样的考虑,往往可以获得一些核心需求,而排除掉价值较低的需求。需求管理中最重要的是对发散性需求的管理,这往往会导致产品需求在实施过程中不断变化或增加。由于人们的思维是发散的,所以在产品构思的过程中经常会出现各种新鲜有趣的想法。这些想法可能来自领导或产品经理本身,但这些想法往往与产品的核心方向无关。但由于这些想法在当时会带来诱惑,这些无关紧要的要求会严重干扰技术团队的精力,打乱或延误产品的原定计划。同样,技术研发同学也需要建立对产品的深度思考。不要把自己定位为产品需求的执行者,也需要对需求负责。很多时候,需求的变化或增加,是因为我们面临太多的选择,想要的太多,没有适当地控制自己的欲望,以自己的喜好来决定需求。这些因素很容易导致产品没有明确的方向,团队成员疲惫不堪,但没有真正的结果。因此,技术TL必须能够评估复检产品和筛选要求的优先级,并确定每个要求的必要性、重要性和实施成本。通过深思熟虑,给团队一个明确的方向和重点,专注于资源配置,确保团队的精力集中在产品的核心需求上。技术架构回顾互联网时代,大家都提倡敏捷迭代。他们总觉得传统的方法太重,工艺复杂,影响效率。一切都应该是短而快的。在一个扁平化的组织中,往往需求会被快速分发到一线研发,然后由个人去折腾Go,其实技术架构评审也是一个很重要的环节。架构评审或者技术方案评审的价值在于凝聚大家的力量,分析解决方案有没有坑,方案上线后会不会出现无法克服的重大技术问题,把一些事情考虑为尽可能提前提出质疑,其实对项目的健康发展大有裨益。基于架构审查,我们的目标核心是满足以下几点:1.设计检查,确保方案合格,考虑到方方面面,避免缺陷和遗漏,不求好的方案,至少不犯错误。2、保证架构设计合理,基本一致,符合总体原则。3.保持对系统架构的全局理解,避免黑盒效应。4.通过评价发现创新亮点,推广优秀实践。架构设计既要保证架构设计的合理性和可扩展性,又要避免过度设计。架构设计不仅要考虑功能实现,还要考虑很多非功能需求,以及持续运维所需要的工作,这就需要工程实践经验,权衡取舍。架构审查需要以下几点:1.技术选择:为什么使用组件A而不是组件B和C?A是开源的。什么是开源协议?基于什么语言开发的,出问题了能不能自己维护?你测试过性能吗?在做出最终决定之前,我们需要将所有这些问题作为技术选择来考虑。2、高性能:产品对应的TPS、QPS、RT是多少?设计中要达到的TPS、QPS、RT是多少?事实上,随着数据量的增加,我们的整体系统性能会不会出现明显的问题呢?随着业务量和数据量的增加,如何进一步提升我们系统的性能呢?系统的哪一部分会成为瓶颈?是否有能力抵抗突如其来的性能压力,能满足多少TPS和QPS,如何做到高性能,这些问题都需要我们去思考。3、高可用:有没有单点组件,非单点组件如何进行failover?您是否考虑过过度生活的选择?有没有数据丢失的可能性?如何恢复丢失的数据?系统宕机对业务有什么影响?还有其他补救措施吗?这些问题都需要想清楚,并有相应的解决办法。4.可扩展性:A和B的业务策略几乎相同。C的经营策略以后还会继续衍生吗?随着业务的发展,哪些环节可以扩展,如何扩展?架构设计需要考虑业务的可扩展性。5、可扩展性:各个环节的服务是不是无状态的?它们都可以水平扩展吗?扩容需要手动或自动完成哪些工作?缩放会提高响应能力吗?这些问题都需要我们想清楚,并有相应的解决办法。6、弹性处理:消息重复消费、接口重复调用是否保证幂等性?是否考虑了服务降级?哪些业务支持降级?是否支持自动降级或手动降级?是否考虑过服务的超时熔断、异常熔断、限流熔断?熔断触发后对客户有何影响?服务是否孤立,单个服务故障是否影响全局?这些问题都需要我们思考相应的解决方案,从而进一步保证架构设计的合理性。7、兼容性:是否梳理了上下游依赖关系,影响范围如何?新旧系统如何更替?新旧系统可以来回切换吗?数据存储是否与遗留数据处理兼容?如果对你的上下游系统有影响,你通知上下游业务方了吗?如何最小化上下游依赖方升级的解决方案成本?这些问题需要很好的解决,稍有不慎就会导致失败。8、安全性:是否完全避免了SQL注入和XSS?是否存在数据泄露的可能性?您是否实施了风险控制策略?接口服务是否有防刷保护机制?数据和功能权限是否受控?二级后台系统是否进行了日志审计?数据传输是否加密和签名?应用代码中是否有明文AK/SK和密码?这些安全细节都需要慎重考虑,任何时候都不能低估安全问题。9、可测试性:测试环境和生产线的区别有多大?压力测试可以在线完成吗?在线压测时如何隔离测试数据?有测试白名单功能吗?是否支持部署多个隔离的测试环境?测试黑盒与白盒工作量的比例是多少?新方案是否非常方便测试也需要在一定程度上考虑。10.可操作性:系统是否有初始化或预热过程?数据是否呈指数增长?业务数据是否需要定期归档?如果压力随时间保持恒定,将如何检查和维护系统?业务运维的设计也需要充分考虑。11、监控告警:是否在对外依赖的接口上增加了监控告警?系统内部在应用层是否有暴露指标用于监控告警?系统级使用的中间件和存储是否有监控告警?只有充分考虑各个环节的监控和告警,出现问题第一时间通知研发,防止故障进一步扩散。事实上,不同阶段的项目有不同的目标。我们不会在项目初期实现支持100万QPS、99.99%可用性的架构。高效完成项目的业务目标也是架构中考虑的因素之一。并且随着项目的发展,随着公司中间件和容器的标准化,很多架构的任务已经被标准化取代,业务代码需要考虑架构的扩展性、运维等,两者都可以被架构接过来和运维团队。这些问题一开始我们可以花一点时间思考,但并不是所有的问题都需要一个最终的解决方案。代码审查代码质量包括功能代码质量和非功能代码质量。大部分功能性质量可以通过测试发现问题,非功能性代码质量用户无法直接体验到这种质量的好坏。如果代码质量不好,最直接最大的“受害者”就是开发者或者组织本身,因为代码的质量直接决定了软件可维护性的成本。代码质量应该更多地从可测试性、可读性、可理解性、容错性等代码可维护性维度来衡量。其中,CodeReview是保证代码质量的一个非常重要的环节。建立良好的CodeReview规范和习惯,是一个技术团队非常重要的核心事情,没有CodeReview的团队是没有未来的。每次项目开发自测完成后,通常会组织组内开发人员集体进行代码审查。代码审查通常审查代码质量和规范问题。此外,我们还需要注意每一行代码的变化是否与这个需求相关。如果有网约车发布或者代码重构优化,需要自己保证测试通过,否则不会发布。CodeReview我会重点关注以下几点:1、确认代码功能:代码实现的功能满足产品需求,逻辑的严谨性和合理性是最基本的要求。同时还要考虑适当的可扩展性,在代码可扩展性和过度设计之间做出权衡,不要写无用的逻辑和一些与代码功能无关的额外代码。在你真正需要的时候实施,而不是在你预见到它会有用的时候实施。——罗恩·杰弗里斯2.编码规范:以群开发规范和静态代码规范为前提,是否遵守编码规范,是否遵循最佳实践。除了形式上的要求,更重要的是命名规范。目标是提高代码可读性并降低代码可维护性成本。3.PotentialBUG:最坏情况下可能导致问题的代码,包括普通线程安全、业务逻辑准确性、系统边界范围、参数校验、安全漏洞(业务鉴权、灰色生产可利用漏洞)代码。.4.文档和注释:太少(缺少必要的信息),太多(没有多少信息),过时的文档或注释,总之文档和注释要与时俱进,与新代码保持同步。其实很多时候我个人认为好的变量和函数命名就是好的注释,好的代码胜过注释。5、重复代码:当一个项目在不断的开发迭代和功能积累的过程中,重复代码的出现几乎是不可避免的,通常可以通过PMD工具检测到。类型系统外的重复代码处理通常可以封装到相应的Util类或Helper类中,而类系统内的重复代码通常可以通过继承、模板模式等方式解决。6、复杂性:代码结构过于复杂(如圈复杂度高),难以理解、测试和维护。7、监控告警:基于产品需求逻辑,需要一些指标来证明业务正常运行。如果出现异常,需要有监控告警指标,通知研发人员进行处理。review业务需求对应的监控告警指标也是CodeReview。重要事项。8、测试覆盖率:编写单元测试,尤其是复杂代码的测试覆盖率是否足够。事实上,维护单元测试的成本并不低于开发的成本,这是团队目前做得不好的。以上每一次codereview涉及的经典案例,都会统一输出到文档中,大家一起学习,避免写出千篇一律的UglyCode。发布计划审核涉及超过10人日的项目。要有明确的发布计划,组织项目成员参与项目发布计划评审。发布计划主要包括以下几点:1)明确是否有外部依赖接口。如果是,请同步协调业务方;2)发布前的配置确认,包括配置文件、数据库配置、中间件配置等,尤其是在各种环境下的差异化配置项;3)二方库发布顺序,是否存在依赖关系;4)申请发布顺序;5)数据库中是否有数据变更和修订,表结构调整;6)回滚计划,要有回滚计划,发布出现问题要有应急回滚策略;7)生产环境回归测试Keycase。3、技术规划与管理在我带领技术团队的这些年里,我对团队一直有个要求,就是每周做系统健康检查,未雨绸缪,晴天修屋顶,以免一些隐藏的bug改动在极端场景下成为故障。系统健康检查为什么要把系统健康检查纳入技术管理?我认为这是一个非常重要的环节。像传统的航空、电力、汽车行业一样,必须有一定的检查机制来保证设备系统的正常运行。同样,软件系统也需要一个检查机制来保证业务的健康发展。随着业务的不断发展,业务量和数据量不断增大,系统架构的腐蚀在所难免。为了保证系统的健康,需要不断地考虑系统架构和性能的优化。系统的监控和告警可以在一定程度上发现系统中存在的问题。系统中的一些隐患,需要通过对系统的巡检来发现。如果优化不及时,在极端情况下会导致失败。检查粒度建议每周检查一次责任业务系统。系统检查应重点关注以下几点:系统指标:系统CPU、负载、内存、网络、磁盘有异常波动,确认是释放原因还是系统调用异常。接口慢:一般需要注意rt大于3s的接口。在极端并发场景下,很容易导致整个系统雪崩。慢查询:需要重点关注MYSQL慢查询。随着数据量的增加,慢查询需要进行优化。错误日志:利用错误日志发现系统中一些隐藏的bug,避免这些bug被放大,甚至在极端情况下导致故障。技术规划技术规划通常是团队TL的职责。在每个财年,TL都需要从全局的角度思考每个季度的技术优化方案,以偿还技术债。技术债务也有利息。因为利息的存在,技术债如果不及时偿还,未来会呈现非线性增长,造成意想不到的损失。这里的技术规划包括以下几点:架构优化:一些结构不好、低内聚、高耦合的代码,即使是很小的需求变更或功能扩展,也会导致无法启动,修改的成本很可能超过修改的成本重写。同样,系统之间的耦合也需要重点关注。遵循微服务原则,系统也必须遵循单一职责原则。对于职责不明确的系统,要做解耦优化,进行一些模块化改造,服务隔离,服务公共化。抽象的。性能优化:基于财年业务量和数据量的发展评估,根据当前系统服务的QPSRT,需要提前规划一些系统性能的升级策略,包括重点优化一些缓慢的接口和缓慢的查询。弹性和可靠性:系统提供的服务需要得到保证,包括数据的一致性和幂等性。同时,要从断路器降级、异地多动的角度考虑存在的问题。系统当前的SLA指标能否做到高可用是需要做的。哪些优化保证了系统的高可用。可扩展性:是否保证应用服务是无状态的,关键节点的故障可以快速转移和扩展,避免故障的扩大。总结一下,不知道大家有没有类似的经历。某段时间,一些线上故障频发,各种技术债、业务债被业务方追债,要求还债。如果出现这种现象,说明TL已经在很大程度上失位了,这支球队就失控了。曾经有人向我抱怨说他的TL把所有的工作都给了他们,而TL什么都没做!TL这个技术真的什么都不做吗?有一段时间我也在思考技术TL的核心职责是什么?技术TL应该具备哪些素质?首先,技术归根结底是为业务服务的,除非技术本身就是业务,否则必须体现其商业价值。在很多公司,技术研发真正成为满足其他部门需求的工具。我觉得这样的技术TL肯定是不合格的。首先,不能影响业务发展。请求者将经历许多转换。如果请求不经过深思熟虑就传递出去,整个过程就会被扭曲。第二个,我觉得最重要的是架构设计能力,可能管理能力次之。关于管理能力,我觉得最重要的是对团队的感知能力,因为一旦到了技术TL的水平,就不能离一线太远了。业务细节可以不清楚,但大方向一定要清楚。如果没有非常细腻的感知能力,很多决定都会有失偏颇。如果他不是业务架构师,不是能给团队更好方向的人,他最终会成为需求翻译,产品经理说到做到。他更多的是负责保证产品的质量和开发的速度,最终被肢解成一个很琐碎的人。一旦团队达到一定规模,团队将从简单的需求实现走向团队运营,运营需要方向。业务架构是基于运营和数据的综合能力。关于技术层面,技术型TL需要具备以下素质:良好的技术视野、优秀的问题解决能力和架构设计能力。技术TL必须具有良好的技术远见。他们不需要精通各种技术,但必须涉猎所有技术并了解它们。他们必须对各个技术领域的发展趋势以及主流和非主流技术的应用场景有很好的了解。知道在什么场景下应用什么技术,业务发展到一定规模时,应该提前做好哪些技术储备。产品架构的设计必须足够灵活,既要保证当前开发的高效率,又要为未来产品架构的演进留有扩展空间。动手能力强,学习能力优秀。技术型TL不需要自己写代码,但如果有需要,可以随时参与到一线的编码工作中。技术型TL不能长期远离一线工作。否则,长此以往,技术的判断就会出现严重的失误。另外,技术型的TL还应该是学习能力优秀的人。毕竟IT行业的技术更新速度是非常快的。如果你没有快速学习的能力,你就没有资格做好技术TL。技术TL除了管人管事,还有很多事情要做,包括团队研发文化的建立、团队人才的培养与建设、跨部门的协调与沟通等等,所以技术TL也需要有良好的沟通和沟通能力。管理能力,以上观点只是个人的一些想法和看法,仅供参考。
