3. 服务架构基础

从单体信号处理系统迁移到服务化架构,第一步不是拆代码,而是建立一套共同的语言和结构判断标准。微服务、领域驱动设计、API 网关、服务发现、配置中心这五个概念,分别回答了“怎么拆”“按什么拆”“入口怎么管”“服务怎么找到彼此”“参数怎么统一治理”五个问题。它们不是并列的工具清单,而是一条从业务边界到运行时的完整链路。

核心判断:服务架构的起点是业务边界,而不是技术组件。先有领域边界,才有服务边界;先有服务边界,才谈得上网关、发现和配置。

一、核心原理:五个概念在同一条链路上

微服务是一种将系统按业务能力拆分为独立部署单元的架构风格。每个服务拥有自己的数据、生命周期和发布节奏,服务之间通过明确定义的接口通信。它的价值不在于“小”,而在于边界清晰、独立演进、故障隔离。

领域驱动设计(DDD)提供了划分边界的思维工具。核心是限界上下文(Bounded Context):同一个词在不同业务语境中含义不同,就应划入不同上下文。例如“信号”在采集上下文里是原始采样序列,在分析上下文里是特征向量,在告警上下文里是触发条件。限界上下文之间通过上下文映射定义协作关系,如防腐层、共享内核、客户方-供应方。

API 网关是系统的统一入口,承担路由转发、鉴权、限流、协议转换、灰度发布等横切职责。它让外部调用方只面对一个地址,内部服务可以自由调整。

服务发现解决“服务实例地址动态变化”的问题。服务启动时向注册中心登记,调用方通过服务名而非 IP 获取可用实例列表,配合健康检查自动剔除故障节点。

配置中心把散落在各服务中的参数集中管理,支持按环境、按服务、按版本下发,并能在运行时动态刷新。对于信号处理系统,采样率、滤波窗口、阈值、模型版本等参数尤其需要统一治理。

服务架构基础:从业务边界到运行时治理 领域驱动设计 DDD 限界上下文 / 上下文映射 聚合根 / 领域事件 回答:按什么边界拆 微服务 独立部署 / 独立数据 接口契约 / 故障隔离 回答:怎么拆与怎么连 API 网关 路由 / 鉴权 / 限流 协议转换 / 灰度 回答:入口怎么统一管 服务发现 注册中心 / 健康检查 服务名寻址 / 负载均衡 回答:服务怎么找到彼此 配置中心 环境隔离 / 版本管理 动态刷新 / 灰度下发 回答:参数怎么统一治理 运行时协作链路 调用方 → API 网关(鉴权/路由)→ 服务发现(取实例)→ 目标微服务 → 配置中心(取参数) DDD 决定服务边界,微服务承载边界,网关、发现、配置保障运行时稳定

二、方法流程:从领域建模到服务落地

落地路径可以按以下步骤推进,每一步都有明确的产出物:

  1. 事件风暴与领域梳理:与业务方一起列出关键业务事件、命令和聚合,识别出候选限界上下文。
  2. 绘制上下文映射:明确上下文之间的上下游关系,确定哪些通过 API 同步调用,哪些通过消息异步解耦。
  3. 定义服务边界与契约:每个限界上下文对应一个或一组微服务,先写接口契约(OpenAPI/Proto),再写实现。
  4. 接入网关与注册中心:服务启动即注册,网关按路由规则暴露统一入口,横切能力下沉到网关。
  5. 参数外置到配置中心:把环境相关、易变的参数从代码中剥离,建立配置命名规范和审批流程。

以信号处理平台为例,可拆分为采集服务、预处理服务、特征分析服务、告警服务、设备管理服务。采集服务只负责接入与原始数据落盘;预处理服务订阅采集事件并做滤波、降采样;特征分析服务消费预处理结果并输出特征向量;告警服务根据特征和阈值规则产生告警。每个服务独立部署,通过消息总线或 REST 接口协作。

三、关键配置与代码示例

服务注册与配置拉取的典型配置如下,服务名、注册中心地址、配置分组是三个必须明确的参数:

# application.yml
spring:
  application:
    name: signal-preprocess-service
  cloud:
    nacos:
      discovery:
        server-addr: nacos.infra:8848
        namespace: signal-platform-prod
      config:
        server-addr: nacos.infra:8848
        group: SIGNAL_PROCESS
        file-extension: yaml
        refresh-enabled: true

# 业务参数从配置中心下发
signal:
  sample-rate: 2000
  filter:
    type: butterworth
    order: 4
    low-cut: 0.5
    high-cut: 450
  window-size: 1024

网关路由配置示例,把外部路径映射到内部服务名,而不是具体 IP:

routes:
  - id: preprocess-route
    uri: lb://signal-preprocess-service
    predicates:
      - Path=/api/preprocess/**
    filters:
      - StripPrefix=2
      - name: RequestRateLimiter
        args:
          redis-rate-limiter.replenishRate: 100
          redis-rate-limiter.burstCapacity: 200

四、核心概念对照清单

概念 解决的问题 关键机制 信号平台中的体现
微服务 独立部署与演进 服务自治、接口契约、数据隔离 采集、预处理、分析、告警各自独立发布
领域驱动设计 边界划分依据 限界上下文、聚合根、上下文映射 “信号”在不同上下文含义不同,分属不同服务
API 网关 统一入口与横切治理 路由、鉴权、限流、灰度 外部系统只访问网关,不直连内部服务
服务发现 实例地址动态变化 注册、健康检查、服务名寻址 预处理服务扩容后调用方无需改配置
配置中心 参数分散与动态调整 集中管理、环境隔离、动态刷新 采样率、滤波参数、告警阈值统一下发

五、常见误区与复盘

误区一:先拆服务再找边界。结果是把单体拆成一堆分布式单体,服务之间强耦合,改一个参数要发多个服务。正确顺序是先做领域建模,再决定服务粒度。
误区二:网关做成“万能层”。把业务逻辑、数据聚合、复杂编排都塞进网关,导致网关成为新的单点和瓶颈。网关只应承担横切关注点,业务逻辑留在服务内。
复盘要点:服务发现和配置中心必须高可用,它们是运行时基础设施。注册中心宕机时,已缓存的实例列表应能继续支撑一段时间;配置中心不可用时,服务应能使用本地兜底配置启动,而不是直接崩溃。

另一个常见问题是配置中心被当成“什么都往里放”的仓库。数据库密码、密钥等敏感信息应使用加密配置或专用密钥管理,而不是明文放在配置中心。同时,配置变更要有版本记录和回滚能力,避免一次误改导致全平台参数异常。

从信号到服务架构的迁移,本质是把“一个进程内的函数调用”转化为“有边界、有契约、可治理的服务协作”。DDD 提供边界判断,微服务提供落地形态,网关、服务发现、配置中心提供运行时保障。四者缺一不可,但优先级明确:先边界,后拆分,再治理。