规模化软件企业的研发管理思考

October 7, 2021

前言: 本篇文章是关于软件企业的研发团队和开发管理的,单纯从字面看与中间件技术关系不大,然而现在中间件广义范畴,已经涉及到软件开发的每个领域。

特别是软件开发进入规模阶段后,需要使用配套的基础设施如云计算,以及相适应的管理方法。写下此文,对一段时间工作进行总结和反思。

一、软件研发企业的重定义

在传统思维中,软件开发是制作软件包装盒子,交给企业安装部署使用,用产品授权许可来保证合法购买,靠售卖软件产品来获得收入。其实从多年前开始,软件产品就已经改变了分发模式,通过下载可以部署在客户企业中,也是可以部署在任何地方,企业客户通过购买订阅来获得一定时期的合法使用许可,软件使用、支持服务、版本升级等都通过互联网完成。即使在客户企业内部,部署模式也一致,即私有云部署方式。我们称之为Saas(软件应用即服务)。

那么软件开发企业组织形式和开发模式,是否根据这种部署模式发生变化了呢? 答案为“否”,大多数研发团队还是使用“传统”的团队组织方式,具有常见角色划分:包括项目经理,产品经理,架构师,分析师,后端工程师,前端工程师,测试,设计,运维人员等。这种人员职能定义按角色划分没有问题,问题是与上面提及的软件部署模式间存在不匹配性。 不再销售软件产品或者产品竞争激烈,如果一个完备的团队辛苦做出来的一款软件,完全没有销售业绩怎么办呢?很多企业方法是由赚钱产品补贴创新亏钱产品,最后大概率砍掉这个项目和负责团队。

我认为软件开发本质是,应当从一开始就以“让软件用起来”作为目标,Saas模式对应的就是有用户使用。在初期,开发团队应该为“自己”研发业务系统,自己先用。即使是做项目给客户开发,也要有接近真实场景的业务环境,具备面向“外部用户”的可操作界面。微软称自己用为“吃狗粮”,金山研发办公室墙上贴的信条是“让软件运行在每一台电脑上”,就是这个道理。

软件价值和盈利能力是不同的,比如优秀的开源软件,使用是免费的,但价值非常大。而有些企业定制项目合同金额巨大,实施后却烂尾无人问津。价值和盈利没有强相关性。 所以软件能否销售的好,为企业获得巨大利润,是软件企业负责人重要要考虑的。作为研发管理负责人,可以退一步,专注在让软件能被更多的人使用这个角度。

听起来有些不合乎逻辑,对么?请您先继续往下看。

二、软件复杂度体现在哪里

软件的复杂程度,主要在两个维度:实体个数和并发访问量。

  1. 实体就是指领域驱动编程中的实体。我们经常也会在刚接触项目时问,数据库里有多少个表,也是类似的。 如果一个软件如果存在上百个实体,又包含有各种业务逻辑,那么整个系统一定复杂,可能只有项目分析师才能准确说清其中的各个业务组成。大型企业的业务管理软件一般都是这样。开发和维护这样的软件,性能只是一个因素,更重要的是可维护性,即代码可读性好、架构和接口定义清晰等等。 经典的开发方案一般采用单体架构,因为业务系统具有复杂性,又是各个团队一起协作开发,稍微管理不好就会开始混乱。 单体架构于是背了黑锅,“沉重”“巨石”“不灵活”等大帽子扣了上来。 可惜架构师们并不是很精通诸如模块化,重新热加载,单体内逻辑隔离等技术。 除了因为受到部署环境,如机器性能、应用服务器效率等因素限制外,单体架构完全可以设计成灵活的可插拔、可组装的。

大多数团队转而使用微服务架构,这里就遇到两个问题,一个是服务分拆方式,建议按照领域模型的聚合根进行实体类进行分拆;另一个就是需要微服务治理能力,跨进程的服务,必然需要一个更高层面的,可以管理多台机器节点的服务管理平台。坦率的说,对于大多数应用来说,微服务带来的管理方面复杂性,远远超过了单体替换成微服务得到的好处。

  1. 另一个复杂就是极大的并发访问量。当互联网带来的用户访问量远远超过一个机器集群能够承受时,并且每天产生的数据不断增加达到海量。软件设计就必须把业务重点放在如何支撑这些需要,而不仅仅是业务逻辑了。 比如我们听说过分库分表,就是典型的业务实现方法。我们举个现实例子,大家都还记得多年前春运时,需要提前到车站排队买票,客流量大的时候会开很多个售票窗口,这就是典型的应对高访问量而调整业务实现方法。当我们采用互联网售票时,消费者就不用再面临那么多窗口选择时的困扰了。 也就是说,高访问量带给软件的复杂性,其实与用户无关! 所以用户根本不需要知道分库分表这些技术,但却要知晓甚至熟悉精通实体概念。我们经常听到,某柜员业务精湛,很有可能是对业务熟悉并对业务系统使用了如指掌。

