@Lenciel

关于在家办公

因为疫情,很多公司都选择远程办公,网上也有了很多不错的指南,比如东旭的这篇

其实大部分在外企工作过的人都有远程办公的经历。

因为远程办公本质上就是团队物理上不在一个地方时产生的协同工作的方式:不管是团队分布在不同的大洲、国家、城市,还是分布在不同的建筑、楼层、房间,其实都是远程办公。

而这次,大家远程的选择比较单一,基本上就是在家办公。

这个我挺熟。

当年汶川地震,我就回成都 WFH 了两个月左右。

在刚创业的时候,我们也因为很喜欢 Basecamp 的文化 (「Remote」 和 「Rework」对我影响挺大),跑过类似的政策。

更不用说,我现在大块点的工作,基本都是所有人睡下之后在家里完成的。

要说有什么经验,那就是:远程办公挺难的,而且用工业化的角度看,既没有统一的流程和工具,也没有普适的最佳实践。

在家办公,难上加难。

我自己能够给的一点建议如下。

给公司管理层的建议

其实也是给所有人的,因为大家认知需要先对齐。

把有人在家办公当常态

远程团队,或者是分布式的团队,只是团队形态的一种。

理论上,你的团队人数超过一定数量,就一定进入这种形态,没什么特殊的。

因此,无论团队是不是有人在家办公,衡量团队效能的标准应该是一致的。

如果你的团队目标管理是透明的(比如大家公开自己的 OKR ),你的团队效能指标是靠谱的,就始终用它们,无论团队是否远程。

如果你之前没有这些指标(于是它们也很难短期内被纳入你所在公司的效能体系),那么感受一下:

  • 你的团队有没有确定的目标,所有团队成员都理解吗?
  • 实现这些目标有计划吗,所有团队成员都了解并进行了讨论吗?
  • 团队成员大部分工作时间是用于这些计划的执行吗?
  • 团队在执行过程中产生的讨论甚至是分歧可以被记录并跟进吗?
  • 这些讨论和分歧是否具有建设性?每个人都可以放心的提出自己的观点吗?

认真设计,反复实践

既然你的公司规模到了一定就一定会有这种形态,不妨借着这次机会好好练习一下。

远程办公的确会提供灵活性,但对于公司来说这个收益要真正获得,需要围绕沟通、协调、组织和文化进行精心设计和反复实践。

以沟通为例,下面的准则是重要的:

  • 先假设对方没有看到:让所有成员在同一个上下文是管理者的职责,因此有人远程的时候要做好这方面的工作会花更多时间的准备。就算你是管理层,也要习惯于重复自己,少说「就像我上周说的」/「根据我的上一封电子邮件」这样的话。
  • 多用表情少开玩笑:线上进行工作方面的沟通时,不要开玩笑,特别是讽刺类的玩笑。如果你实在想搞搞笑,使用表情符号。你的团队需要知道在线上,跟你提出任何类型的问题,都是安全的。
  • 正确决定何时使用同步/异步通信:同步通信(视频会议/电话/ IM 等等)使团队紧密联系在一起,对于讨论创新构想至关重要。在同步环境中解决紧急的事情也容易得多,但不要滥用。尽量减少对其他人的打扰,在每次启动之前问问自己:这件事是不是真的需要立刻响应?

给团队负责人的建议

  • 不要求大家设定一致的工作时间或说出他们何时工作。
  • 不鼓励甚至表彰长时间的加班工作。
  • 鼓励团队合作并公开表示感谢。
  • 鼓励人们写下所有信息。
  • 允许公司中的每个人查看和编辑每个文档。
  • 将每个文档视为草稿,不要等到它完成后再共享。
  • 在 Jira 中鼓励多使用清晰的屏幕截图,以确保每个人在任何时候都可以知道文字背后的思考过程。

给员工的建议

最核心要准备好的是,敢于问问题。

哪怕是你觉得有些丢脸的蠢问题。

如果你是新员工,这对你挑战更大。

虽然我说过,新员工最大的福利就是可以随便问。

虽然实践表明公开问比私聊要更加好

但还是有很多人觉得,私下问要舒服多了。

如果你已经了解问各种问题是任何工作的一部分,并且敢于在公共场合(工作群其实也是公共场合)提问而不觉得有任何不适,恭喜你,你准备好了。

否则你就还没有准备好远程办公。

  • 找到模式:每个人效率高的时间不一样,甚至需要的背景声也不一样,多尝试,找出适合自己的,不断重复它,形成模式。
  • 清晰沟通:和管理层沟通好自己的目标和计划,和家人沟通好自己的安排和需要,这是给自己争取时间节约精力的最好办法。
  • 设置界限:如果你有家人或者宠物,或者你不能抵挡厨房里的吃的喝的,请为这些干扰源设置界限。
  • 保持健康:创建一个符合人体工程学的工作区,哪怕多花点钱。进行有规律的体育锻炼,哪怕不能出门。

祝各位能够健健康康地高效工作。

生产环境优先

