AI要取代我?我选择成为架构师

7 阅读13分钟

晚上8点,报警群炸了。

"接口超时!""服务挂了!""页面打不开!"

打开监控面板,核心数据库CPU飙到100%,所有SQL都在排队。不是服务宕机,是数据库扛不住了。

新活动上线5分钟,大量用户涌入排行榜页面。每次请求都要全表扫描千万级数据——慢查询把数据库CPU占满,所有打到这个库的操作全部超时。

  • 加从库? 来不及。搭建主从、配置同步、改代码读写分离,至少两小时,流量已经打过来了。
  • 重构? 时间不够。SQL优化、索引调整、压测发布,周期太长,线上等不起。
  • 限流? 可以。但活动刚上线就限流,用户体验断裂,转化率直接归零,业务侧不会买单。

最终决策:动态降级。关闭排行榜实时刷新,保留基础参与入口,将慢查询强制熔断。3分钟后,数据库CPU与核心接口RT回落至正常范围,服务恢复。

但这只是止血。

这不是代码Bug,是架构设计缺陷:高消耗查询与核心业务共用了同一个数据库实例

后续改进: 添加缓存层、优化慢查询,并在连接池配置查询超时,超时自动断开,释放连接,防止慢SQL拖垮整个实例。

根本方案: 把非核心业务的高消耗查询拆到独立的数据库实例,与核心业务物理隔离。从此,活动流量峰值不再波及核心链路。

这些决策不在代码里,而在架构层的判断:哪些功能可以牺牲,哪些必须保护;哪些资源可以共享,哪些必须隔离。

AI能帮忙写代码,但它做不了这些判断。


AI能做什么,不能做什么

先承认一个事实:AI写代码比我快。

让它写个排序算法、补全单元测试、生成代码模板——几秒钟搞定。质量还不错,比我手写的规范。

但有些事AI做不了:

理解业务上下文。 某个字段叫balance,是余额还是积分?AI不知道,除非你把整个数据模型、业务规则、历史演进全喂给它。但这些东西往往散落在文档、代码注释、老员工的脑子里——连你自己都不一定说得清。

做取舍决策。 性能优化10%,但会增加复杂度。做不做?AI会给你两个方案,但不会告诉你选哪个——因为它不知道你的团队规模、维护成本承受能力、未来演进方向。

跨系统思考。 你改了一个接口,影响的是上游调用方、下游依赖、监控系统、报警阈值、数据报表……AI看不到这些,它只能看到你给它看的代码。

把握技术演进节奏。 现在引入新技术栈,会不会和半年后的架构规划冲突?这个决策需要时间维度,AI没有。

所以,问题不是"AI会不会取代程序员",而是"AI会让哪种程序员被淘汰"。

答案很明确:只会写代码、不会做架构决策的程序员。


架构师不是title,是思维方式

很多人觉得"架构师"是个职位——干了10年技术,升到架构师,年薪翻倍。

这是误解。

架构师不是职位,是一种能力:在技术、业务、团队、时间四个维度上做权衡,并为决策后果负责的能力

让我用一个真实场景解释。

场景:支付系统的幂等性设计

某社交App的支付模块,用户消费后调用钱包服务扣减余额。最直接的代码:

func Deduct(ctx context.Context, userID int64, amount decimal.Decimal) error {
    _, err := db.ExecContext(ctx, `
        UPDATE wallet_balance 
        SET balance = balance - ? 
        WHERE user_id = ? AND balance >= ?
    `, amount, userID, amount)
    return err
}

这段代码虽然解决了并发问题(原子操作,不会少扣),但面临网络超时重试,用户可能被多扣钱。

AI通常会建议:"加个唯一ID,用数据库唯一索引做幂等。"

但问题是:唯一ID从哪来?存哪里?冲突了怎么告警?

这些决策,AI给不出唯一答案。让我带你推演一线战场的常见方案:

方案A:业务流水号 + Redis分布式锁

func DeductWithLock(ctx context.Context, req *DeductRequest) error {
    // 用业务类型和业务流水号加锁
    lockKey := fmt.Sprintf("deduct_lock:%s:%s", req.BizType, req.BizNo)
    
    ok, err := redis.SetNX(ctx, lockKey, "1", 30*time.Second).Result()
    if err != nil || !ok {
        return errors.New("请勿重复提交")
    }
    defer redis.Del(ctx, lockKey)
    
    // 扣款
    if err := db.DeductBalance(ctx, req.UserID, req.Amount); err != nil {
        return err
    }
    
    return nil
}

