跳到正文
Træfɪk

Service

Traefik 服务定义如何在后端服务器之间分配传入流量。 本页介绍两个主要概念:

  • 服务负载均衡器:使用各种负载均衡策略将流量路由到后端服务器
  • 高级服务类型:组合多个服务,实现加权分配、镜像或故障转移

服务负载均衡器

loadBalancer 服务类型将传入请求路由到一组后端服务器。 每个服务都有负载均衡器,即使只有一台服务器可供转发流量。

负载均衡器支持多种在服务器之间分配流量的策略:

  • wrr(加权轮询):默认策略,轮流向服务器均匀分配请求
  • p2c(二选一):随机选择两台服务器,并路由到活动连接较少的那一台
  • hrw(最高随机权重):使用基于客户端 IP 的一致性哈希实现会话亲和性
  • leasttime:综合响应时间与活动连接数,路由到响应时间最低且活动连接最少的服务器

配置示例

http:
  services:
    my-service:
      loadBalancer:
        strategy: "wrr"
        servers:
          - url: "http://private-ip-server-1/"
            weight: 2
            preservePath: true
        sticky:
          cookie:
            name: "sticky-cookie"
        healthcheck:
          path: "/health"
          interval: "10s"
          timeout: "3s"
        passiveHealthCheck:
          failureWindow: "3s"
          maxFailedAttempts: 3
        passHostHeader: true
        serversTransport: "customTransport@file"
        responseForwarding:
          flushInterval: "150ms"
[http.services]
  [http.services.my-service.loadBalancer]
    strategy = "wrr"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-1/"

    [http.services.my-service.loadBalancer.sticky.cookie]
      name = "sticky-cookie"

    [http.services.my-service.loadBalancer.healthcheck]
      path = "/health"
      interval = "10s"
      timeout = "3s"

    [http.services.my-service.loadBalancer.passiveHealthCheck]
      failureWindow = "3s"
      maxFailedAttempts = 3

    passHostHeader = true
    serversTransport = "customTransport@file"

    [http.services.my-service.loadBalancer.responseForwarding]
      flushInterval = "150ms"
labels:
  - "traefik.http.services.my-service.loadBalancer.strategy=wrr"
  - "traefik.http.services.my-service.loadBalancer.servers[0].url=http://private-ip-server-1/"
  - "traefik.http.services.my-service.loadBalancer.servers[0].weight=2"
  - "traefik.http.services.my-service.loadBalancer.servers[0].preservePath=true"
  - "traefik.http.services.my-service.loadBalancer.sticky.cookie.name=sticky-cookie"
  - "traefik.http.services.my-service.loadBalancer.healthcheck.path=/health"
  - "traefik.http.services.my-service.loadBalancer.healthcheck.interval=10s"
  - "traefik.http.services.my-service.loadBalancer.healthcheck.timeout=3s"
  - "traefik.http.services.my-service.loadBalancer.passiveHealthCheck.failureWindow=3s"
  - "traefik.http.services.my-service.loadBalancer.passiveHealthCheck.maxFailedAttempts=3"
  - "traefik.http.services.my-service.loadBalancer.passHostHeader=true"
  - "traefik.http.services.my-service.loadBalancer.serversTransport=customTransport@file"
  - "traefik.http.services.my-service.loadBalancer.responseForwarding.flushInterval=150ms"
{
  "Tags": [
    "traefik.http.services.my-service.loadBalancer.strategy=wrr",
    "traefik.http.services.my-service.loadBalancer.servers[0].url=http://private-ip-server-1/",
    "traefik.http.services.my-service.loadBalancer.servers[0].weight=2",
    "traefik.http.services.my-service.loadBalancer.servers[0].preservePath=true",
    "traefik.http.services.my-service.loadBalancer.sticky.cookie.name=sticky-cookie",
    "traefik.http.services.my-service.loadBalancer.healthcheck.path=/health",
    "traefik.http.services.my-service.loadBalancer.healthcheck.interval=10s",
    "traefik.http.services.my-service.loadBalancer.healthcheck.timeout=3s",
    "traefik.http.services.my-service.loadBalancer.passiveHealthCheck.failureWindow=3s",
    "traefik.http.services.my-service.loadBalancer.passiveHealthCheck.maxFailedAttempts=3",
    "traefik.http.services.my-service.loadBalancer.passHostHeader=true",
    "traefik.http.services.my-service.loadBalancer.serversTransport=customTransport@file",
    "traefik.http.services.my-service.loadBalancer.responseForwarding.flushInterval=150ms"
  ]
}

