很多团队做国际化,第一反应是“把文案翻译出来”。
这件事当然要做,但如果国际化只盯着翻译,最后通常会落入一个循环:

  • 每次改文案都要找研发发版
  • 每个业务模块都塞 locale 分支
  • 每条链路都在做格式化和兜底

短期看都能跑,长期看系统会变成“语言策略污染业务策略”。

我现在更认同一句话:

国际化不仅是语言替换,而是基于 Context 的流量全链路治理。

这里的 Context,不只是 locale,还包括时区、国家策略、合规约束、货币规则、渠道能力等运行时语义。
这些上下文没有被稳定表达,翻译做得再快,也只是在修表层问题。

一、为什么“翻译视角”会失败

我在国际化项目里见过最常见的三个失败模式:

1)数据污染:把展示当事实

数据库直接存 name,业务逻辑也用 name 判断。
多语言上线后马上出现同名冲突、搜索误判、历史数据歧义。

2)契约污染:把文案塞进通信协议

API/RPC/MQ 里透传渲染后的文案,导致语言策略扩散到全链路。
最终是任何一个语言策略变化,都可能触发跨服务联动。

3)性能污染:把本地化计算压在核心链路

格式化时间、币种、数字和语言包协商都在中心服务做。
并发一上来,核心链路被与业务无关的 CPU 开销拖慢。

所以我把国际化看作工程治理问题,而不是“翻译项目”。

二、国际化的目标函数:三件事必须同时成立

我会同时盯这三个目标:

  1. 文案动态下发能力(Hot-update)
  2. 研发侧非侵入式治理(Non-intrusive)
  3. 边缘层性能卸载(Edge Offloading)

这三个目标共同指向一个问题:
如何降低“每次变化都要改代码、发版本”的成本。

1)Hot-update:文案从代码剥离到配置中心

我的做法是把国际化文案从代码仓库剥离,接入 Apollo、Nacos 或自研 I18n 管理台:

  • 研发只定义稳定 key
  • 文案 value 由产品、运营、法务维护
  • 发布链路支持灰度和秒级热更新

业务方改文案不再依赖研发发版,国际化从“排期问题”变成“配置治理问题”。

2)Non-intrusive:国际化是平台能力,不是业务负担

我的原则是让业务天然获得国际化能力,而不是每个模块重复造轮子:

  • 业务代码只依赖 id/key 和结构化字段
  • 渲染逻辑延后到展示层或网关层
  • SDK/中间件负责 context 透传、默认值和降级

3)Edge Offloading:把可卸载计算前移到边缘

在高并发场景下,我倾向把本地化计算前移到 CDN/Edge:

  • Accept-Language 和地理信息做首层路由
  • 静态语言包边缘缓存
  • 时间/数字等轻量格式化在边缘执行

核心系统做正确性,边缘系统做就近适配和加速。

三、三层落地模型:存储标准化、逻辑透传、表现本地化

我会用一条硬规则约束团队:

  • 存储层:做标准化(UTC/ISO)
  • 逻辑层:做 context 透传
  • 表现层:做本地化适配

1)存储层:存事实,不存展示

时间统一存 UTC 或时间戳,结构化字段尽量走 ISO 标准。
数据库只存系统可计算的事实态,不存“给用户看的语言态”。

2)逻辑层:上下文是契约,不是可选参数

locale/timezone/country 要成为请求上下文的一部分,并在 API/RPC/MQ 统一透传。
上下文一旦漂移,后续渲染和策略判断都会错位。

3)表现层:本地化在离用户最近的位置完成

12/24 小时制、货币符号位置、小数点规则、复数语法,这些都属于表现层。
离用户越近,迭代越快,回归面越小。

四、工程落地:我重点抓三件事

1)身份与展示解耦:从 name 驱动改成 id/key 驱动

标签、分组这类对象经常同时包含内置项和用户自定义项。
多语言后容易出现重名冲突、搜索误判、历史语义不一致。

解决方式是:

  • 业务判断统一切到稳定 id/key
  • 对内置项建立 reserved/alias 兼容
  • 把迁移脚本纳入发布计划,避免“逻辑先改、数据后补”的窗口期

2)通信契约去语言化:链路只传语义,不传文案

API/RPC/MQ 只传 id/key 与结构化字段,不透传渲染文案。
展示时按 locale 回查渲染,把语言影响面控制在可治理边界。

3)运行时与交付标准化:先明确边界,再追求效率

时间默认时间戳/UTC,导出统一在出口格式化。
同时明确配置化与数据库化边界:

  • 高频变化、运营可控:配置中心
  • 强事务一致、业务主数据:数据库

边界不清,后面一定反复重构。

五、国际化与国家化:两层模型,不要混在一起

我会强调一个容易被忽略的点:
先把语言、时区、契约底座做稳,再承载国家差异化流程。

以支付为例:

  • 底层统一订单与支付状态机
  • 国家差异通过 provider adapter 和 country policy 注入

这样新增国家主要是“加配置 + 加适配器”,而不是在核心链路散落 if/else

六、真正的护城河:沉淀、门禁、自动化

国际化做到后面,拼的不是个人经验,而是组织治理。
我通常会同步推进三件事:

  1. 国际化 checklist:覆盖需求评审、技术设计、测试验收、发布回滚
  2. 流水线门禁:硬编码扫描、缺失 key 校验、未翻译阻断
  3. 翻译闭环:从 Excel 人肉流转升级为脚本生成与回写

这里我补一个我常用的评审清单(节选):

  1. 业务判断是否完全脱离 name,统一基于 id/key
  2. 接口契约是否去语言化,避免传输渲染文案
  3. 时间是否统一 UTC 存储,导出是否统一在出口格式化
  4. 是否定义 locale 缺失、翻译缺失、配置拉取失败的降级策略
  5. 是否有灰度、回滚、审计日志和变更追踪

把这些做成门禁后,国际化能力才会从“人”迁移到“规范 + 工具链 + 门禁”。

七、我认为同样重要的边界条件

这套方法不是万能的,至少有三个边界要提前说清:

  1. 早期单市场验证阶段
    如果业务还在找 PMF,国际化不该过度设计,先保留最小可扩展点即可。

  2. 强监管场景
    当文案修改涉及法律合规,热更新必须带审批、审计和生效窗口,不能“配置即生效”。

  3. 超低延迟核心交易链路
    即使做 Edge Offloading,也要评估边缘执行引入的复杂度和一致性成本,避免为了优化而优化。

八、建议的落地顺序(避免大爆炸改造)

我一般按三阶段推进:

  1. 第 1 阶段:止血
    先做 id/key 驱动、时间统一和契约去语言化,清理最危险的耦合点。

  2. 第 2 阶段:提效
    接入文案平台与热更新,补齐灰度、回滚、审计能力。

  3. 第 3 阶段:规模化
    引入边缘卸载、国家策略注入和自动化门禁,形成可复制模板。

结语

国际化不是“把中文变成英文”这么简单。
它的工程本质是:在多国家、多语言、多时区并发演进时,系统依然保持一致性、可扩展性与可治理性。

所以我对团队的要求一直很一致:

存储层做标准化,逻辑层做 context 透传,表现层做本地化适配。

先把底座做稳,再谈业务扩张速度。
这不是语言问题,这是系统治理能力问题。