问题: Redis挂了怎么办?锁30秒到期了,但业务扣款还在执行怎么办?

方案B:流水表 + 唯一索引幂等

func Deduct(ctx context.Context, req *DeductRequest) error {
    // 创建资金流水(用业务类型+业务流水号建唯一索引,防止重复创建)
    err := db.CreateFlow(ctx, req.BizType, req.BizNo, req.UserID, req.Amount)
    if err != nil {
        if db.IsDuplicateKeyError(err) {
            return nil // 已处理过,幂等返回成功
        }
        return err
    }
    
    // 扣款
    if err := db.DeductBalance(ctx, req.UserID, req.Amount); err != nil {
        return err
    }
    
    return nil
}

问题: 资金流水创建了,扣款失败了,怎么办?

方案C:本地事务保障(单库场景)

func DeductWithTransaction(ctx context.Context, req *DeductRequest) error {
    return db.Transaction(ctx, func(tx *sql.Tx) error {
        // 创建流水
        err := tx.CreateFlow(ctx, req.BizType, req.BizNo, req.UserID, req.Amount)
        if err != nil {
            if tx.IsDuplicateKeyError(err) {
                return nil
            }
            return err
        }
        
        // 扣款
        if err := tx.DeductBalance(ctx, req.UserID, req.Amount); err != nil {
            return err
        }
        
        return nil
    })
}

此方案成立的前提是 资金流水表 与 钱包余额表 位于同一个数据库实例。若已拆分至不同库,需升级为本地消息表+MQ最终一致性方案,这在专栏后续文章会详细展开。

问题: 事务持有数据库连接时间长,高并发下可能成为瓶颈。

最终选了方案C。 理由如下:

  • 业务约束:重复扣款用户会投诉,扣款失败财务对不上账,一致性要求极高。方案B无事务,可能有流水但未实际扣款,不满足要求。扣款接口QPS不高,事务持有连接的时间可控,瓶颈风险可以接受。
  • 技术约束:事务保证原子性,数据一致性好。Redis方案多了一个故障点。
  • 团队约束:团队对数据库事务有实战经验,对ACID语义理解到位。Redis分布式锁的边界情况(进程崩溃、时钟漂移)反而更容易踩坑,运维成本更高。

这个判断,AI做不了。 因为它不知道我们的基础设施架构(主从分离)、团队能力栈(数据库强、Redis运维弱)、以及业务对一致性的容忍度(零容忍)。

架构师的价值就在这里:把技术约束、业务目标、团队能力放在一起,做出一个当前最优的选择。


成为架构师的三个关键能力

1. 看清系统全貌

不是看一个服务,是看整个系统。

下面是某社交APP用户在聊天室内发一条消息的调用链路:

graph TD
  Client[用户端: 发送消息请求] --> C1

  subgraph SG_Core [核心业务层: ChatRoom 服务]
    C1[消息组装与基础校验]
    C2[调用关系服务: 获取粉丝/好友列表]
    C3[调用礼物服务: 暴击概率计算]
    C4[调用音视频服务: 连麦状态同步]
    C5[......]
    C6[调用 IM 服务: 触发下发流程]
  end

  C1 --> C2 --> C3 --> C4 --> C5 --> C6

  subgraph SG_Push [消息推送层: IM 网关与路由分发]
    G1[消息网关: 风控审核 & 敏感词过滤]
    G2[内容安全: AI 模型识别 & 权限校验]
    G3[审核通过: 写入消息队列]
    MQ[(Kafka / RocketMQ 消息队列)]
    
    R1[消息消费: 按类型路由分发]
    R2[单播推送: 按用户 ID 路由至对应节点]
    R3[广播推送: 全量下发 / 支持平台/版本/VIP 过滤]
    R4[优先级队列: 高优系统通知插队处理]
    
    P1[长连接网关: WebSocket 实时推送]
    P2[离线兜底: APNs / FCM 系统级推送]
  end

  C6 --> G1 --> G2 --> G3 --> MQ --> R1
  R1 --> R2
  R1 --> R3
  R1 --> R4
  R2 --> P1
  R3 --> P1
  R4 --> P1
  P1 --> P2

  subgraph SG_Async [异步处理层: 数据闭环与业务衍生]
    A1[消息队列异步消费]
    A2[更新推荐系统用户特征]
    A3[触发广告归因回调]
    A4[实时数仓同步]
  end

  C6 -. 异步埋点触发 .-> A1
  A1 --> A2
  A1 --> A3
  A1 --> A4

  classDef user fill:#f8fafc,stroke:#64748b,stroke-width:2px,rx:6px;
  classDef core fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,rx:6px;
  classDef push fill:#f5f3ff,stroke:#8b5cf6,stroke-width:2px,rx:6px;
  classDef async fill:#f0fdf4,stroke:#22c55e,stroke-width:2px,rx:6px;

  class Client user;
  class C1,C2,C3,C4,C5,C6 core;
  class G1,G2,G3,MQ,R1,R2,R3,R4,P1,P2 push;
  class A1,A2,A3,A4 async;