配置选项

字段 说明 必填
servers 表示服务的各个后端实例 是
strategy 在服务器之间分配流量的负载均衡策略。有效值为 wrr(默认)、p2c、hrw、leasttime。 否
sticky 在初始响应中设置 Set-Cookie 响应头,让客户端知道是哪台服务器处理了第一次响应。 否
healthcheck 配置健康检查,将不健康的服务器从负载均衡轮转中移除。 否
passiveHealthCheck 配置被动健康检查,将不健康的服务器从负载均衡轮转中移除。 否
passHostHeader 允许将客户端 Host 请求头转发到服务器。默认情况下,passHostHeader 为 true。 否
serversTransport 支持引用 HTTP ServersTransport 配置,用于 Traefik 与服务器之间的通信。如果未指定 serversTransport,则使用 default@internal。 否
responseForwarding 配置 Traefik 如何将后端服务器响应转发给客户端。 否
responseForwarding.flushInterval 指定复制响应体期间向客户端刷新数据的间隔。此时长以毫秒计,默认为 100ms。负值表示每次向客户端写入后立即刷新。当 ReverseProxy 识别出流式响应时,会忽略 FlushInterval;对于此类响应,写入内容会立即刷新到客户端。 否

服务器

服务器表示服务的各个后端实例。服务 loadBalancer 的 servers 选项支持配置处理传入请求的实例列表。

配置选项
字段 说明 必填
url 指向具体实例。 文件提供者必填,Docker 提供者不必填
weight 允许对服务器进行加权负载均衡。 否
preservePath 允许保留 URL 路径。 否

负载均衡策略

负载均衡器的 strategy 选项决定如何在后端服务器之间分配流量。

加权轮询(wrr)

这是默认策略。遵循服务器权重,轮流向所有服务器均匀分配请求。 此策略使用最早截止时间优先(EDF)调度实现加权轮询行为。

WRR 负载均衡——使用文件提供者
## Routing configuration
http:
  services:
    my-service:
      loadBalancer:
        strategy: "wrr"
        servers:
        - url: "http://private-ip-server-1/"
          weight: 3
        - url: "http://private-ip-server-2/"
          weight: 1
## Routing configuration
[http.services]
  [http.services.my-service.loadBalancer]
    strategy = "wrr"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-1/"
      weight = 3
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-2/"
      weight = 1

二选一(p2c)

随机选择两台服务器,并将请求路由到活动连接数最少的那一台。 当服务器的响应时间不同时,此算法能够提供更好的负载分配。

P2C 负载均衡——使用文件提供者
## Routing configuration
http:
  services:
    my-service:
      loadBalancer:
        strategy: "p2c"
        servers:
        - url: "http://private-ip-server-1/"
        - url: "http://private-ip-server-2/"
        - url: "http://private-ip-server-3/"
## Routing configuration
[http.services]
  [http.services.my-service.loadBalancer]
    strategy = "p2c"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-1/"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-2/"       
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-3/"

最高随机权重(hrw)

使用基于客户端 IP 地址的一致性哈希(Rendezvous 哈希),确保同一客户端的请求始终路由到同一台服务器。 这无需粘性 Cookie 即可提供会话亲和性。

算法使用客户端源 IP 与后端标识符组合后的哈希,为每个可用后端计算分数,并将客户端分配给得分最高的后端。

HRW 负载均衡——使用文件提供者
## Routing configuration
http:
  services:
    my-service:
      loadBalancer:
        strategy: "hrw"
        servers:
        - url: "http://private-ip-server-1/"
        - url: "http://private-ip-server-2/"
        - url: "http://private-ip-server-3/"
## Routing configuration
[http.services]
  [http.services.my-service.loadBalancer]
    strategy = "hrw"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-1/"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-2/"       
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-3/"

最短时间(Least-Time)

综合最低平均响应时间(首字节时间,即 TTFB)与最少活动连接数,并按服务器容量加权,选择服务器。 此策略非常适合异构后端环境,其中服务器的性能特征、硬件能力或网络延迟各不相同。

