服务(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 只需要你的服务返回的健康检查请求返回2XX
和3XX
之间的状态码(每隔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 服务¶
常规配置¶
服务模块的每个字段代表一种服务。也就是说,对于每个指定的服务,只有一个字段,必须定义创建的是哪种服务,当前,有两种可用的类型:LoadBalancer
和 Weighted
。
服务实例的负载均衡¶
实例的负载均衡负责平衡同一服务的实例之间的请求。
声明一个带有两个实例的服务 -- 使用 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"