这个图不是文档里写的,是从代码、日志、监控、事故复盘里一点点拼出来的。

怎么练这个能力?

  • 第一周:选一个核心服务,画出它3层以内的上下游依赖。来源:代码里的HTTP/gRPC调用、消息队列订阅关系、数据库表的主外键。
  • 第二周:选一个完整功能(比如"用户充值"),从入口到底层存储,画出完整调用链路。标出每个环节的超时时间、失败处理、数据一致性级别。
  • 验证指标:你能不查代码,向同事描述这个服务的上下游依赖关系,且对方没有异议。

2. 理解业务逻辑

技术是为业务服务的。不理解业务,技术决策就是瞎猜。

产品说做一个"开宝箱"功能。技术上看,逻辑很简单:

func OpenBox(ctx context.Context, userID int64) (*BoxReward, error) {
    // 扣宝箱钥匙
    if err := db.DeductKey(ctx, userID, 1); err != nil {
        return nil, err
    }
    // 随机出奖
    reward := RandomReward()
    // 发奖
    return reward, SendReward(ctx, userID, reward)
}

三行逻辑,上线就行了吧?

但业务上,这个"随机"背后全是坑:

  • 运营说1%出稀有奖。1%是每箱独立计算,还是累计100箱保底?保底要不要做重置周期?概率引擎不是rand() < 0.01这么简单。
  • 用户充值买了钥匙,开箱得奖后送人。然后申请退款——奖品已经流转出去了,退不退?退的话钱从哪出?
  • 活动最后一分钟,10万用户扎堆开箱。并发高的时候出奖率会不会异常?要不要加锁?失败要不要排队重试?
  • 上线后运营问:这周稀有奖的实际出奖率是多少?你能回答吗?理论概率1%,但实际出了多少、哪些用户拿到了、有没有异常集中——没有监控就是黑盒,出了问题也说不清楚。
  • 运营每周改奖池和概率。热更新时正在开箱的用户怎么处理?加不加版本控制?需不需要灰度?用户拿旧配置的截图来投诉"我开箱的时候明明是这个概率",你怎么排查?

这些问题,AI不会问你。但如果你不想清楚,上线后一定会出事。

怎么练这个能力?

写完代码后问自己5个问题:

  1. 业务规则边界:概率是独立还是保底?有没有每日/全服限量?限量是硬限制还是软限制?
  2. 异常和回滚:扣了钥匙但出奖失败怎么办?充值买的宝箱退款时奖品怎么回收?事务边界在哪?
  3. 高并发边界:活动结束前扎堆开箱,要不要加锁?失败了要不要排队重试?
  4. 可观测性:实际出奖率是多少?有没有异常集中?出了问题能不能说清楚当时发生了什么?
  5. 配置变更追溯:运营改了概率,用户拿旧配置截图来投诉,你能不能证明当时用的是哪套配置?

对照产品文档或找产品经理对一遍。你会发现你漏了多少东西。

3. 掌控技术演进节奏

不是追新技术,是在合适的时间引入合适的技术。

关键是:什么时候是"合适的时间"?

某社交App早期用PHP。团队3个人,DAU不到10万。PHP开发快,部署简单,够用。

