我们讲工程师全能,会说他是全栈工程师;类似地,敏捷有个全功能团队的说法。这些角色定义,直观地表达了团队成员的职责划分与协作模式。DevOps 实践通常理解为开发人员(Dev)与运维人员(Ops)的融合,融合到了一定阶段也会自然会出现旧角色的消失。既是角色消融,接下来,我们就先讨论一下这 DevOps 的渊源,看看过去我们都有哪些消融。

所谓消融,其实是先融合再消退。在越小的团队里,越能看到多种角色的重叠与融合。极端一点来想,如果一个产品是由一个人开发完成的,他一定是全栈工程师。虽然在这个栈上,可能他也并不是所有部分都擅长,但肯定每个部分他都要通晓一二,包括一些 DevOps 实践。

我们先从一个典型的作坊式团队说起,看看角色重叠和消融是怎么发生的。

作坊式团队

作为团队来考查的话,作坊式团队与全功能团队很类似,他们都尽其所能、尽快将需求实现为可以工作的软件。所不同的是,作坊式团队没什么章法,没有明确的质量意识和技术先进的追求,他们的主要工作就是尽可能快地完成代码的实现。

所以,试着想一想,给你一台服务器,问你以最快的速度让用户看到一个 Hello World,你该怎么做?

开一个 Visual Studio,建一个工程吗?
不,一个 node.js 文件,10 行就够了!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

作坊式的团队的问题在于这种快不能持续,至于质量嘛,是其次的。不过,就像上面说的一人项目一样,在作坊式的团队里,角色的重叠却十分常见。因为,要快嘛。这种情况下,反而大家的目标很一致,把实现了新功能的代码立即发布上线!通俗一点讲,不少作坊式的团队就是一两个全栈工程师(高工)带着一帮工程师(码农)在撑着。

简单回顾一下以前在作坊式团队里发布版本的情景(如图):

  1. 周五早上大家把代码提交完毕,由我和另外一位同事把代码拉下来完成编译、打包(获得一堆 dll,以及 config 文件等)
  2. 将获得的程序包从远程桌面复制到新分配的服务器上,部署应用程序
  3. 用临时域名进行一轮简单的测试,发现问题就快速修复(后续所有步骤均使用此方法修改代码,图中虚线)
    1. 配置的问题,就直接在服务器上改
    2. HTML、CSS 的问题,就直接在服务器上改,刷新浏览器看是不是修好了
    3. 逻辑代码的问题,就在本地电脑上修复代码、再编译获得一个新的 dll,传到服务器上替换掉包里原来的 dll 传到服务器上
  4. 一切完备之后,等待在线用户少的时候,准备上线:将线上服务器的数据库A设为只读,备份为数据库B,将新版本程序连到数据库B,完成数据库结构的变更
  5. 将线上域名解析到新服务器上,完成新版本发布上线的过程
  6. 再快速做一轮测试,试一下用户能不能登录,核心功能能不能用
  7. 将刚才第 3 步里,在服务器上修改的代码合并到本地来(图中虚线)

image

角色重叠

先不着急来评判上面流程中的问题,我知道很多团队现在还在这样做。我们主要关注角色,来看一下这个过程如果发生在一个规范化的团队中,会涉及到哪些角色(加粗):

  1. 产品经理测试负责人:编译代码,发布新版本
  2. 运维工程师:分配服务器
  3. 测试工程师:在临时环境回归测试
    • 开发工程师:编辑代码修复问题
  4. 数据库管理员,运维工程师:切换一系列数据库操作
  5. 运维负责人:更新域名解析
  6. 测试工程师:在生产环境回归测试
  7. 开发工程师:合并代码

随便一数,七种角色。这在小而美的互联网团队是很奢侈的,一定会有角色的重叠。如果某一岗位只有一个人,那他自然也就是负责人了,所以把测试经理与测试工程师、运维经理与运维工程师合并之后,还剩五种:

  • 产品经理
  • 开发工程师
  • 测试工程师
  • 运维工程师
  • 数据库管理员

image

如今很多团队只有不到十人,甚至三到五人而已。在这些团队里,上面这五种角色,能做到每种角色至少一人吗?回想一下你曾经参与过的作坊式团队,或者环顾一下你现在团队里的角色——如果你正处于作坊式团队之中的话,从上述五种角色中,试着挑出你们团队里没有的角色吧!

上面说过,很多作坊式团队就是一两名高工带着几个码农。这些团队里很可能是由一两个人担任上面所有的角色(高工),其他人(码农)都是开发。某种意义上,也可以说作坊式团队把这种角色重叠的效果发挥到了极致。

如果说作坊式团队中的角色重叠是资源不足而迫不得已的话,那还有没有其他原因导致的角色重叠?

消失的 DBA

如果再回到上面的列表,相信很多人第一个就会把数据库管理员从列表中去掉——因为他们的工作运维工程师也可以做。在今天,我们完全可以这么说。可放到十年之前却不是这样:那时候,DBA 还是一个炙手可热的工作岗位。在外人看来,他们有四两拨千斤的力量,所以他们受到程序员和所有人的顶礼膜拜。著名的大 V 冯大辉就是著名的早期 DBA 之一。

image

然而不知不觉间,他们的工作慢慢被运维工程师替代了。这是因为现在多数应用开发不再用存储过程来开发应用了,应用程序对数据库的需求如今只限于数据备份、主从热备了,而曾经的存储过程开发、SQL 调优、触发器和视图维护等工作(回想一下曾经维护一个个几十上百行的 T-SQL、PL/SQL 文件的年代)已经被新的开发方式所取代。

要知道,现代化的 ORM (EntifyFramework、NHibernate、MyBatis 等)不光是让我们操作数据库更方便了,它们更让代码本身变成了能够设计数据库结构(Schema)的一种设计工具,我们不再需要用到 PowerDesigner 之类的建模工具了。这种从代码出发(Code First)的方式,让我们在思考应用程序的架构的时候,不用担心重新设计数据库结构成为负担。因为这些工具还让我们在应用程序的重构过程中,更容易地把对数据库结构的调整增量地应用到数据库里去(即数据库迁移)。最终,业务逻辑从数据库回到应用程序代码中,对数据库本身的操作也变成了由代码驱动。

另一方面,近年来大规模互联网应用的实践中逐渐发现关系型数据库的一些不足。比如,当数据量大了之后,难以大规模集群部署;数据结构复杂了之后,大量的多表级联查询对性能的损失也日益明显。为了解决这些问题,以 MongoDB 为代表的 NoSQL 数据库很快得到大量运用,一定程度上替换了关系型数据库的使用。

这样一来,以前 DBA 的工作也就只剩下了做日常备份这类维护性工作了。这大概就是生产力决定了生产关系吧,开发人员这边的生产力的变化,让基于数据库的开发日渐示微,与数据库相关的工作越来越融入到了开发人员和运维人员两边,DBA 这一角色就这样消失了。


作坊式的团队在形式上与专业的全功能团队很接近,这也是为什么小团队往往更容易培养出工程师文化。著名博主陈皓曾分享过打造一支强大的小团队,讲的就如何利用营造工程师文化来让团队自发地展出高效生产力。在 DBA 角色的消失的过程,没有人感受到一丝违和感,反而在 2018 年的现在,我将“DBA”再翻出来讨论,人们却会感受到这种违和感。

角色的重叠和融合让生产关系重组,积极的重组能够带来效率的提升,也有可能带来难以管理的混乱。我们不妨思考,会不会有一天,上面的列表中的其他角色也会继续消融?这种消融会以怎样的方式出现?敬请期待下一篇。