Files
EdgeCommon/pkg/serverconfigs/reverse_proxy_config.go

274 lines
9.1 KiB
Go
Raw Normal View History

2020-09-13 19:27:47 +08:00
package serverconfigs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
2020-09-15 14:44:38 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
2020-09-13 19:27:47 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/lists"
2020-09-13 19:27:47 +08:00
"sync"
)
type RequestHostType = int8
const (
RequestHostTypeProxyServer RequestHostType = 0
RequestHostTypeOrigin RequestHostType = 1
RequestHostTypeCustomized RequestHostType = 2
)
2021-08-01 21:56:15 +08:00
// ReverseProxyConfig 反向代理设置
2020-09-13 19:27:47 +08:00
type ReverseProxyConfig struct {
2020-09-21 20:21:20 +08:00
Id int64 `yaml:"id" json:"id"` // ID
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
PrimaryOrigins []*OriginConfig `yaml:"primaryOrigins" json:"primaryOrigins"` // 主要源站列表
PrimaryOriginRefs []*OriginRef `yaml:"primaryOriginRefs" json:"primaryOriginRefs"` // 主要源站引用
BackupOrigins []*OriginConfig `yaml:"backupOrigins" json:"backupOrigins"` // 备用源站列表
BackupOriginRefs []*OriginRef `yaml:"backupOriginRefs" json:"backupOriginRefs"` // 备用源站引用
Scheduling *SchedulingConfig `yaml:"scheduling" json:"scheduling"` // 调度算法选项
2020-09-13 19:27:47 +08:00
ConnTimeout *shared.TimeDuration `yaml:"connTimeout" json:"connTimeout"` // 连接失败超时 TODO
ReadTimeout *shared.TimeDuration `yaml:"readTimeout" json:"readTimeout"` // 读取超时时间 TODO
IdleTimeout *shared.TimeDuration `yaml:"idleTimeout" json:"idleTimeout"` // 空闲连接超时时间 TODO
MaxFails int `yaml:"maxFails" json:"maxFails"` // 最多失败次数 TODO
MaxConns int `yaml:"maxConns" json:"maxConns"` // 最大并发连接数 TODO
MaxIdleConns int `yaml:"maxIdleConns" json:"maxIdleConns"` // 最大空闲连接数 TODO
StripPrefix string `yaml:"stripPrefix" json:"stripPrefix"` // 去除URL前缀
RequestHostType RequestHostType `yaml:"requestHostType" json:"requestHostType"` // 请求Host类型
RequestHost string `yaml:"requestHost" json:"requestHost"` // 请求Host支持变量
RequestURI string `yaml:"requestURI" json:"requestURI"` // 请求URI支持变量如果同时定义了StripPrefix则先执行StripPrefix
AddHeaders []string `yaml:"addHeaders" json:"addHeaders"` // 自动添加的Header
2020-09-27 18:41:21 +08:00
AutoFlush bool `yaml:"autoFlush" json:"autoFlush"` // 是否自动刷新缓冲区在比如SSEserver-sent events场景下很有用
requestHostHasVariables bool
requestURIHasVariables bool
2020-09-26 19:54:20 +08:00
2020-09-15 14:44:38 +08:00
hasPrimaryOrigins bool
hasBackupOrigins bool
2020-09-13 19:27:47 +08:00
schedulingIsBackup bool
2020-09-15 14:44:38 +08:00
schedulingObject schedulingconfigs.SchedulingInterface
2020-09-13 19:27:47 +08:00
schedulingLocker sync.Mutex
addXRealIPHeader bool
addXForwardedForHeader bool
addForwardedHeader bool
addXForwardedByHeader bool
addXForwardedHostHeader bool
addXForwardedProtoHeader bool
2020-09-13 19:27:47 +08:00
}
2021-08-01 21:56:15 +08:00
// Init 初始化
2020-09-13 19:27:47 +08:00
func (this *ReverseProxyConfig) Init() error {
this.requestHostHasVariables = configutils.HasVariables(this.RequestHost)
this.requestURIHasVariables = configutils.HasVariables(this.RequestURI)
2020-09-15 14:44:38 +08:00
this.hasPrimaryOrigins = len(this.PrimaryOrigins) > 0
this.hasBackupOrigins = len(this.BackupOrigins) > 0
2020-09-13 19:27:47 +08:00
for _, origins := range [][]*OriginConfig{this.PrimaryOrigins, this.BackupOrigins} {
for _, origin := range origins {
// 覆盖参数设置
if origin.MaxFails <= 0 && this.MaxFails > 0 {
origin.MaxFails = this.MaxFails
}
if origin.MaxConns <= 0 && this.MaxConns > 0 {
origin.MaxConns = this.MaxConns
}
if origin.MaxIdleConns <= 0 && this.MaxIdleConns > 0 {
origin.MaxIdleConns = this.MaxIdleConns
}
if (origin.ConnTimeout == nil || origin.ConnTimeout.Count <= 0) && this.ConnTimeout != nil && this.ConnTimeout.Count > 0 {
origin.ConnTimeout = this.ConnTimeout
}
if (origin.ReadTimeout == nil || origin.ReadTimeout.Count <= 0) && this.ReadTimeout != nil && this.ReadTimeout.Count > 0 {
origin.ReadTimeout = this.ReadTimeout
}
if (origin.IdleTimeout == nil || origin.IdleTimeout.Count <= 0) && this.IdleTimeout != nil && this.IdleTimeout.Count > 0 {
origin.IdleTimeout = this.IdleTimeout
}
// 初始化
err := origin.Init()
if err != nil {
return err
}
2020-09-13 19:27:47 +08:00
}
}
// scheduling
2021-08-01 21:56:15 +08:00
this.SetupScheduling(false, false, true)
2020-09-13 19:27:47 +08:00
// Header
if len(this.AddHeaders) == 0 {
// 默认加入两项
this.addXRealIPHeader = true
this.addXForwardedForHeader = true
this.addXForwardedByHeader = true
this.addXForwardedHostHeader = true
this.addXForwardedProtoHeader = true
} else {
this.addXRealIPHeader = lists.ContainsString(this.AddHeaders, "X-Real-IP")
this.addXForwardedForHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-For")
this.addXForwardedByHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-By")
this.addXForwardedHostHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-Host")
this.addXForwardedProtoHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-Proto")
}
2020-09-13 19:27:47 +08:00
return nil
}
2021-08-01 21:56:15 +08:00
// AddPrimaryOrigin 添加主源站配置
2020-09-21 20:21:20 +08:00
func (this *ReverseProxyConfig) AddPrimaryOrigin(origin *OriginConfig) {
2020-09-15 14:44:38 +08:00
this.PrimaryOrigins = append(this.PrimaryOrigins, origin)
}
2021-08-01 21:56:15 +08:00
// AddBackupOrigin 添加备用源站配置
2020-09-21 20:21:20 +08:00
func (this *ReverseProxyConfig) AddBackupOrigin(origin *OriginConfig) {
2020-09-15 14:44:38 +08:00
this.BackupOrigins = append(this.BackupOrigins, origin)
}
2021-08-01 21:56:15 +08:00
// NextOrigin 取得下一个可用的后端服务
2020-09-21 20:21:20 +08:00
func (this *ReverseProxyConfig) NextOrigin(call *shared.RequestCall) *OriginConfig {
2020-09-13 19:27:47 +08:00
this.schedulingLocker.Lock()
defer this.schedulingLocker.Unlock()
if this.schedulingObject == nil {
return nil
}
if this.Scheduling != nil && call != nil && call.Options != nil {
for k, v := range this.Scheduling.Options {
call.Options[k] = v
}
}
candidate := this.schedulingObject.Next(call)
2021-08-01 21:56:15 +08:00
// 末了重置状态
defer func() {
if candidate == nil {
this.schedulingIsBackup = false
}
}()
2020-09-13 19:27:47 +08:00
if candidate == nil {
// 启用备用服务器
if !this.schedulingIsBackup {
2021-08-01 21:56:15 +08:00
this.SetupScheduling(true, true, false)
2020-09-13 19:27:47 +08:00
candidate = this.schedulingObject.Next(call)
if candidate == nil {
2021-08-01 21:56:15 +08:00
// 不检查主要源站
this.SetupScheduling(false, false, false)
candidate = this.schedulingObject.Next(call)
if candidate == nil {
// 不检查备用源站
this.SetupScheduling(true, false, false)
candidate = this.schedulingObject.Next(call)
if candidate == nil {
return nil
}
}
2020-09-13 19:27:47 +08:00
}
}
if candidate == nil {
return nil
}
}
2020-09-21 20:21:20 +08:00
return candidate.(*OriginConfig)
2020-09-13 19:27:47 +08:00
}
2021-08-01 21:56:15 +08:00
// SetupScheduling 设置调度算法
func (this *ReverseProxyConfig) SetupScheduling(isBackup bool, checkOk bool, lock bool) {
if lock {
2020-09-13 19:27:47 +08:00
this.schedulingLocker.Lock()
defer this.schedulingLocker.Unlock()
}
2021-08-01 21:56:15 +08:00
2020-09-13 19:27:47 +08:00
this.schedulingIsBackup = isBackup
if this.Scheduling == nil {
2020-09-15 14:44:38 +08:00
this.schedulingObject = &schedulingconfigs.RandomScheduling{}
2020-09-13 19:27:47 +08:00
} else {
typeCode := this.Scheduling.Code
2020-09-15 14:44:38 +08:00
s := schedulingconfigs.FindSchedulingType(typeCode)
2020-09-13 19:27:47 +08:00
if s == nil {
this.Scheduling = nil
2020-09-15 14:44:38 +08:00
this.schedulingObject = &schedulingconfigs.RandomScheduling{}
2020-09-13 19:27:47 +08:00
} else {
2020-09-15 14:44:38 +08:00
this.schedulingObject = s["instance"].(schedulingconfigs.SchedulingInterface)
2020-09-13 19:27:47 +08:00
}
}
2020-09-15 14:44:38 +08:00
if !isBackup {
for _, origin := range this.PrimaryOrigins {
2021-08-01 21:56:15 +08:00
if origin.IsOn && (origin.IsOk || !checkOk) {
2020-09-13 19:27:47 +08:00
this.schedulingObject.Add(origin)
2020-09-15 14:44:38 +08:00
}
}
} else {
for _, origin := range this.BackupOrigins {
2021-08-01 21:56:15 +08:00
if origin.IsOn && (origin.IsOk || !checkOk) {
2020-09-13 19:27:47 +08:00
this.schedulingObject.Add(origin)
}
}
}
2021-08-01 21:56:15 +08:00
if !this.schedulingObject.HasCandidates() {
return
}
2020-09-13 19:27:47 +08:00
this.schedulingObject.Start()
}
2020-09-15 14:44:38 +08:00
2021-08-01 21:56:15 +08:00
// FindSchedulingConfig 获取调度配置对象
2020-09-15 14:44:38 +08:00
func (this *ReverseProxyConfig) FindSchedulingConfig() *SchedulingConfig {
if this.Scheduling == nil {
this.Scheduling = &SchedulingConfig{Code: "random"}
}
return this.Scheduling
}
2021-08-01 21:56:15 +08:00
// RequestHostHasVariables 判断RequestHost是否有变量
func (this *ReverseProxyConfig) RequestHostHasVariables() bool {
return this.requestHostHasVariables
}
2021-08-01 21:56:15 +08:00
// RequestURIHasVariables 判断RequestURI是否有变量
func (this *ReverseProxyConfig) RequestURIHasVariables() bool {
return this.requestURIHasVariables
}
2021-08-01 21:56:15 +08:00
// ShouldAddXRealIPHeader 是否添加X-Real-IP
func (this *ReverseProxyConfig) ShouldAddXRealIPHeader() bool {
return this.addXRealIPHeader
}
2021-08-01 21:56:15 +08:00
// ShouldAddXForwardedForHeader 是否添加X-Forwarded-For
func (this *ReverseProxyConfig) ShouldAddXForwardedForHeader() bool {
return this.addXForwardedForHeader
}
2021-08-01 21:56:15 +08:00
// ShouldAddXForwardedByHeader 是否添加X-Forwarded-By
func (this *ReverseProxyConfig) ShouldAddXForwardedByHeader() bool {
return this.addXForwardedByHeader
}
2021-08-01 21:56:15 +08:00
// ShouldAddXForwardedHostHeader 是否添加X-Forwarded-Host
func (this *ReverseProxyConfig) ShouldAddXForwardedHostHeader() bool {
return this.addXForwardedHostHeader
}
2021-08-01 21:56:15 +08:00
// ShouldAddXForwardedProtoHeader 是否添加X-Forwarded-Proto
func (this *ReverseProxyConfig) ShouldAddXForwardedProtoHeader() bool {
return this.addXForwardedProtoHeader
}
2021-08-01 21:56:15 +08:00
// ResetScheduling 重置调度算法
func (this *ReverseProxyConfig) ResetScheduling() {
this.SetupScheduling(false, true, true)
}