后来DAU涨到50万。高峰期PHP-FPM进程数打满,请求排队,响应时间从200ms飙到2秒。

这时候该不该切Go?

3个月前不切——DAU只有30万,PHP还能扛,切Go要占用2个核心开发,业务迭代会停。

3个月后再切——DAU可能到80万,那时候不是"切不切"的问题,是"系统能不能活"的问题。

现在切,是因为业务压力已经到了临界点,团队规模也刚够支撑两条线(业务迭代+重构)。

早做,浪费资源。晚做,风险失控。

最终用的方案:绞杀者模式——不是一次性重写,而是按接口逐步迁移。

# Nginx配置:按路径切流量
location /api/v1/chat/ {
    proxy_pass http://go-service;  # 新服务
}
location /api/v1/ {
    proxy_pass http://php-service; # 旧服务兜底
}

流程:Go实现新接口 → Nginx切10%流量 → 观察1周(错误率/RT) → 稳定切50% → 继续切 → PHP下线。

一年半后,PHP服务全部下线。整个过程用户无感知。

这个方案不是从书上抄的,是根据**团队规模(6人,能分出2人做重构)、业务压力(DAU 50万,PHP快扛不住)、风险承受能力(零容忍数据丢失,不能一次性切)**做出来的。

节奏感,就是知道什么时候必须动手,什么时候可以再等等。

怎么练这个能力?

现在去做一件事:观察你系统里的技术债务,列一个优先级清单:

1. [P0] 某服务单点 → 3个月内必须解决(流量预计涨50%,单点扛不住)
2. [P1] 某表没有索引 → 等DAU破X万再优化(现在量还小)
3. [P2] 日志没结构化 → 有空就做(不影响主流程)

每一条后面写上**判断依据:**为什么是P0?为什么是现在?

三个月后回看:P0解决了吗?当时判断的流量涨50%对不对?你的依据准不准?

这个复盘,才是真正积累节奏感的方式。


AI是验证者,架构师是决策者

先想清楚,再让AI干活。 这句话听起来是废话。但实际操作中,90%的人用AI的顺序是反的:拿到需求,先让AI写代码,边写边改,边改边问——最后代码写了一堆,架构一塌糊涂。

AI在架构阶段的价值是逼问假设,不是生成代码。

怎么用AI逼问自己?

有一个固定句式:"这个方案,在XXX情况下会怎样?"

我:支付幂等方案(事务+唯一索引),在极端情况下会怎样?

AI:
- 数据库主从延迟时,从库查不到刚创建的订单,可能重复扣款
- 事务超时没返回,客户端重试,会报"订单已存在"但不知道扣没扣钱
...

虽然它说的不一定对,但能帮忙发现一些没考虑到的边界情况。

AI最大的价值:把你脑子里的假设逼问出来。

你以为自己考虑了并发,AI问你"主从延迟呢"。

你以为自己考虑了幂等,AI问你"事务超时没返回呢"。

每一个追问,都是架构决策的深度。AI不会替你做判断,但它能帮你把判断的依据逼出来。


核心要点

  1. AI会取代只会写代码的程序员,不会取代能做架构决策的程序员。

  2. 架构师不是title,是思维方式:在技术、业务、团队、时间四个维度做权衡,并为结果负责。

  3. 三个关键能力:

    • 看清系统全貌(画调用链路图,第一周一个服务,第二周一条链路)
    • 理解业务逻辑(写5个业务约束条件,对照产品文档验证)
    • 掌控技术演进节奏(列技术债务优先级清单,三个月后复盘判断对不对)
  4. AI是验证者,架构师是决策者。 用AI逼自己把假设说清楚,用AI发现设计漏洞,但最终判断永远是你自己做。


写在最后

我见过很多程序员,技术很强,但只会执行需求。产品说什么做什么,从不问"为什么"。

也见过一些程序员,技术一般,但能看清系统全貌,吃透业务逻辑,在关键时刻做正确决策。

后者,才是AI时代不可替代的人。

从今天开始,别只盯着代码。跟着我一起,抬起头,看看整个系统。那才是你的战场。


📖 下篇预告:《这个需求该怎么实现?》

我们会聊:从一个模糊的业务需求,如何推导出清晰的实现路径。不是讲道理,是给模板。读完你就能照着做。