两个设计教训

在错误中能够学到更多。

有两个设计教训,分享下。

IP 封禁

多主机多IP 网络封禁。原型图如下:执行封禁操作之后,会生成若干条响应记录和对应操作历史记录。

已有的元素响应(进程、文件、容器、主机),都一个主机一个元素一条响应记录。我最开始理解成,每个主机每个(拆分后的)IP(如果是 CIDR 或 IP段,则拆分成多个IP)一条响应记录。没有与产品同学确认。刷刷刷,很快实现了。产品走查时,发现这样不合理,因为一个 IP段或CIDR 会拆分出很多响应记录,如果有万台主机,则响应记录是 len(IPs) * 主机数。很可能一次全部主机的封禁操作是百万级记录。

于是与产品当时讨论了两种方案:

  • 每个主机每行(可能是一个IP,CIDR,IP端)一条响应记录。还是需要拆分,不过拆分数量少了些。
  • 每个主机所有IP一条响应记录。最简单,但有一个缺点,如果用户想要单独解封其中一个IP,则只能全部解封,再单独封禁一条。
    当时因为走查是提测当天,且第二种方案不能支持针对其中单个IP单独解封,而第一种方案与现有实现比较相近,容易实现,因此,选择了第一种方案。
    结果测试同学测试后,发现IP解封非常麻烦。 最后讨论后,将这个feature打回了。几经讨论后,内部达成一致,没有必要做那么复杂,就每个主机所有 IP 一个响应记录。

回顾这个例子,我能学到什么呢?

  • 为什么当时会理解成拆分后的每个主机每个IP一条记录?之前刚做过告警里IP网络封禁,就是一个IP一个主机一条记录。囿于开发人员实现思维,且这样做解封操作就不用写新的代码。
  • 为什么讨论后,不选择第二种方案?时间紧,改动较大,影响提测;第二种方案不能单独解封,从产品体验上不太容易接受(只能先全部解封再单独封禁,体验差一点)。
  • 如果时间考量影响技术方案,那么技术方案很可能会出问题,后续还得重新搞一遍。得不偿失。时间较为充足的情况下,技术方案最好重点考虑产品设计和技术实现。
  • 如果只考虑技术实现,不考虑产品设计,即使技术实现看上去没问题,也得返工。
  • 对于方案存在小的缺点,要深入讨论,是否一定不可接受。方案一定要综合权衡,不要局限于一两个优缺点。
  • 如果有对偶操作,一定要考虑对偶操作是否存在问题。
  • 产品设计评审时,要多从产品角度去思考如何做更合理,避免过早代入开发思维。

入侵看板

入侵看板是关于告警的一系列统计图表。之前入侵看板测试反映性能较慢,讨论了用统计方法的可能性。因此,一开始就打算用统计方法来做入侵看板,没有去思考其它放方案可能性。具体而言,就是先基于原始表及统计指标用定时任务统计到一张中间统计表上,然后再基于统计表做各种图表。这样,统计表的数据条数很少,性能问题就能解决。

不过实际做起来,发现统计方法其实有很多问题:

  • 权限控制很难搞。有主机、集群、业务组、namespace 权限维度。意味着每个维度每个指标都需要统计。
  • 变更处理较多。尤其是告警状态,有很多变更场景。告警打标、元素响应、修复验证、加白、事件处理等。每个变更场景针对多个权限维度都需要更新,更新逻辑复杂。
  • 排查问题很难。由于每个数据是一个整体,如果出错了,很难推断出是哪里出错了,而且一次错持续错,几乎没有补救办法。
  • 代码侵入性强。每个变更处理都需要在相应代码里嵌入一段统计变更代码,影响现有流程,容易出问题。
  • 技术框架局限性。 目前公司技术栈主要限于 mongo, redis,部署大多是单台独立部署,要引入新的大数据平台和组件,在部署上都是较大的成本。很难仅仅为了看板功能引入新技术新组件来增大部署成本。

仅仅只是为了一个性能目标,要冒这么多技术风险,实在是不划算。后来,我想了下,统计方法适合什么场景呢?

  • 变更少的场景。比如订单、商品、金额等,这些一旦确定几乎就不会变化了。统计方法明显不适合于业务变更比较多的场景。
  • 局部优化场景。如果某个指标非常重要且实在太慢,可以针对这个指标单独用统计方法优化。范围小可控。

这个例子中,犯了什么错误?

  • 先入为主。以为 A 方案在 X 方面不好, Y 方案在 X 方面可能有更好表现,就选择 Y 方案,并不仔细考虑 Y 方案的诸多弊端。这也是一个技术方案综合权衡的问题。方案考量切不可只局限在少量点上。
  • 没有考虑其它方案可能性。当只有一种方案可选时,注定要承受这个方案的所有缺点。如果这些缺点有一个是致命的,那么这个方案就是不合理的。

产品设计和技术方案要严格把关

即使是经验丰富的开发者,犯错也是很难避免的。只是可以避免大多数错误,但仍然避免不了犯错。

在研发流程中,产品设计评审和技术方案评审环节一定要严格把关。产品设计不当,严重的就是返工,用另一种设计再做一遍,耗时耗力; 技术方案不当,严重的是按另一种设计方案重新再做一遍,耗时耗力。

产品设计上,就专注思考产品设计上的合理性,避免过早代入开发思维(除非产品设计可能会导致较大的性能或资源开销问题)。反复与产品同学确认自己的理解不存在偏差。技术方案上,多考虑几种方案,列出所有利弊,综合权衡,多审查几遍,请人帮忙一起把关。

不可不察之。

技术方案避坑

  • 存储设计:表设计维度正确,外键或内嵌关联合理。避免将量级大的字段放在量级小的维度的表里。比如将告警ID放在文件上传任务表里。
  • 质量属性:提前考虑性能和稳定性。审查是否存在大数据量或耗时大的操作,用索引、并发、异步、缓存、预处理等方式来处理。
  • 业务逻辑:考虑变更处理和关联处理。如果不同功能之前存在冲突( 比如归并与响应),则需要站在更高的层面思考两者的处理,而不是遇到一个问题解一个(很可能会解决一个问题同时引入另一个问题,直到改不动为止)。
  • 扩展性:适当考虑扩展但不过度。不要想着一开始就设计很多特性,很可能跟业务场景不匹配而用不上。扩展性是为业务而服务的。
  • 可维护性:考虑代码侵入性(改动散布)。如果要在很多地方做相似的改动,考虑切面等。
  • 数据:有大量数据分布在服务器上,要考虑数据分布均衡。
  • 交互:不要让前端或外部直接依赖内部字段结构。因为如果有一天需要修改字段的话,可能就改不动了。

posted @ 2024-12-07 10:08  琴水玉  阅读(19)  评论(0编辑  收藏  举报