跳转至

服务(Services)

配置如何到达服务

services

Services 负责配置如何获取最终将处理传入请求的实际服务。

配置示例

为一个 HTTP 服务声明两个实例 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.my-service.loadBalancer]

    [[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-1/"
        - url: "http://private-ip-server-2/"
为一个 TCP 服务声明两个实例 -- 使用 File Provider
## 动态配置
[tcp.services]
  [tcp.services.my-service.loadBalancer]
     [[tcp.services.my-service.loadBalancer.servers]]
       address = "xx.xx.xx.xx:xx"
     [[tcp.services.my-service.loadBalancer.servers]]
       address = "xx.xx.xx.xx:xx"
tcp:
  services:
    my-service:
      loadBalancer:         
        servers:
        - address: "xx.xx.xx.xx:xx"
        - address: "xx.xx.xx.xx:xx"

配置 HTTP 服务

负载均衡器

负载均衡器能够在程序的多个实例之间对请求进行负载均衡。

为一个服务声明两个实例(使用负载均衡)-- 使用 File Provider
## 动态配置
[http.services]
  [http.services.my-service.loadBalancer]

    [[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-1/"
        - url: "http://private-ip-server-2/"

Servers

服务器(Servers)用于声明你的程序的单个实例。url选项指向特定的实例。

在服务上面的 Path 路径在 url 中的配置是无效的。 如果你希望将请求发送到服务上的特定路径,则配置你的 路由 使用相应的 中间件(例如 AddPrefix 或者 ReplacePath)即可。

一个服务对应一个实例 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.my-service.loadBalancer]
    [[http.services.my-service.loadBalancer.servers]]
      url = "http://private-ip-server-1/"
## 动态配置
http:
  services:
    my-service:
      loadBalancer:
        servers:
          - url: "http://private-ip-server-1/"

负载均衡算法

现阶段只支持 round robin 这种算法:

负载均衡 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.my-service.loadBalancer]
    [[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-1/"
        - url: "http://private-ip-server-2/"

session 亲和性

当启用 session 亲和性后,将在初始请求上设置 cookie,用以跟踪哪个服务器处理的一个响应。后续的请求,客户端将转发到同一个服务器中去。

亲和 & 不健康的服务器

如果 cookie 中指定的服务不正常,则该请求将被转发到新的服务器上去(cookie 将跟踪新的服务器)。

Cookie 名

默认的 cookie 名是 sha1 值的一个缩写(例如:_1d52e)。

Secure 和 HTTPOnly 标记

默认情况下,亲和性的 cookie 被创建是不包含这些标记的,但是,可以通过配置来更改。

添加亲和性 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.my-service]
    [http.services.my-service.loadBalancer.sticky.cookie]
## 动态配置
http:
  services:
    my-service:
      loadBalancer:
        sticky:
         cookie: {}
用定制选项添加亲和性 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.my-service]
    [http.services.my-service.loadBalancer.sticky.cookie]
      name = "my_sticky_cookie_name"
      secure = true
      httpOnly = true
## 动态配置
http:
  services:
    my-service:
      loadBalancer:
        sticky:
          cookie:
            name: my_sticky_cookie_name
            secure: true
            httpOnly: true

健康检查

配置监控检查,可以从负载均衡器中删除不正常的服务。Traefik 只需要你的服务返回的健康检查请求返回2XX3XX之间的状态码(每隔interval间隔检测一次),就会认为你的服务是健康的。

下面是一些运行健康检查机制的可用的选项:

  • path 添加到服务的 URL 上来设置健康检查的端点。
  • 如果定义了 scheme,它将会替换健康检查端点的服务 URL 的 scheme
  • 如果定义了 hostname, 同样它将会替换健康检查端点的服务 URL 的 hostname
  • 如果定义了 port, 同样它将会替换健康检查端点的服务 URL 的 port
  • interval 定义了健康检查检测的频率。
  • timeout 定义了 Traefik 在认为服务不正常之前等待运行健康检查的最长时间。
  • headers 定义了要发送到健康检查端点上的自定义头信息。

Interval & Timeout 格式

Interval 和 timeout 时间同样应该是 time.ParseDuration 支持的格式。

Interval 的时间必须大于超时的时间。如果配置不满足该要求,则 Interval 时间将被设置为 timeout + 1 秒。

服务恢复

Traefik 会继续监视运行不正常的服务的健康状态,如果服务恢复了(返回2xx -> 3xx),它将被添加会负载均衡池里面去的。

定制 Interval 和 Timeout -- 使用 File Provider
## 动态配置
[http.services]
  [http.servicess.Service-1]
    [http.services.Service-1.loadBalancer.healthCheck]
      path = "/health"
      interval = "10s"
      timeout = "3s"
## 动态配置
http:
  servicess:
    Service-1:
      loadBalancer:
        healthCheck:
          path: /health
          interval: "10s"
          timeout: "3s"
定制端口 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.Service-1]
    [http.services.Service-1.loadBalancer.healthCheck]
      path = "/health"
      port = 8080
## 动态配置
http:
  services:
    Service-1:
      loadBalancer:
        healthCheck:
          path: /health
          port: 8080
定制 Scheme -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.Service-1]
    [http.services.Service-1.loadBalancer.healthCheck]
      path = "/health"
      scheme = "http"
