什么是 Service Mesh

想象微服务之间的调用是寄快递:你的服务只管寄件(发请求)和收件(收响应),找地址、保证送达、丢件重发这些事全交给 Service Mesh 处理。

30 秒理解:Service Mesh 给每个服务配一个 Sidecar 代理(通常是 Envoy),代理透明拦截所有网络流量,自动处理服务发现、负载均衡、重试、加密、监控等基础设施能力,让你的业务代码只专注业务逻辑。

Sidecar 是什么:就是在你的应用容器旁边再跑一个代理容器,两个容器共享网络。所有进出你应用的流量都先经过 Sidecar,由它来处理网络复杂性。

前置要求:Service Mesh 通常运行在 Kubernetes 上,如果不了解 K8s,建议先看 k8s-intro

没有 Service Mesh 的痛点

即使有 K8s Service 解决了服务发现,你的代码还是要处理很多”网络治理”逻辑:

@Controller('order')
export class OrderController {
  @Post()
  async createOrder(@Body() orderDto: CreateOrderDto) {
    // ❌ 要自己实现重试逻辑
    let retries = 3;
    while (retries > 0) {
      try {
        const response = await axios.post(
          'http://payment-service/pay',  // ✅ K8s Service 已解决服务发现
          orderDto,
          { timeout: 5000 }
        );
        return response.data;
      } catch (error) {
        retries--;
        if (retries === 0) throw error;
        await sleep(1000);  // ❌ 要自己写退避策略
      }
    }
    
    // ❌ 熔断逻辑要自己实现或引入库(如 Hystrix)
    // ❌ mTLS 加密要自己配置证书
    // ❌ 分布式追踪要手动传递 TraceID
  }
}

问题

  • 重试/超时/熔断:每个服务都要写一遍,或引入 SDK(但多语言栈就麻烦了)
  • 细粒度流量控制:想做金丝雀发布?K8s Service 做不到按比例路由
  • 服务间加密:要手动管理证书、配置 TLS
  • 可观测性:要在每个服务里埋点,传递 TraceID,集成监控
  • 多语言问题:Java 用 Hystrix,Go 用其他库,Node.js 又是另一套

有了 Service Mesh 之后

@Controller('order')
export class OrderController {
  constructor(private readonly paymentClient: PaymentClient) {}
 
  @Post()
  async createOrder(@Body() orderDto: CreateOrderDto) {
    // ✅ 代码超级简洁,只关心业务逻辑
    const result = await this.paymentClient.process(orderDto);
    return result;
  }
}

Sidecar 自动帮你处理

  • 重试:失败自动重试,可配置次数和退避策略
  • 超时:自动超时控制,不需要在代码里写 timeout
  • 熔断:服务故障自动摘除,避免雪崩
  • 负载均衡:多种策略(轮询/最少连接/权重),比 K8s Service 更灵活
  • mTLS 加密:服务间自动加密通信,零配置
  • 分布式追踪:自动注入 TraceID,无需手动传递
  • 监控指标:自动上报延迟、错误率、流量等指标
  • 语言无关:所有服务享受同样的能力,不管你用什么语言

核心架构

Service Mesh 分为两个平面:

控制平面(Control Plane):管理大脑,下发配置、管理证书、收集遥测数据(如 Istio 的 Istiod)

数据平面(Data Plane):实际干活的 Sidecar 代理(如 Envoy),拦截所有流量

         控制平面 (Istiod)
         下发配置 ↓ 上报数据 ↑
    ┌────────┴────────┐
    │                 │
订单 Pod          支付 Pod
┌────────┐      ┌────────┐
│ 订单服务 │      │ 支付服务 │
│  (App) │      │  (App) │
├────────┤      ├────────┤
│ Envoy  │◄────►│ Envoy  │
│Sidecar │ 流量 │Sidecar │
└────────┘      └────────┘

关键:Sidecar 透明拦截,应用完全无感知。

Sidecar 如何注入:在 Kubernetes 中,通过给 Namespace 打标签,Istio 会自动在每个 Pod 里注入 Envoy 容器:

# 给 namespace 打标签,启用自动注入
kubectl label namespace default istio-injection=enabled
 
# 之后部署的所有 Pod 都会自动带上 Envoy Sidecar
kubectl apply -f deployment.yaml

典型场景

金丝雀发布

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: payment-route
spec:
  http:
    - route:
        - destination:
            host: payment
            subset: v1
          weight: 90
        - destination:
            host: payment
            subset: v2
          weight: 10  # 10% 流量到新版本

不改代码,随时调整流量比例,出问题秒回滚。

自动 mTLS

服务 A ─── 明文 HTTP ───→ 服务 B  ❌ 不安全

服务 A ─┬─ 应用看到普通 HTTP
        └─ Envoy 自动加密 ──→ 服务 B  ✅ 自动证书

Istio 自动颁发和轮换证书,零配置。

熔断降级

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
spec:
  trafficPolicy:
    outlierDetection:
      consecutiveErrors: 5
      baseEjectionTime: 30s

服务故障自动摘除,避免雪崩。

主流方案对比

方案IstioLinkerdConsul Connect
复杂度高(功能全)低(轻量)
性能损耗~3-5ms~1-2ms~3-5ms
mTLS
多集群✅ 很强✅ 基础
学习曲线陡峭平缓中等

建议:新手先用 Linkerd 体验,需要高级功能再迁 Istio。

Service Mesh vs API Gateway

很多人会混淆这两个概念:

对比项Service MeshAPI Gateway
位置服务之间(东西向流量)外部到服务(南北向流量)
功能服务间通信治理API 聚合、认证、限流
部署方式每个服务一个 Sidecar集中式网关
典型产品Istio、LinkerdKong、Nginx、Traefik

简单记:API Gateway 是”大门口的保安”,Service Mesh 是”每个房间的管家”。两者通常配合使用。

什么时候需要 Service Mesh

场景建议
2-3 个微服务❌ 没必要,用 K8s Service
10+ 微服务,多语言栈✅ 值得考虑
精细流量控制(金丝雀、A/B)✅ 强烈推荐
服务间必须加密(合规)✅ 自动 mTLS 很香
需要分布式追踪✅ 自动注入 Trace ID
团队小,运维能力弱⚠️ 先上 Linkerd,别碰 Istio

Service Mesh 能做什么、不能做什么

能做:网络层解耦

类型能力
服务发现不用知道 IP,只写服务名
负载均衡自动选实例(轮询/最少连接/权重)
流量管理金丝雀、A/B 测试、流量镜像
安全自动 mTLS、零信任网络
可观测性自动监控指标、分布式追踪、访问日志
弹性超时、重试、熔断、限流

不能做:业务逻辑解耦

订单服务 ──"下单必须扣款"──► 支付服务
         ↑ 这是业务规则
         Service Mesh 无法消除这个依赖

订单服务还是要调用支付服务,代码里还得写 callPayment()。Service Mesh 只是让调用过程更可靠,不改变调用关系

真正的业务解耦需要消息队列(Kafka)或事件驱动架构:

订单服务 ─发事件→ 消息队列 ─消费→ 支付服务
       (不等响应)          (异步处理)
方案耦合程度适用场景
Service Mesh + 同步松耦合(网络)需要实时响应
消息队列 + 异步更松耦合可异步,最终一致