最近在想技术团队的文化。

最后得出来二十四个字:

「生产优先,数据驱动。简明清晰,求真务实。使命必达,精益求精」。

先来说说「生产优先」。

因为在之前呆过的公司都是管理技术团队的同时还要管理产品和运营团队,我逐渐有了一个认知:生产环境中的效能才是最重要的效能。

我甚至觉得,对于创业公司,生产环境的效能是唯一重要的效能。

不是说选 Scrum 还是 Kanban 不重要,也不是说代码审核/静态扫描等等最佳实践不重要,更不是说 Stage/QA 等环境上的测试不重要。

但是,在资源有限的情况下,必须要明白,生产环境的代码是我们唯一的资产,其他的一切都是债务

这样的认知对我最大的帮助是确定工作的优先级。

特别是在刚刚进入一个团队的时候,可以干的事情实在是太多了,优先级的选择如果出了问题,后果非常严重。

在很长一段时间内,我们会把跟下面两个方面有关的事情定为优先级最高的任务:

  1. 如何能尽快把高质量的代码部署到生产环境。
  2. 如何能尽快对生产环境发生的问题进行响应并处置。

这样的认知和优先级的排列,会反应在我们技术团队的很多实践上,它们中的一部分是违反传统经验甚至违反直觉的,所以我想稍作讨论。

下面是我认为「面向生产」需要遵循的几个实践原则。

工程师为自己的系统负责

没有这种文化的团队谈不上什么实践 DevOps 。

工程师不仅仅是开发或运维,我们的测试、数据等等职能的小伙伴也是工程师。

「为自己的系统负责」的具体含义是:

  1. 对自己的线上系统都应该懂得如何进行部署、检测和监控。
  2. 能按照自己的不同职能对线上问题的发现和解决作出贡献,让生产环境故障的感知、响应和处置变得更快。

在具备这种主人翁意识的团队中,我们会逐渐把线上环境的部署、调试等权限开放给所有人。但权利和责任是对等的,这也意味着:

  1. 我们要求编写可观察性好且易于调试的代码,并且始终关心用户体验和用户价值。
  2. 我们要求对自己的系统在生产中的执行情况从有好奇心到有控制力。
  3. 最重要的是,我们要求工程师随时随地为他们的系统服务——包括值班甚至是轮岗。

目前我们已经有一些工程师不定期的在一线进行支持,我认为有计划的值班和轮岗是很好的。在技术团队内部我们还要推开发去运维部门轮岗:这是建立团队内同理心的机会,同时也让我们的工程师体验到自己还有哪些方面可以做得更好。

但最重要的是,我见过两种架构师,一种是只能在自己的机器上写代码最多画画组件交互图的,一种是知道一个业务系统跑什么硬件用什么操作系统能够扛多少请求需要多少带宽的,后面那种我认为才是合格的架构师。

关于这部分的内容有很多细节这里不展开,比如生产环境的告警应该怎么配置,通知到哪些人;如何减少告警疲劳以避免事故被漏掉;比如怎样通过 SLO 驱动来创建 Production Excellence 的文化等等。

多听用户的声音

使用系统的人是最了解系统的人

这适用于人类构建的几乎所有的系统:统治者设计的任何一个高明的制度,最终都会被使用它的人找到漏洞。

就软件系统而言,多听用户的声音包括很多层面,我举几个例子。

  1. 外部用户往往会找到我们测试用例覆盖不了的问题。因此我们需要建立多个层次的用户反馈和行为分析渠道,来解决外部用户的问题。
  2. 一线的工程师更了解时间计划如何制定或者 Bug 是什么风险级别。很多公司的管理者会忍不住参与这些活动,但我们通过一系列的办法来保障工作的优先级安排交给工程师自己来完成。
  3. 业务研发等团队是基础设施/公共服务等团队的用户,他们往往会发现公共平台/组件一些问题,并且知道要怎么绕过那些坑。要有渠道搜集这些反馈,来对我们的内部工具包括内部工具的 UX 进行改进。

我们构建任何系统的时候,都要把创造用户价值放在第一位。

无聊的技术往往是好的技术

和 Dan McKinley 一样,我也通常首选无聊的技术

系统本质上是不可预测的,特别是我们目前构建的各种分布式系统。如果你和我一样看过 Scala 编写的系统崩了之后乱七八糟的堆栈,你就会同意还是应该使用有更好工具链的 Java 。

不仅仅是系统崩溃的时候,你还需要考虑一些常规的操作,比如部署、更新和数据迁移。越无聊的技术在这些部分通常已经做得越成熟,比如 MySQL ,它可能不是一个数据库爱好者听到之后会兴奋的选择,但是在绝大部分时候,我们还是选择它。

这背后的逻辑是,很少有创业阶段的组织有解决特殊问题的带宽。数据持久化的过程,在集群中选择新的 leader,查询时间序列数据,垃圾回收等,这些部分出现的问题可以消耗掉一个小的团队。我们应该吝惜自己的精力,把它尽可能花在客户价值的创造上。