## 动态配置
http:
  services:
    Service-1:
      loadBalancer:
        healthCheck:
          path: /health
          scheme: http
添加 HTTP 头信息 -- 使用 File Provider
## 动态配置
[http.services]
  [http.services.Service-1]
    [http.services.Service-1.loadBalancer.healthCheck]
      path = "/health"

      [http.services.Service-1.loadBalancer.healthCheck.headers]
        My-Custom-Header = "foo"
        My-Header = "bar"
## 动态配置
http:
  services:
    Service-1:
      loadBalancer:
        healthCheck:
          path: /health
          headers:
            My-Custom-Header: foo
            My-Header: bar

带权重的轮询 (服务)

WRR(带权重的轮询) 能够基于权重在多个服务之间平衡请求的负载。该策略仅可用于在 服务 之间进行负载平衡,而不能在 服务器实例 之间进行负载均衡。

该策略只能使用 File 进行定义。

## 动态配置
[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/"
## 动态配置
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/"

镜像 (服务)

镜像能够将发送到服务的请求镜像复制到其他服务去。

该策略只能用 File 进行定义。

## 动态配置
[http.services]
  [http.services.mirrored-api]
    [http.services.mirrored-api.mirroring]
      service = "appv1"
    [[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/"
## 动态配置
http:
  services:
    mirrored-api:
      mirroring:
        service: appv1
        mirrors:
        - name: appv2
          percent: 10

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

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"

配置 TCP 服务

常规配置

服务模块的每个字段代表一种服务。也就是说,对于每个指定的服务,只有一个字段,必须定义创建的是哪种服务,当前,有两种可用的类型:LoadBalancerWeighted

服务实例的负载均衡

实例的负载均衡负责平衡同一服务的实例之间的请求。

声明一个带有两个实例的服务 -- 使用 File Provider
## 动态配置
[tcp.services]
  [tcp.services.my-service.loadBalancer]
    [[tcp.services.my-service.loadBalancer.servers]]
      address = "xx.xx.xx.xx:xx"
    [[tcp.services.my-service.loadBalancer.servers]]
       address = "xx.xx.xx.xx:xx"
## 动态配置
tcp:
  services:
    my-service:
      loadBalancer:
        servers:
        - address: "xx.xx.xx.xx:xx"
        - address: "xx.xx.xx.xx:xx"

服务器实例

Servers 声明了应用的单个实例。address 的选项(IP:Port)指向特定的实例。

一个实例的服务 -- 使用 File Provider
## 动态配置
[tcp.services]
  [tcp.services.my-service.loadBalancer]
    [[tcp.services.my-service.loadBalancer.servers]]
      address = "xx.xx.xx.xx:xx"
## 动态配置
tcp:
  services:
    my-service:
      loadBalancer:
        servers:
          address: "xx.xx.xx.xx:xx"

终止延迟

作为客户端和服务器之间的代理,任何一方(比如客户端)都有可能终止其在连接上的写入功能(比如发出 FIN 数据包)。代理需要将该意图传播到另外一段,因此当发生这种情况的时候,它在域另一端(例如后端)的连接中也要执行相同的操作。

但是,如果由于某些原因(错误的实现或者恶意的攻击)导致另一端没有执行相同的操作,连接将保持半打开状态,导致资源会被锁定很长时间。

所以代理服务器一旦进入了终止序列,就需要为完全终止双方的连接设置一个最后的期限。终止延迟就可以来控制该截止时间。

该时间以毫秒为单位,默认为100。如果为负数则表示无限的截止时间(即连接永远不会被代理本身完全终止掉)。

带有终止延迟的服务 -- 使用 File Provider
## 动态配置
[tcp.services]
  [tcp.services.my-service.loadBalancer]
    [[tcp.services.my-service.loadBalancer]]
      terminationDelay = 200
## 动态配置
tcp:
  services:
    my-service:
      loadBalancer:
        terminationDelay: 200

带权重的轮询

服务的带权重的轮询(WRR)负载均衡器负责根据提供的权重来平衡多个服务之间的请求。该策略仅可用于在 服务 之间进行负载均衡,而不能在 服务器实例 之间使用。

该策略只能用 File 进行定义。

## 动态配置
[tcp.services]
  [tcp.services.app]
    [[tcp.services.app.weighted.services]]
      name = "appv1"
      weight = 3
    [[tcp.services.app.weighted.services]]
      name = "appv2"
      weight = 1

  [tcp.services.appv1]
    [tcp.services.appv1.loadBalancer]
      [[tcp.services.appv1.loadBalancer.servers]]
        address = "private-ip-server-1/:8080"

  [tcp.services.appv2]
    [tcp.services.appv2.loadBalancer]
      [[tcp.services.appv2.loadBalancer.servers]]
        address = "private-ip-server-2/:8080"
## 动态配置
tcp:
  services:
    app:
      weighted:
        services:
        - name: appv1
          weight: 3
        - name: appv2
          weight: 1

    appv1:
      loadBalancer:
        servers:
        - address: "xxx.xxx.xxx.xxx:8080"

    appv2:
      loadBalancer:
        servers:
        - address: "xxx.xxx.xxx.xxx:8080"