算法持续测量各个后端的响应时间,并跟踪活动连接数。 路由请求时,使用公式 (avg_response_time × (1 + active_connections)) / weight 为每台健康服务器计算分数。 得分最低的服务器接收请求。 多台服务器得分相同时,使用采用最早截止时间优先(EDF)调度的加权轮询(WRR)打破平局。

Least-Time 负载均衡——使用文件提供者
## Routing configuration
http:
  services:
    my-service:
      loadBalancer:
        strategy: "leasttime"
        servers:
        - url: "http://private-ip-server-1/"
        - url: "http://private-ip-server-2/"
        - url: "http://private-ip-server-3/"
## Routing configuration
[http.services]
  [http.services.my-service.loadBalancer]
    strategy = "leasttime"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-1/"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-2/"
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-3/"

健康检查

healthcheck 选项配置健康检查,将不健康的服务器从负载均衡轮转中移除。 只要 HTTP(s) 服务器对健康检查请求(每隔 interval 执行一次)返回的状态码介于 2XX 和 3XX 之间,或匹配配置的状态码,Traefik 就会认为其健康。 对于 gRPC 服务器,只要它对 gRPC 健康检查 v1 请求返回 SERVING,Traefik 就会认为其健康。

要向上传播状态变化(例如此服务的所有服务器均不可用),还必须在此服务的父级启用 HealthCheck。

健康检查机制可用的选项如下:

字段 说明 默认值 必填
path 定义健康检查端点的服务器 URL 路径。配置的路径必须是相对 URL。 "" 是
scheme 替换健康检查端点的服务器 URL 协议方案。 否
mode 如果定义为 grpc,则使用 gRPC 健康检查协议探测服务器。 http 否
hostname 定义健康检查请求的 Host 请求头中的主机名值。 "" 否
port 替换健康检查端点的服务器 URL 端口。 否
interval 定义对健康目标执行健康检查的频率。 30s 否
unhealthyInterval 定义对不健康目标执行健康检查的频率。未定义时,默认为 interval 的值。 - 否
timeout 定义 Traefik 等待健康检查请求的最长时间,超过此时间则认为服务器不健康。 5s 否
headers 定义发送到健康检查端点的自定义请求头。 否
followRedirects 定义执行健康检查时是否跟随重定向。 true 否
method 定义连接端点时使用的 HTTP 方法。 GET 否
status 定义健康检查请求响应的预期 HTTP 状态码。 否

粘性会话

启用粘性会话后,初始响应会设置 Set-Cookie 响应头,让客户端知道是哪台服务器处理了第一次响应。 在后续请求中,客户端应发送带有该值的 Cookie,以维持与同一台服务器的会话。

多层级粘性

串联或混合使用负载均衡器时(例如,服务器负载均衡器是服务负载均衡器的一个“子级”),要使粘性贯穿整个链路,必须在所有需要的层级指定此选项。这意味着客户端发送的 Cookie 中,键值对的数量应与粘性层级数相同。

粘性与不健康的服务器

如果 Cookie 指定的服务器变得不健康,请求将转发到新服务器(Cookie 也会记录新服务器)。

默认 Cookie 名称是 sha1 的缩写(例如 _1d52e)。

MaxAge(最大寿命)

默认情况下,亲和性 Cookie 永不过期,因为 MaxAge 选项设置为零。

此选项指定 Cookie 过期前的秒数。 设置为负数时,Cookie 立即过期。

Secure、HTTPOnly 和 SameSite 标志

默认情况下,创建亲和性 Cookie 时不带这些标志。 不过可以通过配置更改这一行为。

SameSite 可以为 none、lax、strict 或空。取值不区分大小写。

域名

Cookie 的 Domain 属性指定该 Cookie 的有效域名。

设置 Domain 属性后,可以在子域名之间共享 Cookie(例如,为 example.com 设置的 Cookie 也可以由 www.example.com、api.example.com 等访问)。这在粘性会话跨越多个子域名时特别有用,可以确保客户端与基础设施的不同部分交互时仍保持会话。

添加粘性——使用文件提供者
## Routing configuration
http:
  services:
    my-service:
      loadBalancer:
        sticky:
         cookie: {}
## Routing configuration
[http.services]
  [http.services.my-service]
    [http.services.my-service.loadBalancer.sticky.cookie]
使用自定义选项添加粘性——使用文件提供者
## Routing configuration
http:
  services:
    my-service:
      loadBalancer:
        sticky:
          cookie:
            name: my_sticky_cookie_name
            secure: true
            domain: mysite.site
            httpOnly: true