软件行业里有三种技术团队:

  1. 开路先锋:它们研发创造性的方案,解决还没有被很好解决的问题。
  2. 吃螃蟹的:它们使用开路先锋的各种还没有稳定的系统,并且做出自己的贡献
  3. 稳定后跟进的:等到螃蟹被反反复复吃得无聊的时候,根据自己的需要选择合适的方案和系统的。

前面两种类型的技术团队,除非公司的产品本身就是技术系统(类似 Kyligence 或者 PingCAP),否则就应该务实的当好第三类团队,让前面两类团队先去踩坑。

让部署变得简单

部署应该像呼吸一样,频繁而平淡

但在很多公司它就像心脏搭桥手术一样,紧张兮兮,流程繁琐,代价高昂。

部署变得简单意味着:

  1. 手动步骤很少
  2. 查看部署是否成功很容易
  3. 当部署不成功时回滚很方便

现在我们看技术团队的效率是要统计部署频率的。因为在 lean theory 里面有一个很重要的指标是 batch size。但是因为软件的 batch size 很难衡量,所以我们考察部署的频率。

要追求比较高的部署频率,部署的过程,无论是技术过程还是决策过程,都必须足够的轻量化:所有的变更只要经过代码审核等一系列手段,不需要挑时间,不需要管理人员的审批,就可以上线。

频繁部署意味着每个变更的范围更小,通常它们都更快也更安全。

部署不够「简单」的时候,我们会规定一些上线的时段,比如「周五不做部署」。要把这种情况当成需要解决的问题而不是「最佳实践」。部署是公司的心跳,我们不应该规定心脏什么时候可以跳。

唯一的例外是假期的封版,这也是因为在线教育这类业务,确实会有假期的流量峰值出现,这种时候让所有人加班并不现实,所以可以运行一个稳定的版本不做任何变更。如果业务类型是假期流量较少的,那么也就没有必要封版。

QA 不是为质量「把关」的人

让某个角色来验证服务是否达到线上质量要求是弊大于利的

我们现在暂时由 QA 来进行业务系统的生产环境部署,这是整个技术团队资源和能力未达到下一个阶段前的无奈之举。

首先,我们现在还需要在部署之前完成不少的手动工作,比如集成测试等等,这慢慢会造成瓶颈:如果部署变得容易并且经常部署小的更改,则没有任何 QA 团队能够满足对每个部署都进行测试。我们应该不断提高自动化率并将其构建到 CI 中(如果它们确实带来了价值)。

其次,QA 团队经常缺乏环境,并承受时间压力。他们可能最终只能测试「用例」而不是「用户路径」。例如,我们经常看到 QA 需要在 UI 层触发一个事件,然后检查数据库的变化。当开发重构了 UI 并同时修改了数据模型后,往往会出现变化没有同步给 QA 造成的测试失败:虽然整个功能是正常的,但是按照用例去触发 UI 事件然后检查数据库发现没有按照预期变化。再比如我们经常看到 CDN 带来的测试中无法遇到的问题。

那么 QA 应该负责什么呢?我认为以后的 QA 团队的发展方向将会是:

  1. 在生产环境中进行「持续测试」,而不是在虚拟的 QA 环境中运行手动和自动测试用例。
  2. 在生产环境中进行探索测试、混沌测试。
  3. 和基础设施团队合作,致力于 CI / CD 的建设。

另外,需要明确的是,线上事故的发生率也不能作为 QA 的绩效目标。

它是一个参考值,说明整个团队的表现。

但必须知道,完全避免系统故障是不可能的,甚至是不可取的。

正确的做法是接受分布式系统的复杂度,并专注于怎么应对故障

这意味着我们整个团队要一起努力不断改进的事件响应流程,做好 RCA ,以及事故分析。这是一个巨大的领域,具有许多有价值的工具和资源,可在发生(或不发生)故障时最大程度地提高投资回报率。

先搞好生产环境

这一节我很想写下的标题是「只搞好生产环境」

随着工作年限的增加,我们都会经历很多的测试环境, Stage 环境从无到有被搭建起来。在每个项目和团队开始成长的初期,它们确实有意义。但是只要业务和团队真的长起来了,这些环境和生产环境一定会漂移。

非生产环境不会有流量,不会有复杂的架构,甚至不会用跟生产环境一样的数据库。所以通常情况下,花费大量的时间维护这些环境并骗自己它们和生产环境」非常一致「,还不如先搞好生产环境:

  1. 有没有很好的灰度策略支持
  2. 有没有很完善的熔断和降级
  3. 有没有很智能的流控和切换
  4. 有没有很完备的监控和告警

总结

「生产优先」作为我们宣扬的技术团队做事风格,体现着我们对西瓜价值观的思考:用户第一,客户第二,创造用户/客户价值的事情,才是第一优先级的。同时,它也表达了对系统复杂度达到目前阶段一些技术架构上的取舍和对各个职能的工作内容的调整。它包括了眼下的安排,也包含了未来的计划。