关于作者:
杨洪志知乎首页架构负责人,主要负责工程建设、工程架构优化、性能提升等工作。
1. 背景
我们旧的主页系统是集中式设计:全方位的feedbase加上main功能。 基本上所有的功能都是耦合的。 每条维护线都必须格外小心,以免影响其他逻辑。 在这里,我们先给大家介绍一下大致的背景:
该系统有 6 个60000行**,首页逻辑习的学习成本至少3个月;
添加新的 Feed 类型需要 7 个工作日;
展开选项卡的工作量约为 3 周;
没有完美的链接跟踪,在线错误就不可能启动;
目前服务端响应高达870ms;
部分逻辑未维护;
二、我们应该怎么做
实际上,这个想法非常清楚解耦模块以优化性能。
但是如何解耦,解耦什么,如何优化性能呢? j**a/go/c……重写?
2024年2月,为了支持兄弟团队的业务,我们几乎所有的工程师都出口到了首页。 事实上,主页上只有三名工程师和一名习。 最资深的员工才入职6个月,其余基本都是新员工,平均2人6个月,无大型项目维护经验。 换句话说,都是新来者。
在这种状况下,我们该如何重建呢?
每个人都知道重构是一件大事,每个人都很积极,每个人都想做一些好事。 但之前大家都是做普通业务的,PM开发的背景色太多了。 看来快速完成功能和快速启动比什么都重要,似乎只有这样才能显示你的可靠性。
在这种情况下,轻率地启动重构或重写的后果是难以想象的。 这就像在100米比赛中使一群运动员失明,并要求他们跑马拉松。 他们很有激情,技术过硬,但不知道跑到哪里去,更重要的是,他们的技术不一定适合长跑。
我们应该:指明方向:让每个人都知道我们想做什么,为什么要做;
确定标准:重构不是一种表演,它不是一个华而不实的系统。 要为工程、合作、商务寻求最合适的设计;
确定方法:让每个人的能力都有针对性;
持续推广:鼓励主动设计和试错; 收紧大门,让大家熟悉和成长。
三、我们做了什么
1、指明方向,引导思考。
为什么要重构? 大家只是肤浅的理解,**吧! 但是为什么? 为什么会改变? “矬”体现在**? 新架构不是一样的吗?
其实现在的“真”并不是因为前辈能力差,而是因为前者的**已经不适合现在的经营场景了。 架构没有好坏之分,只有合适的架构。 我们要做的不是一个完美的系统,所以我们不能炫耀自己的技能,而应该尽力适应当前的业务场景。
我们的目标是使主页更易于使用,并使我们的新架构更慢。
然后,也引导大家思考为什么要在某个地方做打磨,为什么要注意某个细节,为什么要放弃某个功能。 这不是浪费时间,快速输出只是一个及格的加分项,对作者友好的系统绝对是垃圾。
此外,这些标准以可见的结果为指导,以达成共识。 例如,重构后的 ActionCard 模块配置管理清晰,标准自动点,扩展成本极低。 通过一个好的结果,引导大家思考自己为什么要这样做,要做什么,以及如何用自己负责的事情来实现这些指标。
da
单击(最多 18 个字)。
2、确定方法:模块分工。
为什么不面向界面?
面向接口的开发是目前最成熟的开发模式,双方定义接口,并行实现,然后共同调试。 高效部署、出色的解耦、更方便的 bug 定位......
谁定义接口?
新手根本不了解业务逻辑。 脱离实际业务,所有定义的接口都是华而不实的错误。 同时,不可能等到大家都熟悉业务后才开始重构。 即使我熟悉业务,我也没有信心为所有模块定义完美的界面。 比如过滤逻辑,基础计算单元将近100个,里面还有各种性能优化小窍门,怎么处理易于学习和习易于维护易于排除故障,大家只是有一个初步的认知轮廓。 至于兼容性到性能的优化策略,实现是什么样的? 您一次只能迈出一步。
谁实现接口? 如果只是声明,但没有实现,调用方将永远被阻塞,被转移方的逻辑永远不会有真正的流量困难。 脱离验证,贸然上线,所有接口一起上线,如果任何接口出现问题,大家一起回滚:人力互相锁定。
面向模块的开发是如何工作的?
比如重构滤波模块的人,只考虑如何做滤波模块,而不关心其他逻辑。
如果涉及与其他模块的交互:
a.其他模块调用此模块:重构此模块并轻松更改调用者的调用逻辑。
b.该模块调用其他模块:保留原始的 API 调用方法,并尝试尽可能少地进行更改。 (待被调用方准备就绪后,修改接口层,规则与a相同)。
注意:如果调用方和被调用方都没准备好,可以添加一个临时适配层来传输原有的逻辑。
例如,新版本的 FeedItem 具有与旧版本不同的序列化格式; 但是,会话模块不支持协议升级。 使用新版适配层协议适配旧版本,保证会话正常运行,同时可以利用在线流量验证新模块的功能。 会话支持协议升级后,会话维护者将离线进行适配**。
3.小步跑。
面向模块的开发,每个人都负责一个独立的功能,只能专注于这个功能。 其他模块的维护者不会触及模块的任何部分,我们可以在学习习中尽可能多,尽可能小地进行更改:即使某个发布只是一个黑客,即使某个发布只是在临时适配层上。
过滤模块的第一步是简单粗暴地去除计算环节中的 if else 等 hacks,提取基本运算符,然后将它们组合起来。 风险基本为零,成本相当低(不依赖太多的滤清器知识),但收益很大(滤清器的细节懂了,老逻辑理清了)。
明确价值,统一意志
为什么要重构,怎么能让它变慢?
一个好的系统应该是以维护者为导向的,用户友好的,并且具有较低的学习习成本和较低的调试成本。
如果成本降低了,多想想是否可以更低。 在我们的人力和能力范围内,我们提供最简单的东西,而不是作者自在地写作,也不是为了立即上线。 例如,为了方便使用某个功能,进行了几层继承。 作者写得很冷静,但阅读成本却不可预测。 然后,当有人心烦意乱时,重写它......试着想一想,这种架构不是设计得很灵活吗?
这就是为什么我们必须反复引导大家思考我们为什么要重构,以及哪些指标可以证明我们的重构是成功的。 这些指标是首页的核心竞争力,也是个人的核心竞争力。 磨练这些指标不是浪费时间,而是我们与主页一起走向卓越。
不断激励并指出错误
由于对业务不熟悉,缺乏重构经验。 我们经常遇到各种各样的问题,提出很多问题。 比如:我觉得这个设计不错,我觉得这样写也没关系,应该不是浪费时间,而且更有可能是很难上手。 场景很多,如果发现不对劲,应该尽快制止。
作为负责人,接受试错,但要把握试错的方向。 同时,我们要尊重别人的劳动成果,不能一枪打死他们,觉得说到做到。
避免走弯路的基础是意志的统一。 当你看到好的设计时,你应该借此机会加强你的意识,分析它们为什么好,这足以促进某些指标; 对于设计不当的思维,需要指出可能的风险点。
第四,我们做了什么
由于人力有限(考虑到一些产品迭代),重构(耗时 25月,只完成了一期工作,但成果并不低:
延长进料由7d减少到2d(预计二期完成后减少到1d);
将新选项卡从 2W 扩展到 3D;
支持新的促销时段从 1d 减少到 1h;
拉架构的习成本从3W降低到3-5D;
它支持召回的实时反馈;
支持拉取日志实时全链路追踪,快速定位Bug。
通用卡上线,新源类型客户端初次发布,无需发送版本;
接入新版AB平台(含运行时)功能,实现在线实验的动态分析。
无论什么背景,我们都要把首页做成铁军,对首页负责,让工程架构更优化,工程师更强!