## Routing configuration
[http.services]
  [http.services.my-service]
    [http.services.my-service.loadBalancer.sticky.cookie]
      name = "my_sticky_cookie_name"
      secure = true
      httpOnly = true
      domain = "mysite.site"
      sameSite = "none"
在所有必需层级设置粘性——使用文件提供者
## Routing configuration
http:
  services:
    wrr1:
      weighted:
        sticky:
          cookie:
            name: lvl1
        services:
          - name: whoami1
            weight: 1
          - name: whoami2
            weight: 1

    whoami1:
      loadBalancer:
        sticky:
          cookie:
            name: lvl2
        servers:
          - url: http://127.0.0.1:8081
          - url: http://127.0.0.1:8082

    whoami2:
      loadBalancer:
        sticky:
          cookie:
            name: lvl2
        servers:
          - url: http://127.0.0.1:8083
          - url: http://127.0.0.1:8084
## Routing configuration
[http.services]
  [http.services.wrr1]
    [http.services.wrr1.weighted.sticky.cookie]
      name = "lvl1"
    [[http.services.wrr1.weighted.services]]
      name = "whoami1"
      weight = 1
    [[http.services.wrr1.weighted.services]]
      name = "whoami2"
      weight = 1

  [http.services.whoami1]
    [http.services.whoami1.loadBalancer]
      [http.services.whoami1.loadBalancer.sticky.cookie]
        name = "lvl2"
      [[http.services.whoami1.loadBalancer.servers]]
        url = "http://127.0.0.1:8081"
      [[http.services.whoami1.loadBalancer.servers]]
        url = "http://127.0.0.1:8082"

  [http.services.whoami2]
    [http.services.whoami2.loadBalancer]
      [http.services.whoami2.loadBalancer.sticky.cookie]
        name = "lvl2"
      [[http.services.whoami2.loadBalancer.servers]]
        url = "http://127.0.0.1:8083"
      [[http.services.whoami2.loadBalancer.servers]]
        url = "http://127.0.0.1:8084"

为保持与同一台服务器的会话,客户端需要在每个请求的 Cookie 中指定这两个层级,例如使用 curl:

curl -b "lvl1=whoami1; lvl2=http://127.0.0.1:8081" http://localhost:8000

被动健康检查

passiveHealthCheck 选项配置被动健康检查,将不健康的服务器从负载均衡轮转中移除。

被动健康检查依靠真实流量评估服务器健康状态。 Traefik 照常转发请求,并评估每次响应或超时, 每当请求失败时就增加失败计数器。 如果指定时间窗口内连续失败的次数超过配置的阈值, Traefik 将自动停止向该服务器路由流量,直到它恢复。 配置的失败窗口结束后,服务器会再次被认为健康。

被动健康检查机制可用的选项如下:

字段 说明 默认值 必填
failureWindow 定义服务器被标记为不健康前,失败尝试必须发生的时间窗口。此选项也定义服务器被视为不健康的持续时长。 10s 否
maxFailedAttempts 定义在失败窗口内,服务器被标记为不健康前所允许的连续失败尝试次数。 1 否

中间件

可以为每个 HTTP 服务附加一组中间件。 无论由哪个路由器转发请求,这些中间件都会对该服务处理的所有请求生效。

中间件执行顺序

当路由器和服务都配置了中间件时,先应用路由器中间件,再应用服务中间件。 这意味着请求先经过路由器中间件,才会到达服务中间件。

支持的提供者

可以通过文件、Docker、Swarm、Kubernetes IngressRoute、Kubernetes Ingress 和 Kubernetes Gateway API 提供者配置服务级中间件。

向服务附加中间件——使用文件提供者
## Dynamic configuration
http:
  services:
    my-service:
      middlewares:
        - add-header
      loadBalancer:
        servers:
          - url: "http://127.0.0.1:8080"

  middlewares:
    add-header:
      headers:
        customRequestHeaders:
          X-Custom-Header: "service-middleware"
## Dynamic configuration
[http.services]
  [http.services.my-service]
    middlewares = ["add-header"]
    [http.services.my-service.loadBalancer]
      [[http.services.my-service.loadBalancer.servers]]
        url = "http://127.0.0.1:8080"

[http.middlewares]
  [http.middlewares.add-header.headers]
    [http.middlewares.add-header.headers.customRequestHeaders]
      X-Custom-Header = "service-middleware"
