V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kshift
V2EX  ›  分享发现

Tower 的产品开发流程

  •  3
     
  •   kshift · 2019-05-08 15:52:46 +08:00 · 2202 次点击
    这是一个创建于 2026 天前的主题,其中的信息可能已经有所发展或是发生改变。

    作者 @徐峥

    Tower 迄今为止已拥有 80 万的注册团队,这些团队来自不同的行业和领域,使用 Tower 进行协作的姿势也是五花八门,每天我们都会收到大量来自用户的需求。而作为一支只有 10 来人的小团队,我们怎么才能更加快速和高效的对用户的需求进行响应,是对 Tower 产品团队来说最大的挑战。

    我们的产品开发总结起来有如下几个阶段:需求梳理、产品设计、迭代开发、灰度测试、上线发布,以及一个长期的 Bug Fix 过程。在 Tower 里,我们有三个围绕这些阶段的核心项目,分别是整理需求和进行设计的「 What's Next 」,以及围绕开发、测试和上线的敏捷迭代项目「福克斯 RS 」,最后是长期处理 Bug 和一些临时的优化任务的「机械师」:

    Tower 团队的主要项目

    接下来我会跟大家具体介绍我们团队是如何使用这些项目进行各个阶段的协作,抛砖引玉,和大家一起探索更高效的产品研发流程。

    🎤 需求梳理

    一款经过了 PMF 的产品上线以后都会收到各种不同的用户声音,这些声音应该通过整理进入产品需求池,然后经过产品经理的分类后,进入下一阶段,总结起来,需求梳理阶段我们需要做两件事情,一是需求收集,二是需求归类。在 Tower 里,我们创建了一个叫做「 What's Next 」的项目来做这些事情:

    涉及需求梳理的清单:Inbox、暂不考虑、确定要做

    关于需求的收集,我们要求处理好两个要素,一是来源,二是尽可能详细的上下文。

    对于我们团队,需求的来源一般有三种:客服反馈产品汪自创以及其它部门的需求。我们创建了三个项目级别的标签来定义这三种来源,在创建需求任务的时候选择一种标签添加上去:

    用标签给需求分类

    有些客服在收集需求的时候把详细的需求描述写在了在任务标题里,我们认为这是不太好的操作方式,创建任务时标题应尽量精简。比如遇到这么一个需求:

    用户希望在「我自己」页面中,能快速的更改任务所属的项目和清单

    那么这种需求的题目最好是「更高效的编辑自己的任务」,这种标题是对用户诉求的抽象,如果一周遇到 N 个对我自己页面的相关的需求,那么都能放到同一个任务下面,方便产品在设计的时候集中考虑。

    4.jpg

    需求的上下文详情,我们要求在任务的描述中进行填写,如果是来自我们客服系统的客户需求,只需要粘贴对应的链接地址即可。多说几句,客服对于做 SaaS 产品的团队来说其实是个蛮重要的角色,如果只是简单的做客户的传声筒,那么客服的价值完全没有发挥出来,好的客服对自己的定位应该是「产品助理」,在协助用户的同时,应尽量多地挖掘用户诉求的本质,也就是说帮助产品经理找到用户「需要一匹更快的马」背后的真实诉求,至少把用户这诉求背后的痛点问得清清楚楚。

    5.jpg

    每周五下午 17 点,产品小组会召开产品例会,对需求进行梳理,这个会议要求产品经理,客户成功部门负责人,UI 设计师和工程 Leader 一起参与。这个例会做两件事情,一是分析用户需求背后的场景,二是将需求移动到下一阶段的清单。

    在需求场景清楚以后,不做的挪动到「暂不考虑」清单中,剩下的挪动到「确定要做」的清单里。

    挪动到「确定要做」清单里的需求,我们通过上下拖动顺序来设置优先级。Tower 团队鼓励每个成员发挥自己的自主性,对于确定要做的需求,任何人在任何时候,都可以通过评论的方式提供设计或开发建议。

    「暂不考虑」这个清单里的需求会随着时间的推进越来越多,之所以没有直接把这些需求关掉,是因为这里的需求也属于用户的声音,我们鼓励团队成员从各种渠道了解用户对产品的看法,这些需求只是在现阶段的产品规划中不太重要,但是背后所代表的用户以及场景是永远都不应该消失在产品团队的视野里面的。

    🎨 产品设计

    需求梳理结束后,会进入产品设计阶段。对于 Tower 这样的小团队来说,人少事多,产品经理没法花大量的时间去写详细的需求文档,设计师也没有办法每个需求都出详细的 UI 设计图,所以需求也要分为两类,一类是需要设计师设计重点设计的,另一类是工程师和产品经理能自行讨论出实现方案的。

    需要设计师介入的需求,挪到到「 What's Next 」的「设计中」清单里,按照产品经理的优先级分配给设计师进行设计。产品经理和工程 Leader 确认工程师能自己实现的需求,挪到「设计结束」的清单里,等待迭代周期开始时和工程师讨论并认领。

    6.jpg

    有设计师参与的需求,产品经理每天都会跟设计师讨论完成进度。设计师会把已完成的设计稿放在 Zeplin 上,在这里产品经理按照设计图的上传时间和设计师讨论具体的设计细节。期间有不清楚的工程细节,我们也在 Tower 使用 Zoom 视频会议拉上工程师参与。工具不能代替人和人的沟通,比起厚厚的需求说明文档,我们发现小团队通过快速且频繁的沟通对于产品的设计迭代更有帮助。

    7.jpg

    这里需要特别提及一下的,就是挪动到「设计结束」的这些需求,工程 Leader 会给它们打上表示难度级别的标签。团队虽小,也有工程师的级别梯队,我们团队目前有三个级别的工程师,初级 P5,中级 P6,高级 P7 (为啥是从 P5 开始呢?给自己留点余地吧,万一团队变大了,就可以向下扩展槽位了嘛:D )。产品经理在挪动任务到「设计结束」清单的时候,需要工程经理协助确定需求的工程难度,打上对应的标签,这样在开发迭代的时候,确保工程师处理的任务在自己的能力范围之内。

    至此,需求的拆解和设计都告一段落,接下来就进入产品开发的阶段了。

    🔧 迭代开发

    Tower 的工程团队使用敏捷开发流程,团队规定每两周为一个迭代周期。我们会给每次迭代周期指定一个「版本号」,版本号是以自然年 + 当前的周数为标记,比如 2019 年 3 月 25 日开启了一次新的迭代,那么这次迭代的版本号就是 19.13,19 代表 2019 年,13 代表 3 月 25 日开始这天所在的周数是 2019 年的第 13 周。

    我们会在每周一上午 10 点的工程组例会上,启动这次迭代。在这个迭代启动会上,产品经理会和工程师会共同 review 「 What's Next 」项目的「设计结束」清单里的需求,产品经理会大致讲解需求的背景和设计的思路,然后分派给对应的工程师。

    接下来,工程团队会围绕我们的第二个主要项目「福克斯 RS 」进行协作。嗯,这个项目的名字是我们团队的赛车手产品经理同学命名的,是他最喜欢的座驾的型号,对于 Tower 来说,福克斯代表了专注,RS 代表了速度,工程师在迭代周期里,应该用最快的速度,专注于自己的需求的实现。

    这个项目我们分为 Story、待处理、执行中、内测、公测、全量发布等清单:

    迭代项目:福克斯 RS

    迭代启动会议当天,我们会在这个项目里创建一个新的版本标签,然后在 「 Story 」 清单里创建对应的任务,这里的任务并不是从「 What's Next 」项目里直接移动过来的,而是新创建一个任务,在任务描述里,我们会复制原始需求的链接(有时候也会复制任务)。

    之所以这么做,是因为「 What's Next 」项目和「福克斯 RS 」项目的协作群体不同,前者是产品经理、设计师以及运营人员关注的项目,后者是工程师协作的项目。前者需要看到产品进展的全貌,包括用户现有的需求有哪些,产品上决定要做的有哪些,以及正在做的和已经发布的有哪些。这些工作应该完整的保留在「 What's Next 」项目里,方便这些人员查看。

    迭代中 vs Story

    而「福克斯 RS 」强调速度,每个迭代周期,工程师只应该关注当前周期里需要做到的事情,因此 「 Story 」 里只会留下这个迭代周期里应该完成的任务,工程师可以足够聚焦。我们要求产品工程师在迭代开始时,按天为单位分拆 Story 里的任务,分拆后将任务放置在「待处理」清单里,并且用 # tag 的方式标注任务的原始 Story。工程师在迭代周期里,每天只需要从「待处理」中选择一条具体的任务,拖动到「进行中」清单里即可。

    10.jpg

    每个工作日结束的时候,工程组的 Leader 会和工程师核对完成进度,这种核对并不是为了考核工程师的工作量,而是对可能的风险进行评估。

    我们可能需要承认一个现实,就是产品功能进入开发阶段以后,大概率是会出现设计阶段考虑不到的问题的,工程师如果只是按照产品经理的「需求说明」进行开发,非常容易掉进坑里。工程师在做实现的时候,往往会有他自己对场景和解决方案的理解,我们也鼓励工程师主动的思考用户使用产品的痛点和场景,产品由工程师用代码打造,因此工程师理应对产品的最终使用者承担更多的责任。每天和工程师讨论一下负责的任务的进展,不用花太多时间,了解他对任务背后的需求的看法,及时对任务范围进行调整,可以减小延误的风险,这个过程是工具无法自动化处理的。

    工程师每天完成进行中的任务后,会直接关闭掉任务,然后再从待处理的清单中挪动新的任务进行处理,周而复始,直至 Story 相关的任务都被完成。

    🎏 内测

    在迭代周期里,我们会要求工程师尽快的将功能推进至「可以品尝」的阶段,达到这个阶段后,功能负责人会把卡片从「 Story 」清单里拖动到「内测」分组中,并且把产品功能部署到内测服务器上,供我们自己团队试吃。

    我们的内测使用灰度机制来实现。我们在早期会用一些独立的服务器来搭建内测环境,使用这种方式最大的问题是,它和实际的生产环境是隔离的。这种独立的服务器上没有正式的数据,因此团队内的同事往往只是走过场一样的在里面去「玩玩」就结束了测试,这样是达不到我们预期的目的的。

    因此后来,我们改进了内测的方式。我们有一台和生产环境数据库直联的 Web 服务器,这台 Web 服务器会部署内测分支。我们会在后台给我们自己的团队增加一个内测的 Cookie 标志位,这样 Nginx 在收到每个 HTTP 请求的时候,就会根据这个标志位判断是否把请求转发到特定的内测服务器上。

    灰度机制

    这样,每个新功能我们自己团队能够在真实环境下实际使用一到两周左右,有了真实数据的加持,这样的测试会完全还原实际场景,让很多问题在内测阶段就能暴露出来,帮助产品进行改进。

    🛫 公测

    内测完成后,我们还会有一个小范围公测的阶段,公测的原理和内测是一样的,也是把参与公测的团队的流量转发到一台公测服务器上。

    选择公测团队的标准会根据产品功能而定,有些是比较高频的功能改进,比如和任务相关的,那么公测的时候会让免费团队的占比高一些,免费团队使用任务相关的功能的频率很高,所以相关功能的改进这些团队也能有比较好的敏感度,有任何问题免费团队也能很快的跟我们进行反馈。

    我们通过任务检查项的方式将测试期间的问题罗列出来,并且指派给对应的功能负责人,进行修复或者优化。

    测试反馈检查项

    检查项的详细描述,我们一般通过评论的方式直接发在任务后面。

    当然,并不是所有的功能都需要走到公测这一步,有些简单的改进,团队内测已经没问题的,就会略过这个阶段。

    🛬 全量发布

    内测和公测结束的任务卡片,会被移动到「全量发布」清单里。迭代周期的最后一周的周五下午 4:30 我们会召开产品例会,检查全量发布清单里的卡片,产品团队确定是否可以发布。

    发布之前一般需要确定:

    1. 测试是否通过;
    2. 是否有需要大批量迁移的数据,如果有,需要在测试环境提前做预发布测试;
    3. 是否需要调整产品站的常见问题模块;
    4. 是否需要引入新功能弹窗,如果需要弹窗,客户成功团队需要提前准备新功能日志。

    Travis CI

    这些工作一般在周末能够完成,正式发布时间我们会放在周一中午,这个时间团队的工程师都在,如果遇到发布问题,可以快速回滚或者修复,另外还有半天时间可以用来收集用户反馈。

    🔍 Bug Fix

    功能发布以后,肯定会遇到各种各样的问题,可能是代码的报错,也可能是产品上的疏漏,我们要求产品团队应该尽快的修复这些小问题,而不是等到下个大的迭代周期结束后才做更正。所以我们在每次 release 了一个大版本之后,都会生成一些小版本来修复这些问题。

    比如我们周一刚刚发布的上一个迭代的版本是「 19.14.0 」,那么首先,工程团队会在 Github 上创建一个叫做「 19.14.1 」的分支,这种分支我们会使用 Github 标准的 PR 模板来初始化,里面会固定分为:

    Patch PR

    我们创建了一个叫做「机械师」的普通项目来收集所有的 Bug。其中有两个主要的清单:

    机械师的两个主要清单

    MAYDAY 是从告警平台上面直接捕获的服务器内部报错。我们使用 Sentry 作为告警平台,这个产品可以设置告警发生时的 Webhook,我们团队搭建了一个收集告警信息的中转系统,收到从 Sentry 发来的告警后,中转系统会调用 Tower 的 API 直接往 MAYDAY 这个清单里创建任务,并且指派给对应工程模块负责的工程师:

    错误信息自动收集

    工程师收到后负责修理报错,每个报错的修复我们都会在 Github 上拉一个修复的 Pull Request,PR 的名称以 「 FIX: sentry#XXXXX 」固定,这样在 review PR 的时候可以很方便的找到原始的报错信息:

    Fix PR

    这个 PR 会 targeting 到最新的小版本号上,随小版本一并发布。小版本的发布通常一天会有好几次,尽快修复用户的问题。每次的发布我们会在 Github 上记录对应的 Release,这样团队成员都能非常清楚近期发布了哪些产品功能,以及发布点在什么时候:

    Release * 997

    📌 写在最后

    产品研发流程,其实是没有「最佳」实践的,每个团队都有各自的特点,产品是什么,业务场景是什么,团队是什么,每个团队都有各自的不同,因此每个团队也不会有完全统一的流程。

    不过我们认为,高效产品研发的前提一定是招募到真正热爱产品的成员,以及对这样的团队放权和赋能。流程应该是帮助团队更快的开发对用户有价值的产品,而不是控制产品团队的工具。而彩程也正是基于这样的价值观设计 Tower,保持简单、灵活和高效。

    团队协作,从 Tower 开始。

    3 条回复    2019-05-09 08:27:17 +08:00
    ihipop
        1
    ihipop  
       2019-05-08 17:37:03 +08:00 via Android   ❤️ 1
    最早用过,最简单的任务依赖都不支持
    cantonadong
        2
    cantonadong  
       2019-05-08 23:43:47 +08:00 via Android
    @ihipop 有支持的轻量在线项目管理工具吗
    ihipop
        3
    ihipop  
       2019-05-09 08:27:17 +08:00 via Android
    @cantonadong 我最早用过 redmine,除了界面丑,该有的都有,甘特图也是标配,能清晰展示任务依赖关系。tower 的类似甘特图的功能是最近一次更新才有的,而且标题都显示不全。就是个残废。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1060 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:23 · PVG 03:23 · LAX 11:23 · JFK 14:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.