开发经理的职责

  一年前一个偶然的机会参与了公司的一个重点项目,须要长时间出差,开发团队规模在20人左右,并且时间紧迫。在异地,少了公司技术团队的支持,远程沟通不方便,不少事情都显得比较困难,碰到问题每每须要本身摸索,本身解决。有句话说,一个开发团队有的时候就像一台发动机,只要启动起来,就能有成果和产出。但若是方向存在误差,发动机越跑越远,可能收不住脚,最终会致使项目失控。很庆幸,咱们这个项目顺利上线,顺利完成电商大促,以及最后顺利交付。但中间的存在一些风险点以及经验教训仍是值得拿出来总结一下。web

  一般开发经理或架构师会早于开发人员介入项目,了解项目的需求,系统分析,作相关的技术选型,制定开发计划与开发规范。redis

  在制定技术规格说明阶段,开发经理或架构师要协调起全部的开发人员,指定相关的技术规范与开发人员保持沟通,让开发人员理解他们负责的模块或者子系统,确保开发人员可以按照架构意图实现各项功能。数据库

 

1 基本编码规范缓存

  这个基本上每一个公司都有一份这样的文档(若是没有你基本上能够考虑job-hopping),这个文档通常跟项目无关,好比命名规范,注释规范,SQL规范等等。另外,要统一jdk,包括本地开发环境、服务器环境;定好项目名,包名,数据库名,表名,以及是否每一个表须要通用字段(如version乐观锁版本号)等等。服务器

  这里重点强调2个地方,工程规范和包名目录规范。数据结构

  工程规范:要明肯定义每一个工程模块的边界,尤为是在分布式系统中,这一点显得尤其重要,开发人员要对框架的层次结构很是理解,好比何时该定义DTO,何时该定义Domain。这个若是没有搞清楚,在项目的整个生命周期里面,项目的体积愈来愈庞大,这个问题一旦暴露出来简直就是灾难。多线程

  包名目录规范:包目录规范要尽量从顶层开始,开发人员的包目录权限要尽量低,简单的说就是尽量让开发人员少去建包,这一点很像日本的外包项目,目的就是统一规范。另一点,要避免两个工程模块出现相同的包路径,这样在引用的时候极有可能出现冲突。架构

2 定义好组件的边界和职责框架

  系统分解以后,要定义好组件(子系统或者模块)的边界和职责,这个是项目初期开发人员最关心的问题,若是这个没有定义清楚,后面系统就要面临重构的危险。异步

  好比基础数据,并非全部基础资料、配置信息都放到基础数据中,只有跨系统、跨服务、模块的基础资料、配置信息才属于基础数据管理范畴;另外基础数据服务的接口须要具有必定的通用性,尽量减小针对某个系统、服务、模块开放特殊接口;而且不容许基础数据服务依赖上层服务。

3 项目版本定义

  项目初期,除了一些基础的模块,好比工具类等公共模块可能被打包成Release版本,其余的通常都是SNAPSHOT版本,当项目陆陆续续上线以后,好比分布式系统中RPC调用要给客户端系统提供jar包引用,版本控制的做用就会凸显出来。这里推荐一批文章《语义化版本2.0.0》,是关于语义化的版本规范,这个规范是由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werner 所创建。

4 svn代码管理与发布规范

  根据项目的开发模型,定好代码的主干(trunk),分支(branches),基线(tags)的关系,以及相关环境的发布流程规范。

5 自动构建

  在分布式系统开发中,没有自动构建简直不敢想象,每每一个项目有不少个子项目部署在几十台甚至几百台服务器上。若是没有自动构建,开发人员有可能要花费大量的时间在服务打包发布上,一旦须要立刻发布一个测试bug,都须要很长一段时间,这会另整个团队精疲力竭。

6 代码日志规范

  项目的日志在生产环境上禁止将日志输出到Console中。项目代码中都须要经过Logger对象来输出日志和异常,禁止使用system.out.println等方法进行输出,禁止使用e.printStackTrace来输出异常。日志须要经过日期、大小两个维度来分割文件,避免日志文件过大没法打开。生产环境的日志级别禁止开启DEBUG,若是排查确实须要则能够针对特定类打开而不能将整个环境设置为DEBUG,可能会形成系统由于文件锁卡死。