向服务附加中间件——使用 Docker 标签
labels:
  # Define the middleware
  - "traefik.http.middlewares.add-header.headers.customRequestHeaders.X-Custom-Header=service-middleware"
  # Attach middleware to the service (at service level, not loadBalancer level)
  - "traefik.http.services.my-service.middlewares=add-header"
  # Configure the service
  - "traefik.http.services.my-service.loadbalancer.server.port=8080"

高级服务类型

高级服务类型支持组合多个服务,用于加权分配、一致性哈希、镜像或故障转移场景。 这与负载均衡策略不同:它们工作在服务级别,而不是服务器级别。

关键区别

  • 负载均衡策略(wrr、p2c、hrw、leasttime):在单个 loadBalancer 服务内部的服务器之间分配流量
  • 高级服务类型(weighted、highestRandomWeight、mirroring、failover):在多个服务之间分配或管理流量

加权轮询

weighted 服务类型根据权重在多个服务之间对请求进行负载均衡。 这与 wrr 策略不同:它作用于服务,而不是服务器。

支持的提供者

目前可以通过文件提供者或 IngressRoute 定义此服务类型。

## Routing configuration
http:
  services:
    app:
      weighted:
        services:
        - name: appv1
          weight: 3
        - name: appv2
          weight: 1

    appv1:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.app]
    [[http.services.app.weighted.services]]
      name = "appv1"
      weight = 3
    [[http.services.app.weighted.services]]
      name = "appv2"
      weight = 1

  [http.services.appv1]
    [http.services.appv1.loadBalancer]
      [[http.services.appv1.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.appv2]
    [http.services.appv2.loadBalancer]
      [[http.services.appv2.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

健康检查

HealthCheck 为此服务启用自动自健康检查,也就是说,只要有子服务被报告为不可用,此服务就会获知该状态,并在运行负载均衡算法时考虑它(即忽略不可用的子服务)。此外,如果此服务的父级也启用了 HealthCheck,此服务会向父级报告任何状态变化。

行为

如果为某个服务启用了 HealthCheck,但其任意后代未启用 HealthCheck,则该服务创建失败。

目前,加权服务的 HealthCheck 只能通过文件提供者定义。

## Routing configuration
http:
  services:
    app:
      weighted:
        healthCheck: {}
        services:
        - name: appv1
          weight: 3
        - name: appv2
          weight: 1

    appv1:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.app]
    [http.services.app.weighted.healthCheck]
    [[http.services.app.weighted.services]]
      name = "appv1"
      weight = 3
    [[http.services.app.weighted.services]]
      name = "appv2"
      weight = 1

  [http.services.appv1]
    [http.services.appv1.loadBalancer]
      [http.services.appv1.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.appv1.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.appv2]
    [http.services.appv2.loadBalancer]
      [http.services.appv2.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.appv2.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

最高随机权重

highestRandomWeight 服务类型使用一致性哈希(Rendezvous 哈希)在多个服务之间对请求进行负载均衡。 这确保同一客户端 IP 的请求始终路由到同一服务。

这与 loadBalancer 的 hrw 策略不同:它作用于服务,而不是服务器。

支持的提供者

目前只能通过文件提供者定义此服务类型。

## Routing configuration
http:
  services:
    app:
      highestRandomWeight:
        services:
        - name: appv1
          weight: 1
        - name: appv2
          weight: 1

    appv1:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.app]
    [[http.services.app.highestRandomWeight.services]]
      name = "appv1"
      weight = 1
    [[http.services.app.highestRandomWeight.services]]
      name = "appv2"
      weight = 1

  [http.services.appv1]
    [http.services.appv1.loadBalancer]
      [[http.services.appv1.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.appv2]
    [http.services.appv2.loadBalancer]
      [[http.services.appv2.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

健康检查

HealthCheck 为此服务启用自动自健康检查,与加权轮询服务类型类似。

行为

如果为某个服务启用了 HealthCheck,但其任意后代未启用 HealthCheck,则该服务创建失败。

目前,最高随机权重服务的 HealthCheck 只能通过文件提供者定义。

## Routing configuration
http:
  services:
    app:
      highestRandomWeight:
        healthCheck: {}
        services:
        - name: appv1
          weight: 1
        - name: appv2
          weight: 1

    appv1:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.app]
    [http.services.app.highestRandomWeight.healthCheck]
    [[http.services.app.highestRandomWeight.services]]
      name = "appv1"
      weight = 1
    [[http.services.app.highestRandomWeight.services]]
      name = "appv2"
      weight = 1

  [http.services.appv1]
    [http.services.appv1.loadBalancer]
      [http.services.appv1.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.appv1.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.appv2]
    [http.services.appv2.loadBalancer]
      [http.services.appv2.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.appv2.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

镜像

mirroring 服务类型将发送到一个服务的请求镜像到其他服务。请注意,默认情况下,镜像时整个请求会缓存在内存中。如何修改此行为,参阅下例中的 maxBodySize 选项。也可以将 mirrorBody 选项设置为 false,从而省略请求体。

percent 的默认行为

配置 mirror 服务时,如果未设置 percent 字段,则默认为 0,表示不会向镜像发送任何流量。

支持的提供者

目前可以通过文件提供者或 IngressRoute 定义此服务类型。

## Routing configuration
http:
  services:
    mirrored-api:
      mirroring:
        service: appv1
        # mirrorBody defines whether the request body should be mirrored.
        # Default value is true.
        mirrorBody: false
        # maxBodySize is the maximum size allowed for the body of the request.
        # If the body is larger, the request is not mirrored.
        # Default value is -1, which means unlimited size.
        maxBodySize: 1024
        mirrors:
        - name: appv2
          # Percent defines the percentage of requests that should be mirrored.
          # Default value is 0, which means no traffic will be sent to the mirror.
          percent: 10

    appv1:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/
## Routing configuration
[http.services]
  [http.services.mirrored-api]
    [http.services.mirrored-api.mirroring]
      service = "appv1"
      # maxBodySize is the maximum size in bytes allowed for the body of the request.
      # If the body is larger, the request is not mirrored.
      # Default value is -1, which means unlimited size.
      maxBodySize = 1024
      # mirrorBody defines whether the request body should be mirrored.
      # Default value is true.
      mirrorBody = false
    [[http.services.mirrored-api.mirroring.mirrors]]
      name = "appv2"
      percent = 10

  [http.services.appv1]
    [http.services.appv1.loadBalancer]
      [[http.services.appv1.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.appv2]
    [http.services.appv2.loadBalancer]
      [[http.services.appv2.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

健康检查

HealthCheck 为此服务启用自动自健康检查,即如果服务的主处理器变得不可达,此信息会向上传播到父级。

行为

如果为某个服务启用了 HealthCheck,但其任意后代未启用 HealthCheck,则该服务创建失败。

目前,镜像服务的 HealthCheck 只能通过文件提供者定义。

## Routing configuration
http:
  services:
    mirrored-api:
      mirroring:
        healthCheck: {}
        service: appv1
        mirrors:
        - name: appv2
          percent: 10

    appv1:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.mirrored-api]
    [http.services.mirrored-api.mirroring]
      service = "appv1"
      [http.services.mirrored-api.mirroring.healthCheck]
    [[http.services.mirrored-api.mirroring.mirrors]]
      name = "appv2"
      percent = 10

  [http.services.appv1]
    [http.services.appv1.loadBalancer]
      [http.services.appv1.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.appv1.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.appv2]
    [http.services.appv2.loadBalancer]
      [http.services.appv2.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.appv2.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

故障转移

failover 服务类型在主服务不可用时,将请求转发到备用服务。 故障转移有两种触发方式:

  • 基于健康检查:根据健康检查判断主服务变得不可达。
  • 基于状态码:主服务返回 errors 配置中指定的 HTTP 状态码。

与 HealthCheck 的关系

故障转移服务依靠 HealthCheck 系统获知主服务何时变得不可达,因此主服务必须启用 HealthCheck 且其功能正常。但是,故障转移服务本身无需启用 HealthCheck 也能工作。只有在需要向上传播故障转移服务本身不可用的信息时(即主服务和备用服务均不可用),才需要启用它。

支持的提供者

可以通过文件和 Kubernetes CRD 提供者定义此服务类型。

健康检查

HealthCheck 为此服务启用自动自健康检查,即如果主服务和备用服务都变得不可达,此信息会向上传播到父级。

行为

如果为某个服务启用了 HealthCheck,但其任意后代未启用 HealthCheck,则该服务创建失败。

目前,故障转移服务的 HealthCheck 只能通过文件提供者定义。

## Routing configuration
http:
  services:
    app:
      failover:
        healthCheck: {}
        service: main
        fallback: backup

    main:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-1/"

    backup:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.app]
    [http.services.app.failover]
      service = "main"
      fallback = "backup"
      [http.services.app.failover.healthCheck]

  [http.services.main]
    [http.services.main.loadBalancer]
      [http.services.main.loadBalancer.healthCheck]
        path = "/status"
        interval = "10s"
        timeout = "3s"
      [[http.services.main.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.backup]
    [http.services.backup.loadBalancer]
      [http.services.backup.loadBalancer.healthCheck]
        path = "/status"
        interval = "10s"
        timeout = "3s"
      [[http.services.backup.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

错误

errors 选项启用基于状态码的故障转移。 主服务返回的 HTTP 状态码匹配任一配置范围时,Traefik 会自动在备用服务上重试请求。

为支持请求重放,请求体最多缓存 maxRequestBodyBytes 字节。 请求体超过此限制的请求会收到 413 Request Entity Too Large 响应。

下面列出 errors 选项可用的配置项,并给出为故障转移服务配置它的示例:

字段 说明 默认值
status 触发故障转移的 HTTP 状态码范围列表。支持单个状态码("500")和范围("500-504")。 None
maxRequestBodyBytes 为重放到备用服务而缓存的最大请求体大小(字节)。设置为 -1 表示不限制。 -1
## Routing configuration
http:
  services:
    app:
      failover:
        service: main
        fallback: backup
        errors:
          status:
            - "500-504"
          maxRequestBodyBytes: 1048576

    main:
      loadBalancer:
        servers:
          - url: "http://private-ip-server-1/"

    backup:
      loadBalancer:
        servers:
          - url: "http://private-ip-server-2/"
## Routing configuration
[http.services]
  [http.services.app]
    [http.services.app.failover]
      service = "main"
      fallback = "backup"
      [http.services.app.failover.errors]
        status = ["500-504"]
        maxRequestBodyBytes = 1048576

  [http.services.main]
    [http.services.main.loadBalancer]
      [[http.services.main.loadBalancer.servers]]
        url = "http://private-ip-server-1/"

  [http.services.backup]
    [http.services.backup.loadBalancer]
      [[http.services.backup.loadBalancer.servers]]
        url = "http://private-ip-server-2/"

串联故障转移服务

故障转移服务可以串联,以实现多级冗余。 在下例中,如果主服务失败,流量会发送到次级服务。 如果主服务和次级服务都失败,流量会发送到第三级服务。

## Routing configuration
http:
  services:
    app:
      failover:
        healthCheck: {}
        service: primary-failover
        fallback: tertiary

    primary-failover:
      failover:
        healthCheck: {}
        service: primary
        fallback: secondary

    primary:
      loadBalancer:
        healthCheck:
          path: /health
          interval: 10s
          timeout: 3s
        servers:
          - url: "http://primary-server/"

    secondary:
      loadBalancer:
        healthCheck:
          path: /health
          interval: 10s
          timeout: 3s
        servers:
          - url: "http://secondary-server/"

    tertiary:
      loadBalancer:
        healthCheck:
          path: /health
          interval: 10s
          timeout: 3s
        servers:
          - url: "http://tertiary-server/"
## Routing configuration
[http.services]
  [http.services.app]
    [http.services.app.failover]
      service = "primary-failover"
      fallback = "tertiary"
      [http.services.app.failover.healthCheck]

  [http.services.primary-failover]
    [http.services.primary-failover.failover]
      service = "primary"
      fallback = "secondary"
      [http.services.primary-failover.failover.healthCheck]

  [http.services.primary]
    [http.services.primary.loadBalancer]
      [http.services.primary.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.primary.loadBalancer.servers]]
        url = "http://primary-server/"

  [http.services.secondary]
    [http.services.secondary.loadBalancer]
      [http.services.secondary.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.secondary.loadBalancer.servers]]
        url = "http://secondary-server/"

  [http.services.tertiary]
    [http.services.tertiary.loadBalancer]
      [http.services.tertiary.loadBalancer.healthCheck]
        path = "/health"
        interval = "10s"
        timeout = "3s"
      [[http.services.tertiary.loadBalancer.servers]]
        url = "http://tertiary-server/"

版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证