那好,我们回到研发管理。对于一个研发团队,上述哪个是更重要的维度呢? 显然是实体定义。因为我们说了,大的并发访问量得以解决,并不是最重要的业务逻辑,可以由基础运算设施承担很多,尤其现在有了“云原生”的概念,已经将不属于商业业务逻辑的部分定义为非业务功能,希望由云计算设施全部承担了。 理论上来说,只要花钱就可以解决问题。对实体概念的掌握,成为研发团队能力建设的关键。

研发管理平台化

微服务三大维度包括,功能性、水平复制和数据分片。

其中水平复制和数据分片由云计算提供。云计算环境中有云设施计算能力和中间件服务。 应用程序架构有多层Ntiers,微服务,EDA(响应式编程简化心智),数据处理(MapReduce流批一体化)等。 协作模型有状态保存,方法调用,数据绑定,Actor等等。

  • 对于研发团队,需要重点建设一个Devops平台,涉及到开发、测试、运维等方面。
  • 研发的代码可以被管理,测试,构建,部署,上线,运维。
  • 每一个开发者都是在这个Devops平台上进行开发,成果物作为软件的一部分,体现在Saas服务上,供内部外部的用户随时使用。
  • 研发团队之间就是要进行协作,管理维护数量众多的服务组件。整个研发机构关键能力就是减少风险,提高效能。

研发管理平台范畴中,需要有类似ESB的软件,作用是进行系统集成和数据交换共享。是否是传统意义的企业服务总线软件不重要,重要的是这种对于数据集成和使用的能力,在研发平台上要体现出来。 对于开发者来说,可以面对最简化的数据集或者业务接口方法,甚至是聚合后跨多个业务系统的方法调用。这时ESB也是云计算设施,帮助研发团队来管理,监控,记录数据信息的流转过程。开发者不必写代码实现这样的功能,免得费人力又需要维护软件。 当然,这需要更强的整体交付能力,也就引出云环境管理的话题。

现在企业内部基本都有云平台,有的使用公有云,有的自建私有云,有的可能只是虚拟化平台,也被定义为企业云。

如果开发的软件,希望在云平台之间迁移,就需要同时支持多种公有云和私有云环境。 然而,目前公有云之间API接口定义各不相同,私有云就更不必说,对Iaas和Paas功能支持都是参差不齐的。 目前我们有两种选择:

  1. 基于都具备的云功能进行开发。这方面最优选就是Kubernetes(K8s),几乎所有的公有云都支持K8s集群,企业内部可能会采购产品化做的更好的Openshift和CloudFoundry,也有很好的支持,K8s是个可选项。不过需要考虑的是K8s设计思路更多面向运维而非开发,需要针对业务开发做架构设计,即K8s的“云原生设计模式”。目前总体来说,针对K8s设计方法论还处在“正在成熟”阶段。
  2. 还有一种思路是只在容器层面采用云计算设施,因为容器技术已经进入到主流操作系统的主要维护仓库仓库之中,无论RHEL, Ubuntu, Debian等都有LTS安全升级服务。用容器的打包部署方式;访问云平台则使用云中间件。即“传统”的中间件是构建在操作系统之上的,而云中间件是基于容器技术和云计算服务能力的。云中间件发挥其承上启下的优势,屏蔽云计算平台差异性,并提供良好的性能和可管理性。

规模化软件研发管理

回到我们开头提到的问题:对于现代软件企业,研发团队如何配置和管理呢? 之前提到的软件开发的各个角色还是存在的,但他们的知识技能,有些已经融入到云平台提供服务能力中了。 理想情况下,每一个项目或Saas服务,都可以从最小化资源需求开始,项目负责人具有一定的全栈技能和全局把控能力,能利用机器硬件和平台特性的,就尽量不使用人力资源。有合适三方服务可以利用,在项目前期充分使用外部服务资源。只有真正为项目业务功能实现提出的资源需求,才考虑申请所需要的技术资源。

所有的开发人员,都有技能标签,项目经理不是通过组织从属的关系征调,而是通过项目工作说明书的定义来吸引人才竞聘上岗。 开发者进入到项目之后,工作成果物就可以通过Devops平台给他人使用,同时也接受研发指标评估,这些成果会和薪资待遇进行挂钩。

看到这里,可能有些朋友会说太理想化,不符合现实条件。 现在的确存在这样的问题,当前国内软件开发团队管理方式各不相同。尽管有些互联网企业在一些服务项目上有类似做法,但在人员组织,职责分工上也有不同之处。

我相信,这是软件企业研发管理,更确切的说是软件开发未来扁平平台化发展一个重要趋势。