7 统一异常处理

  分布式业务处理系统,系统中存在大量的跨服务调用,而且须要对不一样类型的异常作不一样级别的处理,处理的方式须要随着系统的不断扩展而适应不一样类型的异常处理,而且作到跨服务的异常统必定义和快速定位跨服务的异常发生的源头和缘由。通常经过定义全系通通一的异常编码,并定义其产生的缘由,并须要达到识别系统的目的。

8 提供批量更新方法

  批量更新必须使用提供的统一批量更新方法,对性能有很大的提高,若是有很是特殊的场景需求没法使用则必需要通过评审,不然这有可能成为一个性能瓶颈。

9 尽早提供基础服务

  如短信服务,邮件服务,这些基础服务要优先安排开发,由于几乎每一个模块都有可能涉及到。

10 规范多线程写法

  若是系统中有用到多线程,不要随意开辟线程,尽量使用统一的线程池,并封装公共的调用方法以及返回结果。

11 规范事务的处理

  11.1 避免产生一个较长时间锁定多行数据的事务,尽量将事务拆解或改成异步。

  11.2 分布式事务

    在项目尽量不经过数据库层面的分布式事务来实现数据的一致性而是经过异步、补偿、幂等等方式来实现数据的最终一致性。

l  幂等性:

       任何对外提供的服务入口方法都必须实现幂等性,重复使用一样的参数调用同一方法时总能得到一样的结果,而不会形成重复的处理。

       查询服务:查询自己就是幂等的,因此不须要作额外的处理。

       新增服务:经过惟一性约束来控制数据的惟一性避免重复写入数据

       更新服务:经过乐观锁来控制数据的幂等性

       删除服务:删除自己也是幂等的,因此不须要作额外的处理

l  异步消息处理:

       跨系统进行事务处理时尽量的使用异步消息处理来进行,先将数据保存为一个中间状态,并将消息写入MQ,由下游系统订阅处理。下游系统处理完以后再将结果反馈给上游更新状态。MQ中写入的数据正常状况下不要使用完整数据,会形成MQIO压力很高并且数据多是已通过期的,而且会将队列变成专用而不是通用,可能没法被其余服务订阅。

l  补偿

MQ处理时可能存在消息丢失、故障等问题丢失数据致使流程中断,因此须要补偿措施来保障流程不会长时间中断。由一个分布式事务的最上游系统提供一个定时补偿措施检测长时间未完成事务的流程,并从新触发这个流程(从新写入MQ)。

12 肯定基础数据缓存方案

  缓存每每被忽视,等到项目后期碰到性能瓶颈的时候才发现须要重构,那个时候的代价是很大的,因此须要尽早的定好缓存方案,是用ehcache? guava? redis?这个要肯定下来并让开发人员实施下去。

13 规范缓存环境使用

  memcached/redis缓存环境规划,要定义好数据结构使用规范,好比不能让全部人都用key/value这种方式来存储,最终致使缓存环境脏乱。

14 分布式文件存储

  尽早肯定是在物理上作共享磁盘?仍是使用分布式的文件系统?

15 单元测试

  编写单元测试要成为一种习惯,另外,单元测试应该是没有反作用的。定义良好的单元测试在运行屡次的状况下,若是没有其余条件发生变化,那么每一次都应该产生彻底相同的结果。好比说,在数据库中一般会插入一些假数据,而后在测试中验证这些数据,这种方式的测试不可靠,由于数据库可能发生变化。能够在单元测试过程当中使用内存数据库或者每次单元测试的数据都是自动生产最后自动删除的。

  许多同事怕写单元测试的一个主要缘由就是依赖太多(远程服务调用、redis、webservice等),若是一个服务由于种种缘由挂掉了,那么这个测试就会失败。要解决这个痛点,能够引入mock对象能够知足这些条件的需求,而Mockito正是这样的一个框架,用Mockito来模拟相关行为,不用费力去准备各类依赖环境,这时只需专一于业务逻辑便可。

相关文章
相关标签/搜索