首页
学习
活动
专区
圈层
工具
发布

必须裁掉一个,你觉得该干掉哪个?

公司做组织调整的时候,群里有人讨论“必须裁掉一个,你觉得该干掉哪个”。有人开玩笑说:“保洁吧,让这些当官的轮流干。”

这句话听起来是在吐槽岗位价值,但我在项目里遇到过类似问题:系统出现故障,团队第一反应也是“砍掉一个环节”。后来才发现,很多看似可以砍掉的东西,其实承担的是没人关注的稳定性职责。真正危险的是,某个能力长期没有进入系统设计,只靠某个人或者某个流程撑着。

有一次接手一个订单系统,线上经常出现订单状态异常。业务同学认为问题出在运营审核流程,开发同学认为是数据库慢,最后排查发现,真正的问题是订单状态流转完全依赖一个后台人员的操作经验。

当时的代码很简单。

public void updateOrderStatus(Long orderId, String status) {

  Order order = orderMapper.findById(orderId);

  order.setStatus(status);

  orderMapper.update(order);

}

这个方法上线初期没有问题,因为订单量小,操作人员知道哪些状态可以修改。

比如待支付订单可以改成已取消,支付成功订单可以改成退款中,人工处理异常订单时也能直接修正。

但是业务增长以后,问题开始暴露。

一个新员工接手后台,不知道订单状态之间的限制;一个运营同学为了处理投诉,直接把订单改成完成;一次批量修复数据时,把几十个退款中的订单改回了支付成功。

代码没有报错,数据库也没有异常,但是业务数据已经错了。

这里其实有个坑。

很多系统刚开始设计时,会把业务规则放在人脑里。

开发认为:“这个流程大家都知道。”

运营认为:“以前都是这么操作的。”

测试认为:“正常流程没问题。”

但是几年以后,人员变化、业务增加,原来的隐性规则就会变成线上风险。

后来我们重新梳理订单状态,把修改入口收紧。

订单状态不能由外部直接传字符串,而是通过业务动作驱动。

public void cancelOrder(Long orderId, String operator) {

  Order order = orderMapper.selectForUpdate(orderId);

  if (!OrderStatus.PAYING.equals(order.getStatus())) {

      throw new BusinessException("当前状态不能取消订单");

  }

  order.changeStatus(OrderStatus.CANCELED);

  orderLogMapper.insert(

      new OrderLog(

          orderId,

          "CANCEL",

          operator

      )

  );

  orderMapper.update(order);

}

这里改动最大的地方,不是加了一个判断。

而是把“谁都可以改状态”变成“只有符合业务规则的动作才能改变状态”。

数据库里的状态字段还是存在,但它不再代表全部逻辑,只是业务结果。

后面又遇到一个问题。

有些订单需要自动关闭。

以前运营每天定时筛选超时订单,然后手动处理。订单少的时候没有问题,但是一天几十万订单以后,人工处理已经无法保证准确。

当时有人提出直接删掉人工流程,全部改自动化。

这个方案听起来很彻底,但线上系统很少一步到位。

因为人工流程背后通常还有异常处理能力。

比如支付渠道延迟,订单已经支付但是支付通知晚到了;比如库存服务异常,订单关闭时库存没有释放。

所以我们没有简单删除人工入口,而是增加了自动处理和人工补偿两个路径。

public void closeTimeoutOrder() {

  List<Order> orders = orderMapper.queryTimeoutOrders();

  for (Order order : orders) {

      try {

          transactionTemplate.execute(status -> {

              order.changeStatus(OrderStatus.CLOSED);

              orderMapper.update(order);

              stockService.release(order.getId());

              return true;

          });

      } catch (Exception e) {

          retryTask.save(order.getId(), e.getMessage());

      }

  }

}

自动任务负责处理大部分正常情况,人工只处理异常情况。

这样做以后,运营人员不需要每天检查几万条订单,但是系统也没有失去人工干预能力。

很多团队在做优化时,喜欢问:“这个岗位能不能不要?”

技术团队更应该问:“这个能力有没有进入系统?”

如果一个线上服务只能靠某个开发记住部署顺序,如果一个订单流程只能靠某个运营知道规则,如果一个数据库修复只能靠某个人执行脚本,那说明系统还没有真正承载业务。

后来我们又增加了状态机校验、操作日志和异常补偿。

public boolean changeStatus(Order order, OrderStatus target) {

  Set<OrderStatus> allow =

      statusRule.get(order.getStatus());

  if (!allow.contains(target)) {

      return false;

  }

  order.setStatus(target);

  return true;

}

这段代码解决的是另一个问题:规则集中管理。

以前每个地方都可能修改订单状态,新增一种状态需要搜索整个项目。

现在状态变化关系集中维护,代码Review时也更容易发现问题。

很多线上事故不是因为系统没有人维护,而是系统把关键能力放在了人的经验里。

人员减少以后,暴露出来的不是岗位数量问题,而是软件设计问题。

真正需要被优化的,往往不是某个人,而是那些没有进入代码、没有自动化保障、没有留下约束的业务规则。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ONF58BO3yoAaTQVPMRb4r3HA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券